From 73d951c6732b0d82d5c286eb9d0bdca0306632d4 Mon Sep 17 00:00:00 2001 From: Francois Mauger Date: Mon, 3 May 2021 09:19:17 +0200 Subject: [PATCH 1/7] Fix interface for model classes --- source/bxgeomtools/include/geomtools/box.h | 106 +++-- .../bxgeomtools/include/geomtools/cylinder.h | 23 +- .../cylindric_extrusion_boxed_model.h | 5 +- .../include/geomtools/detail/model_tools.h | 24 +- .../include/geomtools/extruded_box.h | 13 +- .../include/geomtools/extruded_box_model.h | 22 +- .../geomtools/foot_point_on_quadric_finder.h | 6 +- .../include/geomtools/grid_model.h | 9 +- .../include/geomtools/hexagon_box.h | 23 +- .../bxgeomtools/include/geomtools/i_model.h | 41 +- .../include/geomtools/i_shape_3d.h | 37 +- .../include/geomtools/i_wires_3d_rendering.h | 14 +- .../include/geomtools/model_factory.h | 33 +- .../include/geomtools/multiple_items_model.h | 5 +- .../include/geomtools/plain_model.h | 12 +- .../include/geomtools/plate_with_hole_model.h | 5 +- .../bxgeomtools/include/geomtools/polycone.h | 26 +- .../bxgeomtools/include/geomtools/polyhedra.h | 99 +++-- .../include/geomtools/regular_polygon.h | 6 +- .../geomtools/replicated_boxed_model.h | 15 +- .../geomtools/replicated_circular_model.h | 9 +- .../include/geomtools/replicated_model.h | 5 +- .../right_circular_conical_frustrum.h | 18 + .../include/geomtools/rotated_boxed_model.h | 21 +- .../include/geomtools/simple_boxed_model.h | 11 +- .../include/geomtools/simple_shaped_model.h | 89 ++-- .../include/geomtools/simple_world_model.h | 7 +- .../geomtools/spherical_extrusion_box_model.h | 5 +- .../spherical_extrusion_cylinder_model.h | 5 +- .../include/geomtools/stacked_model.h | 23 +- .../geomtools/surrounded_boxed_model.h | 17 +- source/bxgeomtools/include/geomtools/tube.h | 112 +++-- source/bxgeomtools/src/box.cc | 56 +++ source/bxgeomtools/src/cylinder.cc | 44 ++ .../src/cylindric_extrusion_boxed_model.cc | 29 +- source/bxgeomtools/src/extruded_box.cc | 23 + source/bxgeomtools/src/extruded_box_model.cc | 19 +- source/bxgeomtools/src/grid_model.cc | 66 ++- source/bxgeomtools/src/hexagon_box.cc | 38 ++ source/bxgeomtools/src/i_model.cc | 59 ++- source/bxgeomtools/src/i_shape_3d.cc | 5 +- source/bxgeomtools/src/model_factory.cc | 142 +++++-- .../bxgeomtools/src/multiple_items_model.cc | 16 +- source/bxgeomtools/src/plain_model.cc | 10 +- .../bxgeomtools/src/plate_with_hole_model.cc | 25 +- source/bxgeomtools/src/polycone.cc | 229 +++++++++- source/bxgeomtools/src/polyhedra.cc | 207 +++++++++ source/bxgeomtools/src/rectangle.cc | 10 + .../bxgeomtools/src/replicated_boxed_model.cc | 24 +- .../src/replicated_circular_model.cc | 35 +- source/bxgeomtools/src/replicated_model.cc | 26 +- .../src/right_circular_conical_frustrum.cc | 152 +++++++ .../src/right_circular_conical_nappe.cc | 8 + source/bxgeomtools/src/rotated_boxed_model.cc | 37 +- source/bxgeomtools/src/simple_boxed_model.cc | 17 +- source/bxgeomtools/src/simple_shaped_model.cc | 396 +++++++++++------- source/bxgeomtools/src/simple_world_model.cc | 16 +- .../src/spherical_extrusion_box_model.cc | 25 +- .../src/spherical_extrusion_cylinder_model.cc | 25 +- source/bxgeomtools/src/stacked_model.cc | 46 +- .../bxgeomtools/src/surrounded_boxed_model.cc | 30 +- source/bxgeomtools/src/tube.cc | 124 +++++- .../testing/config/test_geometry_models.conf | 18 +- .../testing/geomtools_test_model_1.cc | 6 +- .../testing/geomtools_test_model_1.h | 3 +- .../testing/geomtools_test_model_2.cc | 6 +- .../testing/geomtools_test_model_2.h | 5 +- .../testing/geomtools_test_world_model.cc | 6 +- .../testing/geomtools_test_world_model.h | 3 +- source/bxgeomtools/testing/test_polycone.cxx | 114 ++++- source/bxgeomtools/testing/test_tube.cxx | 41 +- 71 files changed, 2158 insertions(+), 829 deletions(-) diff --git a/source/bxgeomtools/include/geomtools/box.h b/source/bxgeomtools/include/geomtools/box.h index 8527d70d3..14fb97ba1 100644 --- a/source/bxgeomtools/include/geomtools/box.h +++ b/source/bxgeomtools/include/geomtools/box.h @@ -1,15 +1,11 @@ /// \file geomtools/box.h /* Author(s): Francois Mauger * Creation date: 2008-05-23 - * Last modified: 2015-02-15 - * - * License: + * Last modified: 2021-04-24 * * Description: * - * Box solid shape - * - * History: + * Box 3D solid shape * */ @@ -52,21 +48,21 @@ namespace geomtools { /// \brief Masks used for the 6 faces of the box enum faces_mask_type { - FACE_NONE = face_identifier::FACE_BITS_NONE, - _FACE_BEGIN = 0x1, - FACE_BACK = 0x1, - FACE_FRONT = 0x2, - FACE_LEFT = 0x4, - FACE_RIGHT = 0x8, - FACE_BOTTOM = 0x10, - FACE_TOP = 0x20, - _FACE_END = 0x40, - FACE_ALL = (FACE_BACK - | FACE_FRONT - | FACE_LEFT - | FACE_RIGHT - | FACE_BOTTOM - | FACE_TOP) + FACE_NONE = face_identifier::FACE_BITS_NONE, + _FACE_BEGIN = 0x1, + FACE_BACK = 0x1, + FACE_FRONT = 0x2, + FACE_LEFT = 0x4, + FACE_RIGHT = 0x8, + FACE_BOTTOM = 0x10, + FACE_TOP = 0x20, + _FACE_END = 0x40, + FACE_ALL = (FACE_BACK + | FACE_FRONT + | FACE_LEFT + | FACE_RIGHT + | FACE_BOTTOM + | FACE_TOP) }; /// Return the min X coordinates (bounding box) @@ -162,22 +158,40 @@ namespace geomtools { /// Return a collection of face info objects unsigned int compute_faces(face_info_collection_type & faces_) const override; + /// Compute a deflated version of the box + void compute_deflated(box & deflated_, + double by_x_, + double by_y_, + double by_z_); + + /// Compute an inflated version of the box + void compute_inflated(box & deflated_, + double by_x_, + double by_y_, + double by_z_); + + /// Compute an envelope box at user tolerance + void compute_envelope(box & envelope_, + double tolerance_x_, + double tolerance_y_, + double tolerance_z_); + /// Check if a point is inside the box bool is_inside(const vector_3d &, - double a_skin = GEOMTOOLS_PROPER_TOLERANCE) const override; + double a_skin = GEOMTOOLS_PROPER_TOLERANCE) const override; /// Check if a point is inside the box bool is_outside(const vector_3d &, - double a_skin = GEOMTOOLS_PROPER_TOLERANCE) const override; + double a_skin = GEOMTOOLS_PROPER_TOLERANCE) const override; /// Return the surface bit a point belongs to face_identifier on_surface(const vector_3d &, - const face_identifier & a_surface_mask = face_identifier::face_bits_any(), - double a_skin = GEOMTOOLS_PROPER_TOLERANCE) const override; + const face_identifier & a_surface_mask = face_identifier::face_bits_any(), + double a_skin = GEOMTOOLS_PROPER_TOLERANCE) const override; /// Return the vector normal to the surface at some position vector_3d get_normal_on_surface(const vector_3d & a_position, - const face_identifier & a_surface_bit) const override; + const face_identifier & a_surface_bit) const override; /// Print operator friend std::ostream & operator<<( std::ostream & , const box & ); @@ -187,36 +201,36 @@ namespace geomtools { /// Find the intercept point of a segment with the box bool find_intercept(const vector_3d & a_from, - const vector_3d & a_direction, - face_intercept_info & a_intercept, - double a_skin = GEOMTOOLS_PROPER_TOLERANCE) const override; + const vector_3d & a_direction, + face_intercept_info & a_intercept, + double a_skin = GEOMTOOLS_PROPER_TOLERANCE) const override; /// Smart print void tree_dump(std::ostream & a_out = std::clog, - const std::string & a_title = "", - const std::string & a_indent = "", - bool a_inherit = false) const override; + const std::string & a_title = "", + const std::string & a_indent = "", + bool a_inherit = false) const override; /// \brief 3D rendering options enum box_wires_rendering_option_type { - WR_BOX_NO_BACK_FACE = (WR_BASE_LAST << 1), //!< Do not render the X- (back) face - WR_BOX_NO_FRONT_FACE = (WR_BASE_LAST << 2), //!< Do not render the X+ (front) face - WR_BOX_NO_LEFT_FACE = (WR_BASE_LAST << 3), //!< Do not render the Y- (left) face - WR_BOX_NO_RIGHT_FACE = (WR_BASE_LAST << 4), //!< Do not render the Y+ (right) face - WR_BOX_NO_BOTTOM_FACE = (WR_BASE_LAST << 5), //!< Do not render the Z- (bottom) face - WR_BOX_NO_TOP_FACE = (WR_BASE_LAST << 6), //!< Do not render the Z+ (top) face - WR_BOX_LAST = (WR_BOX_NO_TOP_FACE), //!< Last defined bit - WR_BOX_MASK = (WR_BOX_NO_BACK_FACE - | WR_BOX_NO_FRONT_FACE - | WR_BOX_NO_LEFT_FACE - | WR_BOX_NO_RIGHT_FACE - | WR_BOX_NO_BOTTOM_FACE - | WR_BOX_NO_TOP_FACE) //!< Rendering options bit mask + WR_BOX_NO_BACK_FACE = (WR_BASE_LAST << 1), //!< Do not render the X- (back) face + WR_BOX_NO_FRONT_FACE = (WR_BASE_LAST << 2), //!< Do not render the X+ (front) face + WR_BOX_NO_LEFT_FACE = (WR_BASE_LAST << 3), //!< Do not render the Y- (left) face + WR_BOX_NO_RIGHT_FACE = (WR_BASE_LAST << 4), //!< Do not render the Y+ (right) face + WR_BOX_NO_BOTTOM_FACE = (WR_BASE_LAST << 5), //!< Do not render the Z- (bottom) face + WR_BOX_NO_TOP_FACE = (WR_BASE_LAST << 6), //!< Do not render the Z+ (top) face + WR_BOX_LAST = (WR_BOX_NO_TOP_FACE), //!< Last defined bit + WR_BOX_MASK = (WR_BOX_NO_BACK_FACE + | WR_BOX_NO_FRONT_FACE + | WR_BOX_NO_LEFT_FACE + | WR_BOX_NO_RIGHT_FACE + | WR_BOX_NO_BOTTOM_FACE + | WR_BOX_NO_TOP_FACE) //!< Rendering options bit mask }; /// Generate a list of polylines representing the contour of the shape (for display clients) void generate_wires_self(wires_type & wires_, - uint32_t options_ = 0) const override; + uint32_t options_ = 0) const override; /// Compute the positions of the 8 vertexes of the box void compute_vertexes(std::vector & vv_) const; diff --git a/source/bxgeomtools/include/geomtools/cylinder.h b/source/bxgeomtools/include/geomtools/cylinder.h index 4d39b6051..d658bbfba 100644 --- a/source/bxgeomtools/include/geomtools/cylinder.h +++ b/source/bxgeomtools/include/geomtools/cylinder.h @@ -1,13 +1,11 @@ /// \file geomtools/cylinder.h /* Author(s): Francois Mauger * Creation date: 2008-05-24 - * Last modified: 2015-02-15 - * - * License: + * Last modified: 2021-04-24 * * Description: * - * A cylinder on z-axis + * A cylinder 3D solid shape on z-axis * */ @@ -70,6 +68,21 @@ namespace geomtools { /// Return a collection of face info objects unsigned int compute_faces(face_info_collection_type & faces_) const override; + /// Compute a deflated version of the cylinder + void compute_deflated(cylinder & deflated_, + double by_r_, + double by_z_); + + /// Compute an inflated version of the cylinder + void compute_inflated(cylinder & deflated_, + double by_r_, + double by_z_); + + /// Compute an envelope cylinder at user tolerance + void compute_envelope(cylinder & envelope_, + double tolerance_r_, + double tolerance_z_); + /// Return the min X coordinates (bounding box) double get_xmin () const override; @@ -199,7 +212,7 @@ namespace geomtools { /// Generate a list of polylines representing the contour of the shape (for display clients) void generate_wires_self(wires_type & wires_, - uint32_t options_ = 0) const override; + uint32_t options_ = 0) const override; /// OCD support static void init_ocd(datatools::object_configuration_description &); diff --git a/source/bxgeomtools/include/geomtools/cylindric_extrusion_boxed_model.h b/source/bxgeomtools/include/geomtools/cylindric_extrusion_boxed_model.h index 7304250d1..f37deb7ec 100644 --- a/source/bxgeomtools/include/geomtools/cylindric_extrusion_boxed_model.h +++ b/source/bxgeomtools/include/geomtools/cylindric_extrusion_boxed_model.h @@ -132,9 +132,8 @@ namespace geomtools { protected: /// Executed at construct - void _at_construct (const std::string & name_, - const datatools::properties & config_, - models_col_type * models_ = 0) override; + void _at_construct (const datatools::properties & config_, + models_col_type * models_ = nullptr) override; private: diff --git a/source/bxgeomtools/include/geomtools/detail/model_tools.h b/source/bxgeomtools/include/geomtools/detail/model_tools.h index 72ea1388e..d853d618d 100644 --- a/source/bxgeomtools/include/geomtools/detail/model_tools.h +++ b/source/bxgeomtools/include/geomtools/detail/model_tools.h @@ -2,14 +2,9 @@ /* model_tools.h * Author (s) : Francois Mauger * Creation date: 2010-02-12 - * Last modified: 2010-02-12 - * - * License: - * - * Description: - * - * History: + * Last modified: 2021-04-23 * + * Description: utilities and typedefs for geometry model management */ #ifndef GEOMTOOLS_DETAIL_MODEL_TOOLS_H @@ -29,8 +24,21 @@ namespace geomtools { class i_model; /// Type alias for dictionary of geometry model plain handles - typedef std::map models_col_type; + typedef std::map models_ptr_dict_type; + // typedef std::map models_col_type; + // Forward declaration: + class model_factory; + struct model_bus_type : public models_ptr_dict_type + { + model_bus_type(model_factory & factory_) : _factory_(factory_) {} + const model_factory & get_factory() const { return _factory_; } + model_factory & grab_factory() const { return _factory_; } + private: + model_factory & _factory_; + }; + typedef model_bus_type models_col_type; + typedef i_model * (*model_creator_type) (const std::string & name_, const datatools::properties & configuration_, models_col_type * models_); diff --git a/source/bxgeomtools/include/geomtools/extruded_box.h b/source/bxgeomtools/include/geomtools/extruded_box.h index 2b338242d..937847ade 100644 --- a/source/bxgeomtools/include/geomtools/extruded_box.h +++ b/source/bxgeomtools/include/geomtools/extruded_box.h @@ -2,14 +2,11 @@ /* Author(s): Arnaud Chapon * François Mauger * Creation date: 2014-10-27 - * Last modified: 2015-03-23 - * - * License: + * Last modified: 2021-04-24 * * Description: - * Interface: * - * History: + * Extruded box 3D solid shape with box extrusion * */ @@ -262,6 +259,12 @@ namespace geomtools { void generate_wires_self(wires_type & wires_, uint32_t options_ = 0) const override; + /// Compute the outer box envelope with user tolerance + void compute_envelope(box & envelope_, + double x_tolerance_, + double y_tolerance_, + double z_tolerance_); + /// OCD support static void init_ocd(datatools::object_configuration_description &); diff --git a/source/bxgeomtools/include/geomtools/extruded_box_model.h b/source/bxgeomtools/include/geomtools/extruded_box_model.h index 49a2212c6..1b2760555 100644 --- a/source/bxgeomtools/include/geomtools/extruded_box_model.h +++ b/source/bxgeomtools/include/geomtools/extruded_box_model.h @@ -1,16 +1,11 @@ /// \file geomtools/extruded_box_model.h /* Author(s) : Arnaud Chapon * Creation date: 2015-10-27 - * Last modified: 2015-10-27 - * - * License: - * + * Last modified: 2021-04-23 * Description: * * Geometry model for an extruded box * - * History: - * */ #ifndef GEOMTOOLS_EXTRUDED_BOX_MODEL_H @@ -60,9 +55,9 @@ namespace geomtools { /// Smart print void tree_dump(std::ostream & out_ = std::clog, - const std::string & title_ = "", - const std::string & indent_ = "", - bool inherit_ = false) const override; + const std::string & title_ = "", + const std::string & indent_ = "", + bool inherit_ = false) const override; /// Return the embedded extruded box const geomtools::extruded_box & get_extruded_box() const; @@ -79,15 +74,14 @@ namespace geomtools { //! Generate a list of polylines representing the contour of the shape (for display clients) void generate_wires_self(wires_type & wires_, - uint32_t options_ = 0) const override; + uint32_t options_ = 0) const override; }; - protected: + protected: /// Executed at construct - void _at_construct(const std::string & name_, - const datatools::properties & config_, - models_col_type * models_ = 0) override; + void _at_construct(const datatools::properties & config_, + models_col_type * models_ = nullptr) override; private: diff --git a/source/bxgeomtools/include/geomtools/foot_point_on_quadric_finder.h b/source/bxgeomtools/include/geomtools/foot_point_on_quadric_finder.h index 301e9a90f..246ab3120 100644 --- a/source/bxgeomtools/include/geomtools/foot_point_on_quadric_finder.h +++ b/source/bxgeomtools/include/geomtools/foot_point_on_quadric_finder.h @@ -60,11 +60,11 @@ namespace geomtools { private: - const quadric * _quadric_; //!< Referenced quadric - double _epsilon_; //!< Tolerance (dimension of a length) + const quadric * _quadric_ = nullptr; //!< Referenced quadric + double _epsilon_; //!< Tolerance (expected dimension of a length or the dimension of the traversed space) double _alpha_max_; //!< Maximum (dimensionless) unsigned int _max_iter_; //!< Maximum number of iterations - bool _debug_; //!< Debug flag + bool _debug_ = false; //!< Debug flag std::string _debug_filename_; //!< Debug filename }; diff --git a/source/bxgeomtools/include/geomtools/grid_model.h b/source/bxgeomtools/include/geomtools/grid_model.h index 370dd153b..a8fbc07ff 100644 --- a/source/bxgeomtools/include/geomtools/grid_model.h +++ b/source/bxgeomtools/include/geomtools/grid_model.h @@ -90,15 +90,14 @@ namespace geomtools { /// Post construction void _post_construct (datatools::properties & setup_, - models_col_type * models_) override; + models_col_type * models_) override; /// Construction - void _at_construct (const std::string & name_, - const datatools::properties & config_, - models_col_type * models_ = 0) override; + void _at_construct (const datatools::properties & config_, + models_col_type * models_) override; private: - const i_model * _model_; /// Replicated model + const i_model * _model_ = nullptr; /// Replicated model regular_grid_placement _grid_placement_; /// Replication placement on the grid physical_volume _phys_; /// Physical volume std::string _grid_daughter_label_; /// Labels for daughter volumes diff --git a/source/bxgeomtools/include/geomtools/hexagon_box.h b/source/bxgeomtools/include/geomtools/hexagon_box.h index 43508eb90..db2494460 100644 --- a/source/bxgeomtools/include/geomtools/hexagon_box.h +++ b/source/bxgeomtools/include/geomtools/hexagon_box.h @@ -1,14 +1,9 @@ /// \file geomtools/hexagon_box.h /* Author (s): Francois Mauger * Creation date: 2008-05-23 - * Last modified: 2008-05-23 + * Last modified: 2021-04-24 * - * License: - * - * Description: - * Interface: - * - * History: + * Description: hexagon box 3D solid shape * */ @@ -142,10 +137,20 @@ namespace geomtools { static bool xy_is_on_hexagon (double r_, double x_, double y_, double skin_); + /// Compute a deflated version of the hexagon box + void compute_deflated(hexagon_box & deflated_, + double by_r_, + double by_z_); + + /// Compute an inflated version of the hexagon box + void compute_inflated(hexagon_box & deflated_, + double by_r_, + double by_z_); + private: - double _radius_; /// Radius of the hexagonal box - double _z_; /// Height of the hexagonal box + double _radius_; ///< Radius of the hexagonal box + double _z_; ///< Height of the hexagonal box }; diff --git a/source/bxgeomtools/include/geomtools/i_model.h b/source/bxgeomtools/include/geomtools/i_model.h index c8dd4f5c3..61f9c4815 100644 --- a/source/bxgeomtools/include/geomtools/i_model.h +++ b/source/bxgeomtools/include/geomtools/i_model.h @@ -56,8 +56,8 @@ namespace geomtools { static const std::string & exported_properties_prefixes_key(); /// \brief The collection of geometry models: - typedef geomtools::models_col_type models_col_type; - + typedef geomtools::model_bus_type models_col_type; + model_with_internal_mesh_data & grab_meshes(); const model_with_internal_mesh_data & get_meshes() const; @@ -68,7 +68,7 @@ namespace geomtools { /// Check if the geometry model is "phantom" bool is_phantom_solid() const; - /// Check if the name of the geometry model exists + /// Check if the name of the geometry model exists (it should after construction) bool has_name() const; /// Set the name of the geometry model @@ -102,19 +102,25 @@ namespace geomtools { geomtools::logical_volume & grab_logical(); /// Method that constructs the geometry model - virtual void construct(const std::string & name_, - const datatools::properties & setup_, - models_col_type * models_ = nullptr); + void construct(models_col_type * models_ = nullptr); + + /// Method that constructs the geometry model + void construct(const std::string & name_, + models_col_type * models_ = nullptr); + + /// Method that constructs the geometry model + void construct(const std::string & name_, + const datatools::properties & setup_, + models_col_type * models_ = nullptr); /// Main method that constructs the geometry model - virtual void construct(const std::string & name_, - const datatools::properties & setup_, - const std::vector & properties_prefixes_, - models_col_type * models_); + void construct(const std::string & name_, + const datatools::properties & setup_, + const std::vector & properties_prefixes_, + models_col_type * models_); /// Method that destroys the geometry model - virtual void destroy(const std::string & name_, - models_col_type * models_ = nullptr); + void destroy(models_col_type * models_ = nullptr); /// Get the model ID virtual std::string get_model_id() const = 0; @@ -157,10 +163,14 @@ namespace geomtools { /// Pre-construction hook virtual void _pre_construct(datatools::properties & setup_, models_col_type * models_); - /// The main construction hook + /// The main construction hook (replace the former construction hook method) + virtual void _at_construct(const datatools::properties & setup_, + models_col_type * models_ = nullptr); + + /// @deprecated Old/broken construction hook interface (a legacy design error) virtual void _at_construct(const std::string & name_, const datatools::properties & setup_, - models_col_type * models_ = 0) = 0; + models_col_type * models_); /// Post-construction hook virtual void _post_construct(datatools::properties & setup_, models_col_type * models_); @@ -169,8 +179,7 @@ namespace geomtools { void _mandatory_post_construct(datatools::properties & setup_, models_col_type * models_); /// The main destruction hook - virtual void _at_destroy(const std::string & name_, - models_col_type * models_ = nullptr); + virtual void _at_destroy(models_col_type * models_ = nullptr); protected: diff --git a/source/bxgeomtools/include/geomtools/i_shape_3d.h b/source/bxgeomtools/include/geomtools/i_shape_3d.h index 1e0ec1369..68b51ee5b 100644 --- a/source/bxgeomtools/include/geomtools/i_shape_3d.h +++ b/source/bxgeomtools/include/geomtools/i_shape_3d.h @@ -253,13 +253,10 @@ namespace geomtools { void build_default_bounding_data(); /// Smart print - void tree_dump(std::ostream & a_out = std::clog, - const std::string & a_title = "", - const std::string & a_indent = "", - bool a_inherit = false) const override; - - /// OCD support - static void init_ocd(datatools::object_configuration_description &); + void tree_dump(std::ostream & a_out = std::clog, + const std::string & a_title = "", + const std::string & a_indent = "", + bool a_inherit = false) const override; /// Check the lock flag bool is_locked() const; @@ -270,6 +267,9 @@ namespace geomtools { /// Unlock the shape void unlock(); + /// OCD support + static void init_ocd(datatools::object_configuration_description &); + protected: /// Set default values for attributes @@ -282,7 +282,7 @@ namespace geomtools { virtual void _at_unlock(); /// Initialize from properties - void _initialize(const datatools::properties &, const handle_dict_type * = 0); + void _initialize(const datatools::properties &, const handle_dict_type * = nullptr); /// Reset void _reset(); @@ -341,9 +341,9 @@ namespace geomtools { private: // Work data: - bool _locked_; //!< Lock flag - bool _owns_stackable_data_; //!< Ownership flag for stackable data - const stackable_data * _stackable_data_; //!< Handle to stackable data + bool _locked_ = false; //!< Lock flag + bool _owns_stackable_data_ = false; //!< Ownership flag for stackable data + const stackable_data * _stackable_data_ = nullptr; //!< Handle to stackable data bounding_data _bounding_data_; //!< Bounding data boost::optional _forced_volume_; //!< Forced volume datatools::handle _computed_faces_; //!< Computed faces @@ -353,6 +353,21 @@ namespace geomtools { }; + // class wrapper_shaped_3d : public i_shape_3d + // { + // public: + + // wrapper_shaped_3d(i_shape_3d & shape_) + // : _shape_ref_(shape_) {} + + // operator i_shape_3d() const { return _shape_ref_; } + + // private: + + // i_shape_3d & _shaped_ref_; + + // }; + } // end of namespace geomtools /* diff --git a/source/bxgeomtools/include/geomtools/i_wires_3d_rendering.h b/source/bxgeomtools/include/geomtools/i_wires_3d_rendering.h index 08db2c9c2..e1ec84df8 100644 --- a/source/bxgeomtools/include/geomtools/i_wires_3d_rendering.h +++ b/source/bxgeomtools/include/geomtools/i_wires_3d_rendering.h @@ -52,8 +52,8 @@ namespace geomtools { WR_BASE_HIGH_ANGLE_SAMPLING = (WR_BASE_GRID << 6), //!< Use high sampling for angles WR_BASE_VERY_HIGH_ANGLE_SAMPLING = (WR_BASE_GRID << 7), //!< Use very high sampling for angles WR_BASE_HUGE_ANGLE_SAMPLING = (WR_BASE_GRID << 8), //!< Use huge sampling for angles - WR_BASE_UNUSED_09 = (WR_BASE_GRID << 9), //!< Reserved for future usage - WR_BASE_UNUSED_10 = (WR_BASE_GRID << 10), //!< Reserved for future usage + WR_BASE_BEST_GRID_SAMPLING = (WR_BASE_GRID << 9), //!< Activate grid with guessed best density + WR_BASE_BEST_ANGLE_SAMPLING = (WR_BASE_GRID << 10), //!< Use guessed best sampling for angles WR_BASE_UNUSED_11 = (WR_BASE_GRID << 11), //!< Reserved for future usage WR_BASE_UNUSED_12 = (WR_BASE_GRID << 12), //!< Reserved for future usage WR_BASE_UNUSED_13 = (WR_BASE_GRID << 13), //!< Reserved for future usage @@ -248,12 +248,4 @@ namespace geomtools { } // end of namespace geomtools -#endif -/* -** Local Variables: -- -** mode: c++ -- -** c-file-style: "gnu" -- -** tab-width: 2 -- -** End: -- -*/ - // GEOMTOOLS_I_WIRES_3D_RENDERING_H +#endif // GEOMTOOLS_I_WIRES_3D_RENDERING_H diff --git a/source/bxgeomtools/include/geomtools/model_factory.h b/source/bxgeomtools/include/geomtools/model_factory.h index c22ae11ec..1d9a27126 100644 --- a/source/bxgeomtools/include/geomtools/model_factory.h +++ b/source/bxgeomtools/include/geomtools/model_factory.h @@ -1,15 +1,11 @@ /// \file geomtools/model_factory.h /* Author(s) : Francois Mauger * Creation date: 2010-02-24 - * Last modified: 2010-02-24 - * - * License: + * Last modified: 2021-04-23 * * Description: * Factory for geometry models * - * History: - * */ #ifndef GEOMTOOLS_MODEL_FACTORY_H @@ -72,7 +68,7 @@ namespace geomtools { datatools::multi_properties & grab_mp(); /// Get a non-mutable collection of geometry models - const models_col_type & get_models() const; + const model_bus_type & get_models() const; /// Get a non-mutable collection of geometry logicals associated to models const logical_volume::dict_type & get_logicals() const; @@ -139,8 +135,17 @@ namespace geomtools { const std::string & argv_ = "", std::ostream & out_ = std::clog); + void external_model_instance_registration(i_model & model_); + + void external_model_instance_unregistration(i_model & model_); + private: + /// Register a model instance + void _model_instance_registration_(i_model * model_); + + void _model_instance_unregistration_(i_model * model_); + /// Basic construction of the model factory void _basic_construct_(); @@ -153,16 +158,22 @@ namespace geomtools { /// Construct the virtual geometry hierarchy void _construct_(); + /// Get a mutable collection of geometry models + model_bus_type & _grab_models_(); + + /// Get a non-mutable collection of geometry models + const model_bus_type & _get_models_() const; + private: - shape_factory * _shape_factory_ = nullptr; //!< Handle to an external shape factory - i_model::factory_register_type _factory_register_; //!< Register of model factories + shape_factory * _shape_factory_ = nullptr; //!< Handle to an external shape factory + i_model::factory_register_type _factory_register_; //!< Register of model factories where geometry model classes are self registrated bool _locked_; //!< Lock flag datatools::logger::priority _logging_priority_; //!< Logging priority threshold datatools::multi_properties _mp_; //!< Multi-container of parameters - models_col_type _models_; //!< Dictionary of geometry models - std::set _owned_models_; //!< Registry of owned models - logical_volume::dict_type _logicals_; //!< Dictionary of geometry logical volumes + std::set _owned_models_; //!< List of owned model instances ny name + std::unique_ptr _models_; //!< Dictionary of geometry model instances + logical_volume::dict_type _logicals_; //!< Dictionary of geometry logical volume instances std::vector _property_prefixes_; //!< List of proprety prefixes to be preserved in logical volumes }; diff --git a/source/bxgeomtools/include/geomtools/multiple_items_model.h b/source/bxgeomtools/include/geomtools/multiple_items_model.h index 29faf9231..5f602b76b 100644 --- a/source/bxgeomtools/include/geomtools/multiple_items_model.h +++ b/source/bxgeomtools/include/geomtools/multiple_items_model.h @@ -64,9 +64,8 @@ namespace geomtools { protected: /// Construction - void _at_construct (const std::string & label_, - const datatools::properties & config_, - models_col_type * models_ = 0) override; + void _at_construct (const datatools::properties & config_, + models_col_type * models_ = nullptr) override; private: diff --git a/source/bxgeomtools/include/geomtools/plain_model.h b/source/bxgeomtools/include/geomtools/plain_model.h index 402f1d5cf..483e427c0 100644 --- a/source/bxgeomtools/include/geomtools/plain_model.h +++ b/source/bxgeomtools/include/geomtools/plain_model.h @@ -44,20 +44,20 @@ namespace geomtools { const std::string & get_material_name() const; - void tree_dump(std::ostream & out_ = std::clog, + void tree_dump(std::ostream & out_ = std::clog, const std::string & title_ = "", const std::string & indent_ = "", - bool inherit_ = false) const override; - + bool inherit_ = false) const override; protected: void _pre_construct (datatools::properties & setup_, models_col_type * models_) override; - void _at_construct (const std::string & name_, - const datatools::properties & config_, - models_col_type * models_ = 0) override; + void _at_construct (const datatools::properties & config_, + models_col_type * models_ = nullptr) override; + + // void _at_destroy(models_col_type * models_ = nullptr) override; private: diff --git a/source/bxgeomtools/include/geomtools/plate_with_hole_model.h b/source/bxgeomtools/include/geomtools/plate_with_hole_model.h index 82ba84029..426ce29a7 100644 --- a/source/bxgeomtools/include/geomtools/plate_with_hole_model.h +++ b/source/bxgeomtools/include/geomtools/plate_with_hole_model.h @@ -96,9 +96,8 @@ namespace geomtools { protected: /// Construction - void _at_construct(const std::string & name_, - const datatools::properties & setup_, - geomtools::models_col_type * models_ = 0) override; + void _at_construct(const datatools::properties & setup_, + geomtools::models_col_type * models_ = nullptr) override; private: diff --git a/source/bxgeomtools/include/geomtools/polycone.h b/source/bxgeomtools/include/geomtools/polycone.h index 0d4d7d3ad..670214793 100644 --- a/source/bxgeomtools/include/geomtools/polycone.h +++ b/source/bxgeomtools/include/geomtools/polycone.h @@ -1,16 +1,12 @@ /// \file geomtools/polycone.h /* Author(s) : Francois Mauger * Creation date: 2010-03-14 - * Last modified: 2015-03-12 - * - * License: + * Last modified: 2021-04-23 * * Description: * * Polycone 3D solid shape * - * History: - * */ #ifndef GEOMTOOLS_POLYCONE_H @@ -110,7 +106,7 @@ namespace geomtools { /// Return the Z dimension double get_z () const; - /// Check if the nappe has partial phi angle + /// Check if the polycone has partial phi angle bool has_partial_angle() const; /// Check the start phi angle @@ -268,6 +264,24 @@ namespace geomtools { /// Compute the outer polycone void compute_outer_polycone (polycone & op_); + /// Compute a deflated polycone + void compute_deflated(polycone & deflated_, + double by_r_, + double by_z_, + double by_angle_ = -1.0); + + /// Compute an inflated polycone + void compute_inflated(polycone & inflated_, + double by_r_, + double by_z_, + double by_angle_ = -1.0); + + /// Compute the polycone envelope + void compute_envelope(polycone & envelope_, + double r_tolerance_, + double z_tolerance_, + double angle_tolerance_ = -1.0); + /// Compute the volume double get_volume (uint32_t flags_ = 0) const override; diff --git a/source/bxgeomtools/include/geomtools/polyhedra.h b/source/bxgeomtools/include/geomtools/polyhedra.h index 781764beb..ee5d5dfff 100644 --- a/source/bxgeomtools/include/geomtools/polyhedra.h +++ b/source/bxgeomtools/include/geomtools/polyhedra.h @@ -1,16 +1,12 @@ /// \file geomtools/polyhedra.h /* Author(s) : Francois Mauger * Creation date: 2010-10-08 - * Last modified: 2015-03-19 - * - * License: + * Last modified: 2021-04-23 * * Description: * Polyhedra 3D shape with regular polygon sections * See also: http://en.wikipedia.org/wiki/Frustum * - * History: - * */ #ifndef GEOMTOOLS_POLYHEDRA_H @@ -45,22 +41,22 @@ namespace geomtools { /// \brief Face flags enum faces_mask_type { - FACE_NONE = face_identifier::FACE_BITS_NONE, - FACE_INNER_SIDE = datatools::bit_mask::bit00, - FACE_OUTER_SIDE = datatools::bit_mask::bit01, - FACE_BOTTOM = datatools::bit_mask::bit02, - FACE_TOP = datatools::bit_mask::bit03, - FACE_ALL = (FACE_INNER_SIDE - | FACE_OUTER_SIDE - | FACE_BOTTOM - | FACE_TOP) + FACE_NONE = face_identifier::FACE_BITS_NONE, + FACE_INNER_SIDE = datatools::bit_mask::bit00, + FACE_OUTER_SIDE = datatools::bit_mask::bit01, + FACE_BOTTOM = datatools::bit_mask::bit02, + FACE_TOP = datatools::bit_mask::bit03, + FACE_ALL = (FACE_INNER_SIDE + | FACE_OUTER_SIDE + | FACE_BOTTOM + | FACE_TOP) }; /// \brief Format of the datafile for reading Z/Rmin/Rmax data enum datafile_column_mode { - RMIN_RMAX = 0, //!< Use one first column for Rmin and second one for Rmax - IGNORE_RMIN = 1, //!< Ignore first column as Rmin and use only second one for Rmax - RMIN_AS_RMAX = 2 //!< Use one first column as Rmax + RMIN_RMAX = 0, //!< Use one first column for Rmin and second one for Rmax + IGNORE_RMIN = 1, //!< Ignore first column as Rmin and use only second one for Rmax + RMIN_AS_RMAX = 2 //!< Use one first column as Rmax }; /* @@ -165,7 +161,7 @@ namespace geomtools { /// Main initialization method from a container of configuration parameters void initialize (const datatools::properties & setup_, const handle_dict_type * = 0) override; - /// Reset/invalidate the solid + /// Reset/invalidate the solid void reset () override; /// Initialize from a file @@ -213,6 +209,21 @@ namespace geomtools { /// Compute the outer polyhedra void compute_outer_polyhedra (polyhedra & op_); + /// Compute a deflated polyhedra + void compute_deflated(polyhedra & deflated_, + double by_r_, + double by_z_); + + /// Compute an inflated polyhedra + void compute_inflated(polyhedra & inflated_, + double by_r_, + double by_z_); + + /// Compute the polyhedra envelope + void compute_envelope(polyhedra & envelope_, + double r_tolerance_, + double z_tolerance_); + /// Compute the volume double get_volume (uint32_t flags_ = 0) const override; @@ -233,54 +244,54 @@ namespace geomtools { /// Check if a point is inside the frustrum bool is_inside (const vector_3d &, - double skin_ = GEOMTOOLS_PROPER_TOLERANCE) const override; + double skin_ = GEOMTOOLS_PROPER_TOLERANCE) const override; /// Check if a point is outside the frustrum bool is_outside (const vector_3d &, - double skin_ = GEOMTOOLS_PROPER_TOLERANCE) const override; + double skin_ = GEOMTOOLS_PROPER_TOLERANCE) const override; /// Return the surface bit a point belongs to face_identifier on_surface(const vector_3d &, - const face_identifier & a_surface_mask = face_identifier::face_bits_any(), - double a_skin = GEOMTOOLS_PROPER_TOLERANCE) const override; + const face_identifier & a_surface_mask = face_identifier::face_bits_any(), + double a_skin = GEOMTOOLS_PROPER_TOLERANCE) const override; /// Compute the normal to the surface of the furstrum vector_3d get_normal_on_surface (const vector_3d & position_, - const face_identifier & ) const override; + const face_identifier & ) const override; /// Find the intercept point with a face of the frustrum bool find_intercept(const vector_3d & from_, - const vector_3d & direction_, - face_intercept_info & intercept_, - double skin_ = GEOMTOOLS_PROPER_TOLERANCE) const override; + const vector_3d & direction_, + face_intercept_info & intercept_, + double skin_ = GEOMTOOLS_PROPER_TOLERANCE) const override; /// Smart print void tree_dump(std::ostream & out_ = std::clog, - const std::string & title_ = "", - const std::string & indent_ = "", - bool inherit_ = false) const override; + const std::string & title_ = "", + const std::string & indent_ = "", + bool inherit_ = false) const override; /// \brief 3D rendering options enum polyhedra_wires_rendering_option_type { - WR_POLYHEDRA_NO_BOTTOM_FACE = (WR_BASE_LAST << 1), //!< Do not render the bottom face - WR_POLYHEDRA_NO_TOP_FACE = (WR_BASE_LAST << 2), //!< Do not render the top face - WR_POLYHEDRA_NO_INNER_FACE = (WR_BASE_LAST << 3), //!< Do not render the inner face - WR_POLYHEDRA_NO_OUTER_FACE = (WR_BASE_LAST << 4), //!< Do not render the outer face - // WR_POLYHEDRA_NO_START_ANGLE_FACE = (WR_BASE_LAST << 5), //!< Do not render the start angle face - // WR_POLYHEDRA_NO_STOP_ANGLE_FACE = (WR_BASE_LAST << 6), //!< Do not render the stop angle face - WR_POLYHEDRA_LAST = (WR_POLYHEDRA_NO_OUTER_FACE), //!< Last defined bit - WR_POLYHEDRA_MASK = (WR_POLYHEDRA_NO_BOTTOM_FACE - | WR_POLYHEDRA_NO_TOP_FACE - | WR_POLYHEDRA_NO_INNER_FACE - | WR_POLYHEDRA_NO_OUTER_FACE - // | WR_POLYHEDRA_NO_START_ANGLE_FACE - // | WR_POLYHEDRA_NO_STOP_ANGLE_FACE - ) //!< Rendering options bit mask + WR_POLYHEDRA_NO_BOTTOM_FACE = (WR_BASE_LAST << 1), //!< Do not render the bottom face + WR_POLYHEDRA_NO_TOP_FACE = (WR_BASE_LAST << 2), //!< Do not render the top face + WR_POLYHEDRA_NO_INNER_FACE = (WR_BASE_LAST << 3), //!< Do not render the inner face + WR_POLYHEDRA_NO_OUTER_FACE = (WR_BASE_LAST << 4), //!< Do not render the outer face + // WR_POLYHEDRA_NO_START_ANGLE_FACE = (WR_BASE_LAST << 5), //!< Do not render the start angle face + // WR_POLYHEDRA_NO_STOP_ANGLE_FACE = (WR_BASE_LAST << 6), //!< Do not render the stop angle face + WR_POLYHEDRA_LAST = (WR_POLYHEDRA_NO_OUTER_FACE), //!< Last defined bit + WR_POLYHEDRA_MASK = (WR_POLYHEDRA_NO_BOTTOM_FACE + | WR_POLYHEDRA_NO_TOP_FACE + | WR_POLYHEDRA_NO_INNER_FACE + | WR_POLYHEDRA_NO_OUTER_FACE + // | WR_POLYHEDRA_NO_START_ANGLE_FACE + // | WR_POLYHEDRA_NO_STOP_ANGLE_FACE + ) //!< Rendering options bit mask }; /// Generate a list of polylines representing the contour of the shape (for display clients) void generate_wires_self(wires_type & wires_, - uint32_t options_ = 0) const override; + uint32_t options_ = 0) const override; friend std::ostream & operator<< (std::ostream &, const polyhedra &); diff --git a/source/bxgeomtools/include/geomtools/regular_polygon.h b/source/bxgeomtools/include/geomtools/regular_polygon.h index d833bab1c..0fa8d259b 100644 --- a/source/bxgeomtools/include/geomtools/regular_polygon.h +++ b/source/bxgeomtools/include/geomtools/regular_polygon.h @@ -3,13 +3,9 @@ * Creation date: 2010-02-14 * Last modified: 2015-02-16 * - * License: - * * Description: * - * A regular_polygon in x-y plane - * - * History: + * A regular polygon in x-y plane 2D shape * */ diff --git a/source/bxgeomtools/include/geomtools/replicated_boxed_model.h b/source/bxgeomtools/include/geomtools/replicated_boxed_model.h index b11d1a1e5..3ce1190cf 100644 --- a/source/bxgeomtools/include/geomtools/replicated_boxed_model.h +++ b/source/bxgeomtools/include/geomtools/replicated_boxed_model.h @@ -59,18 +59,17 @@ namespace geomtools { protected: - void _at_construct (const std::string & name_, - const datatools::properties & config_, - models_col_type * models_ = 0) override; + void _at_construct (const datatools::properties & config_, + models_col_type * models_ = nullptr) override; private: - const i_model * _boxed_model_; + const i_model * _boxed_model_ = nullptr; regular_linear_placement _boxed_replica_placement_; physical_volume _boxed_phys_; - size_t _number_of_items_; - double _x_; - double _y_; - double _z_; + size_t _number_of_items_ = 0; + double _x_ = datatools::invalid_real(); + double _y_ = datatools::invalid_real(); + double _z_ = datatools::invalid_real(); geomtools::box _solid_; // registration interface : diff --git a/source/bxgeomtools/include/geomtools/replicated_circular_model.h b/source/bxgeomtools/include/geomtools/replicated_circular_model.h index 50d9da392..1759396e2 100644 --- a/source/bxgeomtools/include/geomtools/replicated_circular_model.h +++ b/source/bxgeomtools/include/geomtools/replicated_circular_model.h @@ -70,16 +70,15 @@ namespace geomtools { /// Pre-construction void _pre_construct(datatools::properties & setup_, - models_col_type * models_ = 0) override; + models_col_type * models_) override; /// Construction - void _at_construct(const std::string & name_, - const datatools::properties & config_, - models_col_type * models_ = 0) override; + void _at_construct(const datatools::properties & config_, + models_col_type * models_) override; /// Post-construction void _post_construct (datatools::properties & setup_, - models_col_type * models_ = 0) override; + models_col_type * models_) override; private: diff --git a/source/bxgeomtools/include/geomtools/replicated_model.h b/source/bxgeomtools/include/geomtools/replicated_model.h index 74e8b0165..cb3073920 100644 --- a/source/bxgeomtools/include/geomtools/replicated_model.h +++ b/source/bxgeomtools/include/geomtools/replicated_model.h @@ -93,9 +93,8 @@ namespace geomtools { models_col_type * models_) override; /// Construction - void _at_construct (const std::string & name_, - const datatools::properties & config_, - models_col_type * models_ = 0) override; + void _at_construct (const datatools::properties & config_, + models_col_type * models_) override; private: const i_model * _model_; /// Replicated model diff --git a/source/bxgeomtools/include/geomtools/right_circular_conical_frustrum.h b/source/bxgeomtools/include/geomtools/right_circular_conical_frustrum.h index 443d41002..521705c48 100644 --- a/source/bxgeomtools/include/geomtools/right_circular_conical_frustrum.h +++ b/source/bxgeomtools/include/geomtools/right_circular_conical_frustrum.h @@ -194,6 +194,24 @@ namespace geomtools { /// Compute the bottom face void compute_bottom_face(disk & bottom_disk_, placement &) const; + /// Compute a deflated version of the frustrum + void compute_deflated(right_circular_conical_frustrum & deflated_, + double by_r_, + double by_z_, + double by_angle_ = -1.0); + + /// Compute an inflated version of the frustrum + void compute_inflated(right_circular_conical_frustrum & deflated_, + double by_r_, + double by_z_, + double by_angle_ = -1.0); + + /// Compute an envelope of the frustrum + void compute_envelope(right_circular_conical_frustrum & envelope_, + double tolerance_r_, + double tolerance_z_, + double angle_tolerance_ = -1.0); + /// \brief Start/stop angle face type /// /// diff --git a/source/bxgeomtools/include/geomtools/rotated_boxed_model.h b/source/bxgeomtools/include/geomtools/rotated_boxed_model.h index 05162572a..08f36b6ad 100644 --- a/source/bxgeomtools/include/geomtools/rotated_boxed_model.h +++ b/source/bxgeomtools/include/geomtools/rotated_boxed_model.h @@ -1,15 +1,11 @@ /// \file geomtools/rotated_boxed_model.h /* Author(s) : Francois Mauger * Creation date: 2010-02-24 - * Last modified: 2013-06-27 - * - * License: + * Last modified: 2021-04-23 * * Description: * Factory for geometry models * - * History: - * */ #ifndef GEOMTOOLS_ROTATED_BOXED_MODEL_H @@ -48,19 +44,18 @@ namespace geomtools { std::string get_model_id () const override; - void tree_dump (std::ostream & out_ = std::clog, - const std::string & title_ = "", - const std::string & indent_ = "", - bool inherit_ = false) const override; + void tree_dump (std::ostream & out_ = std::clog, + const std::string & title_ = "", + const std::string & indent_ = "", + bool inherit_ = false) const override; protected: - void _at_construct (const std::string & name_, - const datatools::properties & config_, - models_col_type * models_ = 0) override; + void _at_construct (const datatools::properties & config_, + models_col_type * models_ = nullptr) override; private: - const i_model * _boxed_model_; + const i_model * _boxed_model_ = nullptr; placement _boxed_placement_; physical_volume _boxed_phys_; geomtools::box _solid_; diff --git a/source/bxgeomtools/include/geomtools/simple_boxed_model.h b/source/bxgeomtools/include/geomtools/simple_boxed_model.h index a81f726f5..956518729 100644 --- a/source/bxgeomtools/include/geomtools/simple_boxed_model.h +++ b/source/bxgeomtools/include/geomtools/simple_boxed_model.h @@ -63,15 +63,14 @@ namespace geomtools { protected: - void _at_construct (const std::string & name_, - const datatools::properties & config_, - models_col_type * models_ = 0) override; + void _at_construct (const datatools::properties & config_, + models_col_type * models_ = nullptr) override; private: std::string _material_name_; - double _x_; - double _y_; - double _z_; + double _x_ = datatools::invalid_real(); + double _y_ = datatools::invalid_real(); + double _z_ = datatools::invalid_real(); geomtools::box _solid_; // registration interface : diff --git a/source/bxgeomtools/include/geomtools/simple_shaped_model.h b/source/bxgeomtools/include/geomtools/simple_shaped_model.h index 6ac2b1532..aac4bce85 100644 --- a/source/bxgeomtools/include/geomtools/simple_shaped_model.h +++ b/source/bxgeomtools/include/geomtools/simple_shaped_model.h @@ -1,9 +1,7 @@ /// \file geomtools/simple_shaped_model.h /* Author(s) : Francois Mauger * Creation date: 2010-10-13 - * Last modified: 2014-05-19 - * - * License: + * Last modified: 2021-04-23 * * Description: * @@ -11,8 +9,6 @@ * box, cylinder, sphere, tube, polycone, polyhedra or whatever solid (3D-shape) * registerable in a shape factory. * - * History: - * */ #ifndef GEOMTOOLS_SIMPLE_SHAPED_MODEL_H @@ -20,6 +16,7 @@ // Standard library: #include +#include // This project: #include @@ -27,6 +24,7 @@ #include #include #include +#include namespace geomtools { @@ -91,6 +89,27 @@ namespace geomtools { std::string get_model_id () const override; + struct envelope_tolerance_type + { + bool deflated_shape = false; + double x_tolerance = datatools::invalid_real(); + double y_tolerance = datatools::invalid_real(); + double r_tolerance = datatools::invalid_real(); + double z_tolerance = datatools::invalid_real(); + double theta_tolerance = datatools::invalid_real(); + double phi_tolerance = datatools::invalid_real(); + bool has_x_tolerance() const { return datatools::is_valid(x_tolerance); } + bool has_y_tolerance() const { return datatools::is_valid(y_tolerance); } + bool has_z_tolerance() const { return datatools::is_valid(z_tolerance); } + bool has_r_tolerance() const { return datatools::is_valid(r_tolerance); } + bool has_theta_tolerance() const { return datatools::is_valid(theta_tolerance); } + bool has_phi_tolerance() const { return datatools::is_valid(phi_tolerance); } + }; + + const envelope_tolerance_type & get_envelope_tolerance() const; + + envelope_tolerance_type & grab_envelope_tolerance(); + void tree_dump (std::ostream & out_ = std::clog, const std::string & title_ = "", const std::string & indent_ = "", @@ -99,37 +118,30 @@ namespace geomtools { protected: void _pre_construct (datatools::properties & setup_, - models_col_type * models_) override; + models_col_type * models_) override; void _post_construct (datatools::properties & setup_, - models_col_type * models_) override; + models_col_type * models_) override; - void _at_construct (const std::string & name_, - const datatools::properties & config_, - models_col_type * models_ = 0) override; + void _at_construct (const datatools::properties & config_, + models_col_type * models_) override; - virtual void _construct_box (const std::string & name_, - const datatools::properties & config_, + virtual void _construct_box (const datatools::properties & config_, models_col_type * models_); - virtual void _construct_cylinder (const std::string & name_, - const datatools::properties & config_, + virtual void _construct_cylinder (const datatools::properties & config_, models_col_type * models_); - virtual void _construct_sphere (const std::string & name_, - const datatools::properties & config_, + virtual void _construct_sphere (const datatools::properties & config_, models_col_type * models_); - virtual void _construct_tube (const std::string & name_, - const datatools::properties & config_, + virtual void _construct_tube (const datatools::properties & config_, models_col_type * models_); - virtual void _construct_polycone (const std::string & name_, - const datatools::properties & config_, + virtual void _construct_polycone (const datatools::properties & config_, models_col_type * models_); - virtual void _construct_polyhedra (const std::string & name_, - const datatools::properties & config_, + virtual void _construct_polyhedra (const datatools::properties & config_, models_col_type * models_); private: @@ -137,29 +149,28 @@ namespace geomtools { shape_build_mode_type _sbm_; //!< The shape build mode std::string _shape_type_id_; //!< The type identifier of the shape std::string _material_name_; //!< The name of the material the shape is made of - filled_utils::filled_type _filled_mode_; //!< The filled mode for tube, polycone or polyhedra (legacy) - std::string _filled_material_name_; //!< The name of the material of the shape cavity for tube, polycone or polyhedra (legacy) + filled_utils::filled_type _filled_mode_; //!< The filled mode for closed tube, polycone or polyhedra (legacy) + std::string _filled_material_name_; //!< The name of the material of the shape cavity for closed tube, polycone or polyhedra (legacy) std::string _filled_label_; //!< The label of the shape in enveloppe filled mode (legacy) - - // Effective solids: - geomtools::box * _box_; - geomtools::cylinder * _cylinder_; - geomtools::tube * _tube_; - geomtools::sphere * _sphere_; - geomtools::polycone * _polycone_; - geomtools::polyhedra * _polyhedra_; - - geomtools::i_shape_3d * _solid_; //!< Solid handle - geomtools::i_shape_3d * _inner_shape_; //!< For filled tube or polycone or polyhedra - geomtools::i_shape_3d * _outer_shape_; //!< For mother polycone or polyhedra - + envelope_tolerance_type _envelope_tolerance_; //!< Envelope's tolerance data (if needed) + + std::shared_ptr _box_; + std::shared_ptr _cylinder_; + std::shared_ptr _tube_; + std::shared_ptr _sphere_; + std::shared_ptr _polycone_; + std::shared_ptr _polyhedra_; + std::shared_ptr _solid_; //!< Solid handle + std::shared_ptr _inner_shape_ = nullptr; //!< For filled tube or polycone or polyhedra + std::shared_ptr _outer_shape_ = nullptr; //!< For mother polycone or polyhedra + + plain_model _inner_model_; //!< Inner plain model placement _inner_placement_; //!< Inner daughter volume placement - logical_volume _inner_logical_; //!< Inner logical volume physical_volume _inner_phys_; //!< Inner physical volume //logical_volume * _daughter_owner_logical_; //!< The logical volume that is the top level mother of all daughter volumes implied by this model - MWIM _internals_; //!< Internal items within the shape + MWIM _internals_; //!< Internal items within the target shape MWIM _filled_internals_; //!< Internal items within the cavity (tube, polycone, polyhedra) // registration interface : diff --git a/source/bxgeomtools/include/geomtools/simple_world_model.h b/source/bxgeomtools/include/geomtools/simple_world_model.h index aaf41ebfd..59d65a6aa 100644 --- a/source/bxgeomtools/include/geomtools/simple_world_model.h +++ b/source/bxgeomtools/include/geomtools/simple_world_model.h @@ -51,13 +51,12 @@ namespace geomtools { protected: - void _at_construct (const std::string & name_, - const datatools::properties & setup_, - models_col_type * models_ = 0) override; + void _at_construct (const datatools::properties & setup_, + models_col_type * models_) override; private: - const i_model * _setup_model_; + const i_model * _setup_model_ = nullptr; geomtools::placement _setup_placement_; geomtools::physical_volume _setup_phys_; geomtools::box _solid_; diff --git a/source/bxgeomtools/include/geomtools/spherical_extrusion_box_model.h b/source/bxgeomtools/include/geomtools/spherical_extrusion_box_model.h index 233c7d6f3..b5f9b4179 100644 --- a/source/bxgeomtools/include/geomtools/spherical_extrusion_box_model.h +++ b/source/bxgeomtools/include/geomtools/spherical_extrusion_box_model.h @@ -88,9 +88,8 @@ namespace geomtools { protected: - void _at_construct(const std::string & name_, - const datatools::properties & setup_, - geomtools::models_col_type * models_ = 0) override; + void _at_construct(const datatools::properties & setup_, + geomtools::models_col_type * models_ = nullptr) override; private: std::string _material_; diff --git a/source/bxgeomtools/include/geomtools/spherical_extrusion_cylinder_model.h b/source/bxgeomtools/include/geomtools/spherical_extrusion_cylinder_model.h index 711be0fd5..7b79c1e59 100644 --- a/source/bxgeomtools/include/geomtools/spherical_extrusion_cylinder_model.h +++ b/source/bxgeomtools/include/geomtools/spherical_extrusion_cylinder_model.h @@ -90,9 +90,8 @@ namespace geomtools { protected: - void _at_construct(const std::string & name_, - const datatools::properties & setup_, - geomtools::models_col_type * models_ = 0) override; + void _at_construct(const datatools::properties & setup_, + geomtools::models_col_type * models_ = nullptr) override; private: std::string _material_; //!< Material name diff --git a/source/bxgeomtools/include/geomtools/stacked_model.h b/source/bxgeomtools/include/geomtools/stacked_model.h index 3995f1491..7cbeaa659 100644 --- a/source/bxgeomtools/include/geomtools/stacked_model.h +++ b/source/bxgeomtools/include/geomtools/stacked_model.h @@ -1,9 +1,7 @@ /// \file geomtools/stacked_model.h /* Author(s) : Francois Mauger * Creation date: 2010-04-02 - * Last modified: 2017-02-23 - * - * License: + * Last modified: 2021-04-23 * * Description: * @@ -42,10 +40,10 @@ namespace geomtools { static const double DEFAULT_NUMERICS_PLAY; enum stacking_axis_t { - STACKING_ALONG_INVALID = -1, - STACKING_ALONG_X = AXIS_X, - STACKING_ALONG_Y = AXIS_Y, - STACKING_ALONG_Z = AXIS_Z + STACKING_ALONG_INVALID = -1, + STACKING_ALONG_X = AXIS_X, + STACKING_ALONG_Y = AXIS_Y, + STACKING_ALONG_Z = AXIS_Z }; struct stacked_item @@ -140,16 +138,15 @@ namespace geomtools { /// Smart print void tree_dump (std::ostream & out_ = std::clog, - const std::string & title_ = "", - const std::string & indent_ = "", - bool inherit_ = false) const override; + const std::string & title_ = "", + const std::string & indent_ = "", + bool inherit_ = false) const override; protected: /// Construction - void _at_construct (const std::string & name_, - const datatools::properties & config_, - models_col_type * models_ = 0) override; + void _at_construct (const datatools::properties & config_, + models_col_type * models_) override; private: diff --git a/source/bxgeomtools/include/geomtools/surrounded_boxed_model.h b/source/bxgeomtools/include/geomtools/surrounded_boxed_model.h index f6629adeb..483c39cbc 100644 --- a/source/bxgeomtools/include/geomtools/surrounded_boxed_model.h +++ b/source/bxgeomtools/include/geomtools/surrounded_boxed_model.h @@ -1,16 +1,12 @@ /// \file geomtools/surrounded_boxed_model.h /* Author(s) : Francois Mauger * Creation date: 2010-04-02 - * Last modified: 2010-04-02 - * - * License: + * Last modified: 2021-04-23 * * Description: * * Geometry model with multiple surrounded boxes. * - * History: - * */ #ifndef GEOMTOOLS_SURROUNDED_BOXED_MODEL_H @@ -116,16 +112,15 @@ namespace geomtools { /// Smart print void tree_dump (std::ostream & out_ = std::clog, - const std::string & title_ = "", - const std::string & indent_ = "", - bool inherit_ = false) const override; + const std::string & title_ = "", + const std::string & indent_ = "", + bool inherit_ = false) const override; protected: /// Construction - void _at_construct (const std::string & name_, - const datatools::properties & config_, - models_col_type * models_ = 0) override; + void _at_construct (const datatools::properties & config_, + models_col_type * models_) override; private: diff --git a/source/bxgeomtools/include/geomtools/tube.h b/source/bxgeomtools/include/geomtools/tube.h index 8af36cff0..7612859ef 100644 --- a/source/bxgeomtools/include/geomtools/tube.h +++ b/source/bxgeomtools/include/geomtools/tube.h @@ -1,14 +1,11 @@ /// \file geomtools/tube.h /* Author(s): F.Mauger * Creation date: 2006-11-28 - * Last modified: 2015-02-22 - * - * License: + * Last modified: 2021-04-24 * * Description: - * 3D tube description * - * History: + * Tube 3D solid shape * */ @@ -49,26 +46,26 @@ namespace geomtools { /// \brief Face flags enum faces_mask_type { - FACE_NONE = face_identifier::FACE_BITS_NONE, - FACE_OUTER_SIDE = datatools::bit_mask::bit00, - FACE_BOTTOM = datatools::bit_mask::bit01, - FACE_TOP = datatools::bit_mask::bit02, - FACE_INNER_SIDE = datatools::bit_mask::bit03, - FACE_START_ANGLE = datatools::bit_mask::bit04, - FACE_STOP_ANGLE = datatools::bit_mask::bit05, - FACE_ALL = (FACE_OUTER_SIDE - | FACE_BOTTOM - | FACE_TOP - | FACE_INNER_SIDE - | FACE_START_ANGLE - | FACE_STOP_ANGLE) + FACE_NONE = face_identifier::FACE_BITS_NONE, + FACE_OUTER_SIDE = datatools::bit_mask::bit00, + FACE_BOTTOM = datatools::bit_mask::bit01, + FACE_TOP = datatools::bit_mask::bit02, + FACE_INNER_SIDE = datatools::bit_mask::bit03, + FACE_START_ANGLE = datatools::bit_mask::bit04, + FACE_STOP_ANGLE = datatools::bit_mask::bit05, + FACE_ALL = (FACE_OUTER_SIDE + | FACE_BOTTOM + | FACE_TOP + | FACE_INNER_SIDE + | FACE_START_ANGLE + | FACE_STOP_ANGLE) }; /// \brief Volume flags enum volumes_mask_type { - VOLUME_NONE = 0, - VOLUME_BULK = datatools::bit_mask::bit00, - VOLUME_CAVITY = datatools::bit_mask::bit01 + VOLUME_NONE = 0, + VOLUME_BULK = datatools::bit_mask::bit00, + VOLUME_CAVITY = datatools::bit_mask::bit01 }; /// Return the identifier label for the class @@ -187,6 +184,29 @@ namespace geomtools { /// Compute the outer nappe void compute_outer_cylinder(cylinder & oc_); + /// Compute a deflated version of the tube + void compute_deflated(tube & deflated_, + double by_r_, + double by_z_, + double by_angle_ = -1.0); + + /// Compute an inflated version of the tube + void compute_inflated(tube & deflated_, + double by_r_, + double by_z_, + double by_angle_ = -1.0); + + /// Compute the outer envelope with user tolerance + void compute_envelope(tube & oc_, + double r_tolerance_, + double z_tolerance_, + double angle_tolerance_ = -1.0); + + /// Compute the outer cylindric envelope with user tolerance + void compute_envelope(cylinder & oc_, + double r_tolerance_, + double z_tolerance_); + /// Default constructor tube(); @@ -228,26 +248,26 @@ namespace geomtools { /// Check if a point is inside the tube bool is_inside(const vector_3d &, - double skin_ = GEOMTOOLS_PROPER_TOLERANCE) const override; + double skin_ = GEOMTOOLS_PROPER_TOLERANCE) const override; /// Check if a point is outside the tube bool is_outside(const vector_3d &, - double skin_ = GEOMTOOLS_PROPER_TOLERANCE) const override; + double skin_ = GEOMTOOLS_PROPER_TOLERANCE) const override; /// Return the surface bit a point belongs to face_identifier on_surface(const vector_3d &, - const face_identifier & a_surface_mask = face_identifier::face_bits_any(), - double a_skin = GEOMTOOLS_PROPER_TOLERANCE) const override; + const face_identifier & a_surface_mask = face_identifier::face_bits_any(), + double a_skin = GEOMTOOLS_PROPER_TOLERANCE) const override; /// Return the vector normal to the surface at some position vector_3d get_normal_on_surface(const vector_3d & a_position, - const face_identifier & a_surface_bit) const override; + const face_identifier & a_surface_bit) const override; /// Find the intercept point with a face of the tube bool find_intercept(const vector_3d & from_, - const vector_3d & direction_, - face_intercept_info & intercept_, - double skin_ = GEOMTOOLS_PROPER_TOLERANCE) const override; + const vector_3d & direction_, + face_intercept_info & intercept_, + double skin_ = GEOMTOOLS_PROPER_TOLERANCE) const override; /// Output operator friend std::ostream & @@ -259,30 +279,30 @@ namespace geomtools { /// Smart print void tree_dump(std::ostream & out_ = std::clog, - const std::string & title_ = "", - const std::string & indent_ = "", - bool inherit_ = false) const override; + const std::string & title_ = "", + const std::string & indent_ = "", + bool inherit_ = false) const override; /// \brief 3D rendering options enum tube_wires_rendering_option_type { - WR_TUBE_NO_BOTTOM_FACE = (WR_BASE_LAST << 1), //!< Do not render the bottom face - WR_TUBE_NO_TOP_FACE = (WR_BASE_LAST << 2), //!< Do not render the top face - WR_TUBE_NO_INNER_FACE = (WR_BASE_LAST << 3), //!< Do not render the inner face - WR_TUBE_NO_OUTER_FACE = (WR_BASE_LAST << 4), //!< Do not render the outer face - WR_TUBE_NO_START_ANGLE_FACE = (WR_BASE_LAST << 5), //!< Do not render the start angle face - WR_TUBE_NO_STOP_ANGLE_FACE = (WR_BASE_LAST << 6), //!< Do not render the stop angle face - WR_TUBE_LAST = (WR_TUBE_NO_STOP_ANGLE_FACE), //!< Last defined bit - WR_TUBE_MASK = (WR_TUBE_NO_BOTTOM_FACE - | WR_TUBE_NO_TOP_FACE - | WR_TUBE_NO_INNER_FACE - | WR_TUBE_NO_OUTER_FACE - | WR_TUBE_NO_START_ANGLE_FACE - | WR_TUBE_NO_STOP_ANGLE_FACE) //!< Rendering options bit mask + WR_TUBE_NO_BOTTOM_FACE = (WR_BASE_LAST << 1), //!< Do not render the bottom face + WR_TUBE_NO_TOP_FACE = (WR_BASE_LAST << 2), //!< Do not render the top face + WR_TUBE_NO_INNER_FACE = (WR_BASE_LAST << 3), //!< Do not render the inner face + WR_TUBE_NO_OUTER_FACE = (WR_BASE_LAST << 4), //!< Do not render the outer face + WR_TUBE_NO_START_ANGLE_FACE = (WR_BASE_LAST << 5), //!< Do not render the start angle face + WR_TUBE_NO_STOP_ANGLE_FACE = (WR_BASE_LAST << 6), //!< Do not render the stop angle face + WR_TUBE_LAST = (WR_TUBE_NO_STOP_ANGLE_FACE), //!< Last defined bit + WR_TUBE_MASK = (WR_TUBE_NO_BOTTOM_FACE + | WR_TUBE_NO_TOP_FACE + | WR_TUBE_NO_INNER_FACE + | WR_TUBE_NO_OUTER_FACE + | WR_TUBE_NO_START_ANGLE_FACE + | WR_TUBE_NO_STOP_ANGLE_FACE) //!< Rendering options bit mask }; /// Generate a sequence of polylines for wires 3D rendering void generate_wires_self(wires_type & wires_, - uint32_t options_ = 0) const override; + uint32_t options_ = 0) const override; /// OCD support static void init_ocd(datatools::object_configuration_description &); diff --git a/source/bxgeomtools/src/box.cc b/source/bxgeomtools/src/box.cc index d729ed1a9..a266d79fa 100644 --- a/source/bxgeomtools/src/box.cc +++ b/source/bxgeomtools/src/box.cc @@ -408,6 +408,62 @@ namespace geomtools { return; } + void box::compute_deflated(box & deflated_, + double by_x_, + double by_y_, + double by_z_) + { + DT_THROW_IF(! is_valid(), std::logic_error, "Invalid box!"); + deflated_.reset(); + double x_eps = 0.0; + double y_eps = 0.0; + double z_eps = 0.0; + if (datatools::is_valid(by_x_) and by_x_ > 0.0) x_eps = by_x_; + if (datatools::is_valid(by_y_) and by_y_ > 0.0) y_eps = by_y_; + if (datatools::is_valid(by_z_) and by_z_ > 0.0) z_eps = by_z_; + double x = get_x(); + double y = get_y(); + double z = get_z(); + x -= (2 * x_eps); + y -= (2 * y_eps); + z -= (2 * z_eps); + deflated_.set(x, y, z); + deflated_.lock(); + return; + } + + void box::compute_inflated(box & inflated_, + double by_x_, + double by_y_, + double by_z_) + { + DT_THROW_IF(! is_valid(), std::logic_error, "Invalid box!"); + double x_eps = 0.0; + double y_eps = 0.0; + double z_eps = 0.0; + if (datatools::is_valid(by_x_) and by_x_ > 0.0) x_eps = by_x_; + if (datatools::is_valid(by_y_) and by_y_ > 0.0) y_eps = by_y_; + if (datatools::is_valid(by_z_) and by_z_ > 0.0) z_eps = by_z_; + double x = get_x(); + double y = get_y(); + double z = get_z(); + x += (2 * x_eps); + y += (2 * y_eps); + z += (2 * z_eps); + inflated_.reset(); + inflated_.set(x, y, z); + inflated_.lock(); + return; + } + + void box::compute_envelope(box & envelope_, + double tolerance_x_, + double tolerance_y_, + double tolerance_z_) + { + compute_inflated(envelope_, tolerance_x_, tolerance_y_, tolerance_z_); + } + bool box::is_outside(const vector_3d & a_position, double a_skin) const { diff --git a/source/bxgeomtools/src/cylinder.cc b/source/bxgeomtools/src/cylinder.cc index 819a13e68..768813da2 100644 --- a/source/bxgeomtools/src/cylinder.cc +++ b/source/bxgeomtools/src/cylinder.cc @@ -581,7 +581,51 @@ namespace geomtools { return nfaces; } + void cylinder::compute_deflated(cylinder & deflated_, + double by_r_, + double by_z_) + { + DT_THROW_IF(! is_valid(), std::logic_error, "Invalid cylinder!"); + double r_eps = 0.0; + double z_eps = 0.0; + if (datatools::is_valid(by_r_) and by_r_ > 0.0) r_eps = by_r_; + if (datatools::is_valid(by_z_) and by_z_ > 0.0) z_eps = by_z_; + double r = get_r(); + double z = get_z(); + r -= r_eps; + z -= (2 * z_eps); + deflated_.reset(); + deflated_.set(r, z); + deflated_.lock(); + return; + } + void cylinder::compute_inflated(cylinder & inflated_, + double by_r_, + double by_z_) + { + DT_THROW_IF(! is_valid(), std::logic_error, "Invalid cylinder!"); + double r_eps = 0.0; + double z_eps = 0.0; + if (datatools::is_valid(by_r_) and by_r_ > 0.0) r_eps = by_r_; + if (datatools::is_valid(by_z_) and by_z_ > 0.0) z_eps = by_z_; + double r = get_r(); + double z = get_z(); + r += r_eps; + z += (2 * z_eps); + inflated_.reset(); + inflated_.set(r, z); + inflated_.lock(); + return; + } + + void cylinder::compute_envelope(cylinder & envelope_, + double tolerance_r_, + double tolerance_z_) + { + compute_inflated(envelope_, tolerance_r_, tolerance_z_); + } + void cylinder::generate_wires_self(wires_type & wires_, uint32_t options_) const { diff --git a/source/bxgeomtools/src/cylindric_extrusion_boxed_model.cc b/source/bxgeomtools/src/cylindric_extrusion_boxed_model.cc index d180cb1a2..9241ba6ad 100644 --- a/source/bxgeomtools/src/cylindric_extrusion_boxed_model.cc +++ b/source/bxgeomtools/src/cylindric_extrusion_boxed_model.cc @@ -140,8 +140,7 @@ namespace geomtools { return; } - void cylindric_extrusion_boxed_model::_at_construct (const std::string & name_, - const datatools::properties & config_, + void cylindric_extrusion_boxed_model::_at_construct (const datatools::properties & config_, models_col_type * /*models_*/) { DT_LOG_TRACE (get_logging_priority (), "Entering..."); @@ -153,22 +152,22 @@ namespace geomtools { } DT_THROW_IF (! config_.has_key ("x"), std::logic_error, - "Missing 'x' property in cylindric extrusion boxed model '" << name_ << "' !"); + "Missing 'x' property in cylindric extrusion boxed model '" << get_name() << "' !"); double mother_x = config_.fetch_real ("x"); if (! config_.has_explicit_unit ("x")) mother_x *= lunit; DT_THROW_IF (! config_.has_key ("y"), std::logic_error, - "Missing 'y' property in cylindric extrusion boxed model '" << name_ << "' !"); + "Missing 'y' property in cylindric extrusion boxed model '" << get_name() << "' !"); double mother_y = config_.fetch_real ("y"); if (! config_.has_explicit_unit ("y")) mother_y *= lunit; DT_THROW_IF (! config_.has_key ("z"), std::logic_error, - "Missing 'z' property in cylindric extrusion boxed model '" << name_ << "' !"); + "Missing 'z' property in cylindric extrusion boxed model '" << get_name() << "' !"); double mother_z = config_.fetch_real ("z"); if (! config_.has_explicit_unit ("z")) mother_z *= lunit; DT_THROW_IF (! config_.has_key ("extrusion_radius"), std::logic_error, - "Missing 'extrusion_radius' property in cylindric extrusion boxed model '" << name_ << "' !"); + "Missing 'extrusion_radius' property in cylindric extrusion boxed model '" << get_name() << "' !"); double extrusion_radius = config_.fetch_real ("extrusion_radius"); if (! config_.has_explicit_unit ("extrusion_radius")) extrusion_radius *= lunit; @@ -185,34 +184,34 @@ namespace geomtools { } DT_THROW_IF (! config_.has_key ("material.ref"), std::logic_error, - "Missing 'material.ref' property in cylindric extrusion boxed model '" << name_ << "' !"); + "Missing 'material.ref' property in cylindric extrusion boxed model '" << get_name() << "' !"); const std::string material_name = config_.fetch_string ("material.ref"); // TODO: better check : for now we do not take into account extrusion_x and extrusion_y shifts !!! DT_THROW_IF (extrusion_radius >= 0.5 * mother_x, std::logic_error, "Extrusion radius (" << extrusion_radius / CLHEP::mm << " mm) is too large (X-axis) in cylindric extrusion boxed model '" - << name_ << "' !"); + << get_name() << "' !"); DT_THROW_IF (extrusion_radius >= 0.5 * mother_y, std::logic_error, "Extrusion radius (" << extrusion_radius / CLHEP::mm << " mm) is too large (Y-axis) in cylindric extrusion boxed model '" - << name_ << "' !"); + << get_name() << "' !"); DT_THROW_IF(extrusion_x + extrusion_radius >= +0.5 * mother_x, std::logic_error, "Extrusion radius (" << extrusion_radius / CLHEP::mm << " mm) is too large (X-axis) in cylindric extrusion boxed model '" - << name_ << "' !"); + << get_name() << "' !"); DT_THROW_IF(extrusion_x - extrusion_radius <= -0.5 * mother_x, std::logic_error, "Extrusion radius (" << extrusion_radius / CLHEP::mm << " mm) is too large (X-axis) in cylindric extrusion boxed model '" - << name_ << "' !"); + << get_name() << "' !"); DT_THROW_IF(extrusion_y + extrusion_radius >= +0.5 * mother_y, std::logic_error, "Extrusion radius (" << extrusion_radius / CLHEP::mm << " mm) is too large (Y-axis) in cylindric extrusion boxed model '" - << name_ << "' !"); + << get_name() << "' !"); DT_THROW_IF(extrusion_y - extrusion_radius <= -0.5 * mother_y, std::logic_error, "Extrusion radius (" << extrusion_radius / CLHEP::mm << " mm) is too large (y-axis) in cylindric extrusion boxed model '" - << name_ << "' !"); + << get_name() << "' !"); set_material_name (material_name); set_mother_x(mother_x); @@ -226,7 +225,7 @@ namespace geomtools { _mother_box_.set_z(get_mother_z()); _mother_box_.lock(); DT_THROW_IF(! _mother_box_.is_valid(), std::logic_error, - "Invalid box dimensions in cylindric extrusion boxed model '" << name_ << "' !"); + "Invalid box dimensions in cylindric extrusion boxed model '" << get_name() << "' !"); _extrusion_cylinder_.set_diameter(2 * get_extrusion_radius()); const double eps = 1.0e-5 * CLHEP::mm; @@ -283,7 +282,7 @@ namespace geomtools { _extruded_solid_.set_wires_drawer(*_drawer_); _extruded_solid_.lock(); - grab_logical ().set_name (i_model::make_logical_volume_name (name_)); + grab_logical ().set_name (i_model::make_logical_volume_name (get_name())); grab_logical ().set_shape (_extruded_solid_); grab_logical ().set_material_ref (material_name); grab_logical ().set_geometry_model (*this); diff --git a/source/bxgeomtools/src/extruded_box.cc b/source/bxgeomtools/src/extruded_box.cc index c46091bf7..6a24aa510 100644 --- a/source/bxgeomtools/src/extruded_box.cc +++ b/source/bxgeomtools/src/extruded_box.cc @@ -1123,6 +1123,29 @@ namespace geomtools { return nfaces; } + + void extruded_box::compute_envelope(box & envelope_, + double x_tolerance_, + double y_tolerance_, + double z_tolerance_) + { + DT_THROW_IF(! is_valid(), std::logic_error, "Invalid extruded box!"); + double x_eps = 0.0; + double y_eps = 0.0; + double z_eps = 0.0; + if (datatools::is_valid(x_tolerance_) and x_tolerance_ > 0.0) x_eps = x_tolerance_; + if (datatools::is_valid(y_tolerance_) and y_tolerance_ > 0.0) y_eps = y_tolerance_; + if (datatools::is_valid(z_tolerance_) and z_tolerance_ > 0.0) z_eps = z_tolerance_; + double x = get_x(); + double y = get_y(); + double z = get_z(); + x += (2 * x_eps); + y += (2 * y_eps); + z += (2 * z_eps); + envelope_.reset(); + envelope_.set(x, y, z); + envelope_.lock(); + } void extruded_box::generate_wires_self(wires_type & wires_, uint32_t options_) const diff --git a/source/bxgeomtools/src/extruded_box_model.cc b/source/bxgeomtools/src/extruded_box_model.cc index b11625325..b086cae23 100644 --- a/source/bxgeomtools/src/extruded_box_model.cc +++ b/source/bxgeomtools/src/extruded_box_model.cc @@ -65,8 +65,7 @@ namespace geomtools { return; } - void extruded_box_model::_at_construct(const std::string & name_, - const datatools::properties & config_, + void extruded_box_model::_at_construct(const datatools::properties & config_, models_col_type * /*models_*/) { DT_LOG_TRACE(get_logging_priority(), "Entering..."); @@ -78,26 +77,26 @@ namespace geomtools { } DT_THROW_IF(! config_.has_key("material.ref"), std::logic_error, - "Missing 'material.ref' property in extruded box model '" << name_ << "' !"); + "Missing 'material.ref' property in extruded box model '" << get_name() << "' !"); const std::string material_name = config_.fetch_string("material.ref"); DT_THROW_IF(! config_.has_key("x"), std::logic_error, - "Missing 'x' property in extruded box model '" << name_ << "' !"); + "Missing 'x' property in extruded box model '" << get_name() << "' !"); double x = config_.fetch_real("x"); if(! config_.has_explicit_unit("x")) x *= lunit; DT_THROW_IF(! config_.has_key("y"), std::logic_error, - "Missing 'y' property in extruded box model '" << name_ << "' !"); + "Missing 'y' property in extruded box model '" << get_name() << "' !"); double y = config_.fetch_real("y"); if(! config_.has_explicit_unit("y")) y *= lunit; DT_THROW_IF(! config_.has_key("z"), std::logic_error, - "Missing 'z' property in extruded box model '" << name_ << "' !"); + "Missing 'z' property in extruded box model '" << get_name() << "' !"); double z = config_.fetch_real("z"); if(! config_.has_explicit_unit("z")) z *= lunit; DT_THROW_IF(! config_.has_key("thickness"), std::logic_error, - "Missing 'thickness' property in extruded box model '" << name_ << "' !"); + "Missing 'thickness' property in extruded box model '" << get_name() << "' !"); double thickness = config_.fetch_real("thickness"); if(! config_.has_explicit_unit("thickness")) thickness *= lunit; @@ -128,7 +127,7 @@ namespace geomtools { _mother_box_.set_y(_extruded_box_.get_y()); _mother_box_.set_z(_extruded_box_.get_z()); DT_THROW_IF(! _mother_box_.is_valid(), std::logic_error, - "Invalid mother box dimensions in extruded box model '" << name_ << "' !"); + "Invalid mother box dimensions in extruded box model '" << get_name() << "' !"); _mother_box_.lock(); double daughter_z = _extruded_box_.get_z(); @@ -148,7 +147,7 @@ namespace geomtools { _daughter_box_.set_z(daughter_z); _daughter_box_.lock(); DT_THROW_IF(! _daughter_box_.is_valid(), std::logic_error, - "Invalid daughter box dimensions in extruded box model '" << name_ << "' !"); + "Invalid daughter box dimensions in extruded box model '" << get_name() << "' !"); const placement p2(vector_3d(0.0, 0.0, daughter_pos * _extruded_box_.get_thickness() / 2.), 0.0, 0.0, 0.0); @@ -233,7 +232,7 @@ namespace geomtools { _subtraction_box_.set_wires_drawer(*_drawer_); _subtraction_box_.lock(); - grab_logical().set_name(i_model::make_logical_volume_name(name_)); + grab_logical().set_name(i_model::make_logical_volume_name(get_name())); grab_logical().set_shape(_subtraction_box_); grab_logical().set_material_ref(material_name); grab_logical().set_geometry_model(*this); diff --git a/source/bxgeomtools/src/grid_model.cc b/source/bxgeomtools/src/grid_model.cc index e314944f4..340f5f1c1 100644 --- a/source/bxgeomtools/src/grid_model.cc +++ b/source/bxgeomtools/src/grid_model.cc @@ -141,15 +141,13 @@ namespace geomtools { return; } - void grid_model::_at_construct (const std::string & name_, - const datatools::properties & config_, + void grid_model::_at_construct (const datatools::properties & config_, models_col_type * models_) { DT_LOG_TRACE (get_logging_priority (), "Entering..."); - //set_name (name_); /*** material ***/ - DT_THROW_IF (! config_.has_key ("material.ref"), std::logic_error, "Missing 'material.ref' property in grid model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("material.ref"), std::logic_error, "Missing 'material.ref' property in grid model '" << get_name() << "' !"); std::string material_name = config_.fetch_string ("material.ref"); if (config_.has_flag ("grid.force_stackable")) { @@ -158,7 +156,7 @@ namespace geomtools { "grid.force_stackable.", stackable::STACKABLE_PREFIX); DT_THROW_IF (! _sd_.initialize(stackable_config), std::logic_error, - "Cannot build the stackable data in grid model '" << name_ << "' !"); + "Cannot build the stackable data in grid model '" << get_name() << "' !"); } double length_unit = CLHEP::mm; @@ -172,7 +170,7 @@ namespace geomtools { grid_daughter_label = config_.fetch_string ("grid.daughter_label"); } - DT_THROW_IF (! config_.has_key ("grid.plane"), std::logic_error, "Missing 'grid.plane' property in grid model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("grid.plane"), std::logic_error, "Missing 'grid.plane' property in grid model '" << get_name() << "' !"); const std::string grid_plane_label = config_.fetch_string ("grid.plane"); size_t number_of_items[2]; @@ -183,86 +181,86 @@ namespace geomtools { // Numbers of steps : DT_THROW_IF (! config_.has_key ("grid.x.number_of_items"), std::logic_error, - "Missing 'grid.x.number_of_items' property in grid model '" << name_ << "' !"); + "Missing 'grid.x.number_of_items' property in grid model '" << get_name() << "' !"); number_of_items[0] = config_.fetch_integer ("grid.x.number_of_items"); DT_THROW_IF (! config_.has_key ("grid.y.number_of_items"), std::logic_error, - "Missing 'grid.y.number_of_items' property in grid model '" << name_ << "' !"); + "Missing 'grid.y.number_of_items' property in grid model '" << get_name() << "' !"); number_of_items[1] = config_.fetch_integer ("grid.y.number_of_items"); // Steps : - DT_THROW_IF (! config_.has_key ("grid.x.step"), std::logic_error, "Missing 'grid.x.step' property in grid model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("grid.x.step"), std::logic_error, "Missing 'grid.x.step' property in grid model '" << get_name() << "' !"); step[0] = config_.fetch_real ("grid.x.step"); DT_THROW_IF (step[0] <= 0.0, std::logic_error, "Invalid value for 'grid.x.step' property !"); if (! config_.has_explicit_unit ("grid.x.step")) step[0] *= length_unit; - DT_THROW_IF (! config_.has_key ("grid.y.step"), std::logic_error, "Missing 'grid.y.step' property in grid model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("grid.y.step"), std::logic_error, "Missing 'grid.y.step' property in grid model '" << get_name() << "' !"); step[1] = config_.fetch_real ("grid.y.step"); - DT_THROW_IF (step[1] <= 0.0, std::logic_error, "Invalid value for 'grid.y.step' property in grid model '" << name_ << "' !"); + DT_THROW_IF (step[1] <= 0.0, std::logic_error, "Invalid value for 'grid.y.step' property in grid model '" << get_name() << "' !"); if (! config_.has_explicit_unit ("grid.y.step")) step[1] *= length_unit; } else if (grid_plane_label == "xz") { // Numbers of steps : DT_THROW_IF (! config_.has_key ("grid.x.number_of_items"), std::logic_error, - "Missing 'grid.x.number_of_items' property in grid model '" << name_ << "' !"); + "Missing 'grid.x.number_of_items' property in grid model '" << get_name() << "' !"); number_of_items[0] = config_.fetch_integer ("grid.x.number_of_items"); DT_THROW_IF (! config_.has_key ("grid.z.number_of_items"), std::logic_error, - "Missing 'grid.z.number_of_items' property in grid model '" << name_ << "' !"); + "Missing 'grid.z.number_of_items' property in grid model '" << get_name() << "' !"); number_of_items[1] = config_.fetch_integer ("grid.z.number_of_items"); // Steps : - DT_THROW_IF (! config_.has_key ("grid.x.step"), std::logic_error, "Missing 'grid.x.step' property in grid model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("grid.x.step"), std::logic_error, "Missing 'grid.x.step' property in grid model '" << get_name() << "' !"); step[0] = config_.fetch_real ("grid.x.step"); - DT_THROW_IF (step[0] <= 0.0, std::logic_error, "Invalid value for 'grid.x.step' property in grid model '" << name_ << "' !"); + DT_THROW_IF (step[0] <= 0.0, std::logic_error, "Invalid value for 'grid.x.step' property in grid model '" << get_name() << "' !"); if (! config_.has_explicit_unit ("grid.x.step")) step[0] *= length_unit; - DT_THROW_IF (! config_.has_key ("grid.z.step"), std::logic_error, "Missing 'grid.z.step' property in grid model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("grid.z.step"), std::logic_error, "Missing 'grid.z.step' property in grid model '" << get_name() << "' !"); step[1] = config_.fetch_real ("grid.z.step"); - DT_THROW_IF (step[1] <= 0.0, std::logic_error, "Invalid value for 'grid.z.step' property in grid model '" << name_ << "' !"); + DT_THROW_IF (step[1] <= 0.0, std::logic_error, "Invalid value for 'grid.z.step' property in grid model '" << get_name() << "' !"); if (! config_.has_explicit_unit ("grid.z.step")) step[1] *= length_unit; } else if (grid_plane_label == "yz") { // Numbers of steps : DT_THROW_IF (! config_.has_key ("grid.y.number_of_items"), std::logic_error, - "Missing 'grid.y.number_of_items' property in grid model '" << name_ << "' !"); + "Missing 'grid.y.number_of_items' property in grid model '" << get_name() << "' !"); number_of_items[0] = config_.fetch_integer ("grid.y.number_of_items"); DT_THROW_IF (! config_.has_key ("grid.z.number_of_items"), std::logic_error, - "Missing 'grid.z.number_of_items' property in grid model '" << name_ << "' !"); + "Missing 'grid.z.number_of_items' property in grid model '" << get_name() << "' !"); number_of_items[1] = config_.fetch_integer ("grid.z.number_of_items"); // Steps : - DT_THROW_IF (! config_.has_key ("grid.y.step"), std::logic_error, "Missing 'grid.y.step' property in grid model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("grid.y.step"), std::logic_error, "Missing 'grid.y.step' property in grid model '" << get_name() << "' !"); step[0] = config_.fetch_real ("grid.y.step"); - DT_THROW_IF (step[0] <= 0.0, std::logic_error, "Invalid value for 'grid.y.step' property in grid model '" << name_ << "' !"); + DT_THROW_IF (step[0] <= 0.0, std::logic_error, "Invalid value for 'grid.y.step' property in grid model '" << get_name() << "' !"); if (! config_.has_explicit_unit ("grid.y.step")) step[0] *= length_unit; - DT_THROW_IF (! config_.has_key ("grid.z.step"), std::logic_error, "Missing 'grid.z.step' property in grid model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("grid.z.step"), std::logic_error, "Missing 'grid.z.step' property in grid model '" << get_name() << "' !"); step[1] = config_.fetch_real ("grid.z.step"); - DT_THROW_IF (step[1] <= 0.0 , std::logic_error, "Invalid value for 'grid.z.step' property in grid model '" << name_ << "' !"); + DT_THROW_IF (step[1] <= 0.0 , std::logic_error, "Invalid value for 'grid.z.step' property in grid model '" << get_name() << "' !"); if (! config_.has_explicit_unit ("grid.z.step")) step[1] *= length_unit; } else { - DT_THROW_IF (true, std::logic_error, "Invalid grid plane label '" << grid_plane_label << "' property in grid model '" << name_ << "' !"); + DT_THROW_IF (true, std::logic_error, "Invalid grid plane label '" << grid_plane_label << "' property in grid model '" << get_name() << "' !"); } _grid_plane_label_ = grid_plane_label; - DT_THROW_IF (! config_.has_key ("grid.model"), std::logic_error, "Missing 'grid.model' property in grid model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("grid.model"), std::logic_error, "Missing 'grid.model' property in grid model '" << get_name() << "' !"); const std::string model_name = config_.fetch_string ("grid.model"); - DT_THROW_IF (number_of_items[0] == 0, std::logic_error, "Number of items on first axis is zero in grid model '" << name_ << "' !"); - DT_THROW_IF (number_of_items[1] == 0, std::logic_error, "Number of items on second axis is zero in grid model '" << name_ << "' !"); + DT_THROW_IF (number_of_items[0] == 0, std::logic_error, "Number of items on first axis is zero in grid model '" << get_name() << "' !"); + DT_THROW_IF (number_of_items[1] == 0, std::logic_error, "Number of items on second axis is zero in grid model '" << get_name() << "' !"); _number_of_items_[0] = number_of_items[0]; _number_of_items_[1] = number_of_items[1]; _step_[0] = step[0]; _step_[1] = step[1]; - DT_THROW_IF (! models_, std::logic_error, "Missing logicals dictionary in grid model '" << name_ << "' !"); + DT_THROW_IF (! models_, std::logic_error, "Missing logicals dictionary in grid model '" << get_name() << "' !"); // Stackable model: { models_col_type::const_iterator found = models_->find (model_name); - DT_THROW_IF (found == models_->end (), std::logic_error, "Cannot find model with name '" << model_name << "' in grid model '" << name_ << "' !"); + DT_THROW_IF (found == models_->end (), std::logic_error, "Cannot find model with name '" << model_name << "' in grid model '" << get_name() << "' !"); set_model (dynamic_cast(*(found->second))); } @@ -352,21 +350,21 @@ namespace geomtools { if (config_.has_key ("x")) { double x = config_.fetch_real ("x"); if (! config_.has_explicit_unit ("x")) x *= length_unit; - DT_THROW_IF (x < _x_, std::logic_error, "Value for 'x' property is too small (<" << _x_ / CLHEP::mm << " mm) in grid model '" << name_ << "' !"); + DT_THROW_IF (x < _x_, std::logic_error, "Value for 'x' property is too small (<" << _x_ / CLHEP::mm << " mm) in grid model '" << get_name() << "' !"); _x_ = x; } if (config_.has_key ("y")) { double y = config_.fetch_real ("y"); if (! config_.has_explicit_unit ("y")) y *= length_unit; - DT_THROW_IF (y < _y_, std::logic_error, "Value for 'y' property is too small (<" << _y_ / CLHEP::mm << " mm) in grid model '" << name_ << "' !"); + DT_THROW_IF (y < _y_, std::logic_error, "Value for 'y' property is too small (<" << _y_ / CLHEP::mm << " mm) in grid model '" << get_name() << "' !"); _y_ = y; } if (config_.has_key ("z")) { double z = config_.fetch_real ("z"); if (! config_.has_explicit_unit ("z")) z *= length_unit; - DT_THROW_IF (z < _z_, std::logic_error, "Value for 'z' property is too small (<" << _z_ / CLHEP::mm << " mm) in grid model '" << name_ << "' !"); + DT_THROW_IF (z < _z_, std::logic_error, "Value for 'z' property is too small (<" << _z_ / CLHEP::mm << " mm) in grid model '" << get_name() << "' !"); _z_ = z; } @@ -375,9 +373,9 @@ namespace geomtools { _solid_.set_y(_y_); _solid_.set_z(_z_); _solid_.lock(); - DT_THROW_IF (! _solid_.is_valid (), std::logic_error, "Invalid solid in grid model '" << name_ << "' !"); + DT_THROW_IF (! _solid_.is_valid (), std::logic_error, "Invalid solid in grid model '" << get_name() << "' !"); - grab_logical ().set_name (i_model::make_logical_volume_name (name_)); + grab_logical ().set_name (i_model::make_logical_volume_name (get_name())); grab_logical ().set_shape (_solid_); grab_logical ().set_material_ref (material_name); _grid_daughter_label_ = grid_daughter_label; diff --git a/source/bxgeomtools/src/hexagon_box.cc b/source/bxgeomtools/src/hexagon_box.cc index 01b33ec56..5675b23b2 100644 --- a/source/bxgeomtools/src/hexagon_box.cc +++ b/source/bxgeomtools/src/hexagon_box.cc @@ -419,6 +419,44 @@ namespace geomtools { return in_; } + void hexagon_box::compute_deflated(hexagon_box & deflated_, + double by_r_, + double by_z_) + { + DT_THROW_IF(! is_valid(), std::logic_error, "Invalid hexagon box!"); + double r_eps = 0.0; + double z_eps = 0.0; + if (datatools::is_valid(by_r_) and by_r_ > 0.0) r_eps = by_r_; + if (datatools::is_valid(by_z_) and by_z_ > 0.0) z_eps = by_z_; + double r = get_radius(); + double z = get_z(); + r -= r_eps; + z -= (2 * z_eps); + deflated_.reset(); + deflated_.set(r, z); + deflated_.lock(); + return; + } + + void hexagon_box::compute_inflated(hexagon_box & inflated_, + double by_r_, + double by_z_) + { + DT_THROW_IF(! is_valid(), std::logic_error, "Invalid hexagon box!"); + double r_eps = 0.0; + double z_eps = 0.0; + if (datatools::is_valid(by_r_) and by_r_ > 0.0) r_eps = by_r_; + if (datatools::is_valid(by_z_) and by_z_ > 0.0) z_eps = by_z_; + double r = get_radius(); + double z = get_z(); + r += r_eps; + z += (2 * z_eps); + inflated_.reset(); + inflated_.set(r, z); + inflated_.lock(); + return; + } + } // end of namespace geomtools // end of hexagon_box.cc diff --git a/source/bxgeomtools/src/i_model.cc b/source/bxgeomtools/src/i_model.cc index 1b08e7311..04e62dda2 100644 --- a/source/bxgeomtools/src/i_model.cc +++ b/source/bxgeomtools/src/i_model.cc @@ -183,6 +183,9 @@ namespace geomtools { void i_model::set_name(const std::string & name_) { + DT_THROW_IF(!datatools::name_validation(name_, datatools::NV_INSTANCE), + std::logic_error, + "Invalid model name '" << name_ << "'!"); _name_ = name_; return; } @@ -224,7 +227,7 @@ namespace geomtools { bool i_model::has_shape_factory() const { - return _shape_factory_ != 0; + return _shape_factory_ != nullptr; } void i_model::set_shape_factory(shape_factory & sf_) @@ -331,7 +334,9 @@ namespace geomtools { // Plug internal meshes: datatools::properties internal_mesh_setup; - setup_.export_and_rename_starting_with(internal_mesh_setup, model_with_internal_mesh_data::INTERNAL_MESH_PREFIX, ""); + setup_.export_and_rename_starting_with(internal_mesh_setup, + model_with_internal_mesh_data::INTERNAL_MESH_PREFIX, + ""); if (internal_mesh_setup.size()) { _meshes_.plug_internal_meshes(internal_mesh_setup, _logical, models_); } @@ -339,18 +344,51 @@ namespace geomtools { return; } + void i_model::_at_construct(const datatools::properties & /* setup_ */, + models_col_type * /* models_ */) + { + // // Nothing done here. TO be overriden by inherited models to free special internal resources setup at construction. + // DT_LOG_WARNING(datatools::logger::PRIO_ALWAYS, + // "Invoking the deprecated '_at_construct' method !"); + // DT_LOG_WARNING(datatools::logger::PRIO_ALWAYS, + // "Please reimplement using the '_at_construct(const datatools::properties &, geomtools::models_col_type *)' abstract method in place in the geometry model class '" << get_model_id() << "'!") + // _at_construct("", setup_, models_); + return; + } - void i_model::_at_destroy(const std::string & /* name_ */, - models_col_type * /* models_ */) + void i_model::_at_construct(const std::string & /* name_ */, + const datatools::properties & /* setup_ */, + models_col_type * /* models_ */) { - // Nothing done here. TO be overriden by inherited models to free special internal resourcessetup at construction. + // Unused deprecated method + DT_THROW(std::logic_error, "Deprecated method ! Check the new 'geomtools::i_model' interface!"); } - - void i_model::destroy(const std::string & name_, - models_col_type * models_) + void i_model::_at_destroy(models_col_type * /* models_ */) { - _at_destroy(name_, models_); + // Nothing done here. TO be overriden by inherited models to free special internal resources setup at construction. + } + + void i_model::destroy(models_col_type * models_) + { + _at_destroy(models_); + return; + } + + void i_model::construct(models_col_type * models_) + { + datatools::properties dummy_setup; + std::vector dummy; + construct("", dummy_setup, dummy, models_); + return; + } + + void i_model::construct(const std::string & name_, + models_col_type * models_) + { + datatools::properties dummy_setup; + std::vector dummy; + construct(name_, dummy_setup, dummy, models_); return; } @@ -385,6 +423,7 @@ namespace geomtools { if (_name_.empty() && ! name_.empty()) { set_name(name_); } + DT_THROW_IF(_name_.empty(), std::logic_error, "Missing geometry model name !"); { // Set description for logical parameters : std::ostringstream log_params_desc; @@ -396,7 +435,7 @@ namespace geomtools { properties_prefixes_); _mandatory_pre_construct(setup, models_); _pre_construct(setup, models_); - _at_construct(name_, setup, models_); + _at_construct(setup, models_); _post_construct(setup, models_); _mandatory_post_construct(setup, models_); _logical.set_geometry_model(*this); diff --git a/source/bxgeomtools/src/i_shape_3d.cc b/source/bxgeomtools/src/i_shape_3d.cc index 64a9aff24..c4874a897 100644 --- a/source/bxgeomtools/src/i_shape_3d.cc +++ b/source/bxgeomtools/src/i_shape_3d.cc @@ -734,12 +734,16 @@ namespace geomtools { void i_shape_3d::_at_unlock() { + if (has_computed_faces()) { + reset_computed_faces(); + } _reset_bounding_data(); return; } void i_shape_3d::build_default_bounding_data() { + _build_bounding_data(); return; } @@ -762,7 +766,6 @@ namespace geomtools { return _computed_faces_.has_data() && _computed_faces_.get().size() > 0; } - /// Return the collection of faces const face_info_collection_type & i_shape_3d::get_computed_faces() const { if (! _computed_faces_.has_data()) { diff --git a/source/bxgeomtools/src/model_factory.cc b/source/bxgeomtools/src/model_factory.cc index 6489a8f33..42983bce6 100644 --- a/source/bxgeomtools/src/model_factory.cc +++ b/source/bxgeomtools/src/model_factory.cc @@ -122,9 +122,9 @@ namespace geomtools { return *_shape_factory_; } - const models_col_type & model_factory::get_models() const + const model_bus_type & model_factory::get_models() const { - return _models_; + return _get_models_(); } const logical_volume::dict_type & model_factory::get_logicals() const @@ -145,6 +145,7 @@ namespace geomtools { _factory_register_.tree_dump(std::cerr, "Geometry model factory: ", "INFO: "); } } + _models_.reset(new model_bus_type(*this)); return; } @@ -152,7 +153,7 @@ namespace geomtools { : _factory_register_("geomtools::i_model/model_factory", (lp_ >= datatools::logger::PRIO_NOTICE) ? i_model::factory_register_type::verbose : 0) { - _shape_factory_ = 0; + _shape_factory_ = nullptr; _locked_ = false; _logging_priority_ = lp_; _basic_construct_(); @@ -164,7 +165,7 @@ namespace geomtools { core_factory_verbose_ ? i_model::factory_register_type::verbose : 0) { - _shape_factory_ = 0; + _shape_factory_ = nullptr; _locked_ = false; _logging_priority_ = datatools::logger::PRIO_FATAL; if (debug_) _logging_priority_ = datatools::logger::PRIO_DEBUG; @@ -177,9 +178,21 @@ namespace geomtools { if (_locked_) { reset(); } + _models_.reset(); return; } + model_bus_type & model_factory::_grab_models_() + { + return *_models_; + } + + const model_bus_type & model_factory::_get_models_() const + { + model_factory * mutable_this = const_cast(this); + return const_cast(mutable_this->_grab_models_()); + } + // 2012-05-25 FM : add support for loading a file that contains a list of geometry filenames : void model_factory::load_geom_list(const std::string & geom_list_file_) { @@ -283,26 +296,28 @@ namespace geomtools { // The container of logicals does not have ownership of the pointers : _logicals_.clear(); // Memory leak to be fixed: - for (models_col_type::iterator i = _models_.begin(); - i != _models_.end(); + for (model_bus_type::iterator i = _grab_models_().begin(); + i != _grab_models_().end(); i++) { const std::string & model_name = i->first; i_model * model_ptr = i->second; if (model_ptr != nullptr) { - if (model_ptr->is_constructed()) { - // This is the place from which individual models can perform - // special cleaning operations (see the overriden _at_destroy method) - model_ptr->destroy(model_name, &_models_); - } if (is_owned_model(model_name)) { + if (model_ptr->is_constructed()) { + // This is the place from which individual models can perform + // special cleaning operations (see the overriden _at_destroy method) + model_ptr->destroy(_models_.get()); + } DT_LOG_DEBUG(_logging_priority_,"Deleting registered model '" << model_name << "'."); delete model_ptr; } else { + // We do not explicitely destroy a not-owned mode here for this is not the responsabilty + // of the factory. model_ptr = nullptr; } } } - _models_.clear(); + _grab_models_().clear(); _owned_models_.clear(); _mp_.reset(); _property_prefixes_.clear(); @@ -330,6 +345,75 @@ namespace geomtools { return _owned_models_.count(model_name_) > 0; } + void model_factory::external_model_instance_registration(i_model & model_) + { + _model_instance_registration_(&model_); + return; + } + + void model_factory::external_model_instance_unregistration(i_model & model_) + { + DT_THROW_IF(_owned_models_.count(model_.get_name()), + std::logic_error, + "Model instance with name '" << model_.get_name() << "' is not an external model instance!"); + _model_instance_unregistration_(&model_); + return; + } + + void model_factory::_model_instance_unregistration_(i_model * model_) + { + DT_THROW_IF(! _get_models_().count(model_->get_name()), + std::logic_error, + "No model instance with name '" << model_->get_name() << "' is known from the registry of model instances!"); + + // Unregister all daughter logical volumes in the registry of logical volumes: + for (logical_volume::physicals_col_type::const_iterator iphys + = model_->get_logical().get_physicals().begin(); + iphys != model_->get_logical().get_physicals().end(); + iphys++) { + const physical_volume & phys_vol = *iphys->second; + if (phys_vol.has_logical()) { + const logical_volume & log_vol = phys_vol.get_logical(); + if (_logicals_.find(log_vol.get_name()) != _logicals_.end()) { + _logicals_.erase(log_vol.get_name()); + } + } + } + // Unregister the main logical volume from the model: + _logicals_.erase(model_->get_logical().get_name()); + _grab_models_().erase(model_->get_name()); + return; + } + + void model_factory::_model_instance_registration_(i_model * model_) + { + DT_THROW_IF(_get_models_().count(model_->get_name()), + std::logic_error, + "A model instance with name '" << model_->get_name() << "' is aalready known from the registry of model instances!"); + _grab_models_()[model_->get_name()] = model_; + std::string log_name = model_->get_logical().get_name(); + if (_logicals_.find(log_name) == _logicals_.end()) { + _logicals_[log_name] = &(model_->get_logical()); + } else { + DT_THROW(std::logic_error, + "Logical volume '" << log_name << "' is already referenced in the model factory !"); + } + // Register all daughter logical volumes in the registry of logical volumes: + for (logical_volume::physicals_col_type::const_iterator iphys + = model_->get_logical().get_physicals().begin(); + iphys != model_->get_logical().get_physicals().end(); + iphys++) { + const physical_volume & phys_vol = *iphys->second; + if (phys_vol.has_logical()) { + const logical_volume & log_vol = phys_vol.get_logical(); + if (_logicals_.find(log_vol.get_name()) == _logicals_.end()) { + _logicals_[log_vol.get_name()] = &log_vol; + } + } + } + return; + } + void model_factory::_construct_() { DT_LOG_TRACE(_logging_priority_, "Entering..."); @@ -363,18 +447,22 @@ namespace geomtools { if (has_shape_factory()) { model->set_shape_factory(grab_shape_factory()); } - model->construct(model_name, e.get_properties(), _property_prefixes_, &_models_); - _models_[model_name] = model; + model->construct(model_name, e.get_properties(), _property_prefixes_, _models_.get()); _owned_models_.insert(model_name); - DT_LOG_DEBUG(_logging_priority_,"Adding model '" << model_name << "'..."); + DT_LOG_DEBUG(_logging_priority_,"Adding owned model '" << model_name << "' in the registry of models..."); + _model_instance_registration_(model); + /* + _models_[model_name] = model; std::string log_name = model->get_logical().get_name(); if (_logicals_.find(log_name) == _logicals_.end()) { _logicals_[log_name] = &(model->get_logical()); } else { - DT_THROW_IF(true, std::runtime_error, - "Logical volume '" << log_name << "' is already referenced in the model factory !"); + DT_THROW(std::runtime_error, + "Logical volume '" << log_name << "' is already referenced in the model factory !"); } - for (logical_volume::physicals_col_type::const_iterator iphys = model->get_logical().get_physicals().begin(); + // Register all daughter logical volumes in the logical registry: + for (logical_volume::physicals_col_type::const_iterator iphys + = model->get_logical().get_physicals().begin(); iphys != model->get_logical().get_physicals().end(); iphys++) { const physical_volume & phys_vol = *iphys->second; @@ -385,8 +473,8 @@ namespace geomtools { } } } - - DT_LOG_DEBUG(_logging_priority_,"New model is:"); + */ + DT_LOG_DEBUG(_logging_priority_, "New model is:"); if (is_debug()) model->tree_dump(std::clog, "", "[debug]: "); } DT_LOG_TRACE(_logging_priority_,"Exiting."); @@ -454,23 +542,23 @@ namespace geomtools { { out_ << indent << datatools::i_tree_dumpable::inherit_tag(inherit_) << "Geometry models : "; - if ( _models_.size() == 0) { + if ( _get_models_().size() == 0) { out_ << ""; } else { - out_ << "[" << _models_.size() << "]"; + out_ << "[" << _get_models_().size() << "]"; } out_ << std::endl; - for (models_col_type::const_iterator i = _models_.begin(); - i != _models_.end(); + for (model_bus_type::const_iterator i = _get_models_().begin(); + i != _get_models_().end(); i++) { const std::string & key = i->first; const i_model * a_model = i->second; std::ostringstream indent_oss; out_ << indent << datatools::i_tree_dumpable::inherit_skip_tag(inherit_); indent_oss << indent << datatools::i_tree_dumpable::inherit_skip_tag(inherit_); - models_col_type::const_iterator j = i; + model_bus_type::const_iterator j = i; j++; - if (j == _models_.end()) { + if (j == _get_models_().end()) { out_ << datatools::i_tree_dumpable::inherit_tag(inherit_); indent_oss << datatools::i_tree_dumpable::inherit_skip_tag(inherit_); } else { @@ -540,7 +628,7 @@ namespace geomtools { //std::cerr << "DEVEL: model_factory::print_list_of_models: Parsed options. \n"; std::vector selected_models; - for (geomtools::models_col_type::const_iterator i + for (geomtools::model_bus_type::const_iterator i = mf_.get_models().begin(); i != mf_.get_models().end(); i++) { diff --git a/source/bxgeomtools/src/multiple_items_model.cc b/source/bxgeomtools/src/multiple_items_model.cc index 9767e2a6c..15639fc18 100644 --- a/source/bxgeomtools/src/multiple_items_model.cc +++ b/source/bxgeomtools/src/multiple_items_model.cc @@ -75,11 +75,9 @@ namespace geomtools { return; } - void multiple_items_model::_at_construct (const std::string & name_, - const datatools::properties & config_, + void multiple_items_model::_at_construct (const datatools::properties & config_, models_col_type * models_) { - //set_name (name_); /*** box dimensions ***/ double lunit = CLHEP::mm; @@ -91,7 +89,7 @@ namespace geomtools { double x; datatools::invalidate (x); DT_THROW_IF (! config_.has_key ("x"), std::logic_error, - "Missing 'x' property in multiple items model '" << name_ << "' !"); + "Missing 'x' property in multiple items model '" << get_name() << "' !"); x = config_.fetch_real ("x"); if (! config_.has_explicit_unit ("x")) { x *= lunit; @@ -100,7 +98,7 @@ namespace geomtools { double y; datatools::invalidate (y); DT_THROW_IF (! config_.has_key ("y"), std::logic_error, - "Missing 'y' property in multiple items model '" << name_ << "' !"); + "Missing 'y' property in multiple items model '" << get_name() << "' !"); y = config_.fetch_real ("y"); if (! config_.has_explicit_unit ("y")) { y *= lunit; @@ -109,7 +107,7 @@ namespace geomtools { double z; datatools::invalidate (z); DT_THROW_IF (! config_.has_key ("z"), std::logic_error, - "Missing 'z' property in multiple items model '" << name_ << "' !"); + "Missing 'z' property in multiple items model '" << get_name() << "' !"); z = config_.fetch_real ("z"); if (! config_.has_explicit_unit ("z")) { z *= lunit; @@ -117,7 +115,7 @@ namespace geomtools { DT_THROW_IF (! config_.has_key ("material.ref"), std::logic_error, - "Missing 'material.ref' property in multiple items model '" << name_ << "' !"); + "Missing 'material.ref' property in multiple items model '" << get_name() << "' !"); const std::string material_name = config_.fetch_string ("material.ref"); set_material_name (material_name); @@ -126,9 +124,9 @@ namespace geomtools { _solid_.set_y (y); _solid_.set_z (z); _solid_.lock (); - DT_THROW_IF (!_solid_.is_valid (), std::logic_error, "Invalid solid in multiple items model '" << name_ << "' !"); + DT_THROW_IF (!_solid_.is_valid (), std::logic_error, "Invalid solid in multiple items model '" << get_name() << "' !"); - grab_logical ().set_name (i_model::make_logical_volume_name (name_)); + grab_logical ().set_name (i_model::make_logical_volume_name (get_name())); grab_logical ().set_shape (_solid_); grab_logical ().set_material_ref (_material_name_); diff --git a/source/bxgeomtools/src/plain_model.cc b/source/bxgeomtools/src/plain_model.cc index 3186b1e05..36d1a0429 100644 --- a/source/bxgeomtools/src/plain_model.cc +++ b/source/bxgeomtools/src/plain_model.cc @@ -73,18 +73,22 @@ namespace geomtools { return; } - void plain_model::_at_construct (const std::string & name_, - const datatools::properties & /* config_ */, + void plain_model::_at_construct (const datatools::properties & /* config_ */, models_col_type * /* models_ */) { // Set the envelope solid shape: - grab_logical().set_name(i_model::make_logical_volume_name(name_)); + grab_logical().set_name(i_model::make_logical_volume_name(get_name())); grab_logical().set_shape(*_solid_); grab_logical().set_material_ref(_material_name_); grab_logical().set_geometry_model(*this); return; } + + // void plain_model::_at_destroy (models_col_type * /* models_ */) + // { + // return; + // } } // end of namespace geomtools diff --git a/source/bxgeomtools/src/plate_with_hole_model.cc b/source/bxgeomtools/src/plate_with_hole_model.cc index 8bfeff9d5..fc6a28d18 100644 --- a/source/bxgeomtools/src/plate_with_hole_model.cc +++ b/source/bxgeomtools/src/plate_with_hole_model.cc @@ -59,8 +59,7 @@ namespace geomtools { return; } - void plate_with_hole_model::_at_construct(const std::string & name_, - const datatools::properties & config_, + void plate_with_hole_model::_at_construct(const datatools::properties & config_, geomtools::models_col_type * /*models_*/) { /* Parse properties */ @@ -71,22 +70,22 @@ namespace geomtools { lunit = datatools::units::get_length_unit_from(lunit_str); } - DT_THROW_IF (!config_.has_key ("material.ref"), std::logic_error, "Missing 'material.ref' property in plate with hole model '" << name_ << "' !"); + DT_THROW_IF (!config_.has_key ("material.ref"), std::logic_error, "Missing 'material.ref' property in plate with hole model '" << get_name() << "' !"); _material_ = config_.fetch_string ("material.ref"); - DT_THROW_IF (! config_.has_key ("x"), std::logic_error, "Missing 'x' property in plate with hole model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("x"), std::logic_error, "Missing 'x' property in plate with hole model '" << get_name() << "' !"); double x = config_.fetch_real ("x"); if (! config_.has_explicit_unit ("x")) { x *= lunit; } - DT_THROW_IF (! config_.has_key ("y"), std::logic_error, "Missing 'y' property in plate with hole model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("y"), std::logic_error, "Missing 'y' property in plate with hole model '" << get_name() << "' !"); double y = config_.fetch_real ("y"); if (! config_.has_explicit_unit ("y")) { y *= lunit; } - DT_THROW_IF (! config_.has_key ("z"), std::logic_error, "Missing 'z' property in plate with hole model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("z"), std::logic_error, "Missing 'z' property in plate with hole model '" << get_name() << "' !"); double z = config_.fetch_real ("z"); if (! config_.has_explicit_unit ("z")) { z *= lunit; @@ -107,12 +106,12 @@ namespace geomtools { datatools::invalidate (x_hole); datatools::invalidate (y_hole); if (! datatools::is_valid (r_hole)) { - DT_THROW_IF (! config_.has_key ("x_hole"), std::logic_error, "Missing 'x_hole' property in plate with hole model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("x_hole"), std::logic_error, "Missing 'x_hole' property in plate with hole model '" << get_name() << "' !"); x_hole = config_.fetch_real ("x_hole"); if (! config_.has_explicit_unit ("x_hole")) { x_hole *= lunit; } - DT_THROW_IF (! config_.has_key ("y_hole"), std::logic_error, "Missing 'y_hole' property in plate with hole model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("y_hole"), std::logic_error, "Missing 'y_hole' property in plate with hole model '" << get_name() << "' !"); y_hole = config_.fetch_real ("y_hole"); if (! config_.has_explicit_unit ("y_hole")) { y_hole *= lunit; @@ -164,11 +163,11 @@ namespace geomtools { DT_THROW_IF ((hole_x_min < -0.5 * _x_) || (hole_x_max > 0.5 * _x_), std::logic_error, - "Hole size is too large for mother box dimension in plate with hole model '" << name_ << "' !"); + "Hole size is too large for mother box dimension in plate with hole model '" << get_name() << "' !"); DT_THROW_IF ((hole_y_min < -0.5 * _y_) || (hole_y_max > 0.5 * _y_), std::logic_error, - "Hole size is too large for mother box dimension in plate with hole model '" << name_ << "' !"); + "Hole size is too large for mother box dimension in plate with hole model '" << get_name() << "' !"); _mother_.set_x (_x_); _mother_.set_y (_y_); @@ -177,7 +176,7 @@ namespace geomtools { DT_THROW_IF (! _mother_.is_valid (), std::logic_error, - "Invalid dimension(s) for the mother box in plate with hole model '" << name_ << "' !"); + "Invalid dimension(s) for the mother box in plate with hole model '" << get_name() << "' !"); geomtools::placement hole_placement (_x_pos_hole_, _y_pos_hole_, 0.0, 0, 0, 0); double hole_vol = 0.0; @@ -195,7 +194,7 @@ namespace geomtools { _solid_.set_shapes(_mother_, _box_hole_, hole_placement); hole_vol = _box_hole_.get_volume(); } else { - DT_THROW_IF (true, std::logic_error, "No defined shape for hole in plate with hole model '" << name_ << "' !"); + DT_THROW_IF (true, std::logic_error, "No defined shape for hole in plate with hole model '" << get_name() << "' !"); } hole_vol *= (_z_ / _z_hole_); _solid_.set_forced_volume(_mother_.get_volume() - hole_vol); @@ -217,7 +216,7 @@ namespace geomtools { _solid_.set_wires_drawer(*_drawer_); _solid_.lock(); - grab_logical().set_name(i_model::make_logical_volume_name(name_)); + grab_logical().set_name(i_model::make_logical_volume_name(get_name())); grab_logical().set_shape(_solid_); grab_logical().set_material_ref(_material_); diff --git a/source/bxgeomtools/src/polycone.cc b/source/bxgeomtools/src/polycone.cc index 816c74045..f62eec1ec 100644 --- a/source/bxgeomtools/src/polycone.cc +++ b/source/bxgeomtools/src/polycone.cc @@ -602,36 +602,243 @@ namespace geomtools { return; } - void polycone::compute_inner_polycone (polycone & ip_) + void polycone::compute_inner_polycone (polycone & inner_) { - ip_.reset (); + inner_.reset (); for (polycone::rz_col_type::const_iterator i = _points_.begin (); i != _points_.end (); i++) { double z = i->first; - double rmax = i->second.rmin; + double rmin = i->second.rmin; bool add_it = true; if (add_it) { - ip_.add (z, rmax, false); + inner_.add (z, rmin, false); } } - ip_._compute_all_ (); - ip_.lock(); + inner_._start_angle_ = this->_start_angle_; + inner_._delta_angle_ = this->_delta_angle_; + inner_._compute_all_ (); + inner_.lock(); return; } - void polycone::compute_outer_polycone (polycone & op_) + void polycone::compute_outer_polycone (polycone & outer_) { - op_.reset (); + outer_.reset (); for (polycone::rz_col_type::const_iterator i = _points_.begin (); i != _points_.end (); i++) { double z = i->first; double rmax = i->second.rmax; - op_.add (z, 0.0, rmax, false); + outer_.add (z, 0.0, rmax, false); } - op_._compute_all_ (); - op_.lock(); + outer_._start_angle_ = this->_start_angle_; + outer_._delta_angle_ = this->_delta_angle_; + outer_._compute_all_(); + outer_.lock(); + return; + } + + void polycone::compute_inflated(polycone & inflated_, + double by_r_, + double by_z_, + double by_angle_) + { + DT_THROW_IF(! is_valid(), std::logic_error, "Invalid polycone!"); + double r_eps = 0.0; + double z_eps = 0.0; + if (datatools::is_valid(by_r_) and by_r_ > 0.0) r_eps = by_r_; + if (datatools::is_valid(by_z_) and by_z_ > 0.0) z_eps = by_z_; + bool apply_inflated_z = false; + if (z_eps > 0.0) { + apply_inflated_z = true; + } + inflated_.reset(); + size_t sz = _points_.size(); + std::size_t counter = 0; + double maxR = -1.0; + for (polycone::rz_col_type::const_iterator i = _points_.begin(); + i != _points_.end(); + i++) { + double z = i->first; + double rmin = i->second.rmin; + double rmax = i->second.rmax; + rmax += r_eps; + if (datatools::is_valid(rmin) and rmin >= 0.0) { + rmin -= r_eps; + } else { + rmin = 0.0; + } + if (maxR < 0.0 or rmax > maxR) { + maxR = rmax; + } + if (rmax < 0.0) rmax = 0.0; + if (rmin < 0.0) rmin = 0.0; + if (apply_inflated_z) { + if (counter == 0) { + if (rmin < rmax) { + inflated_.add(z - z_eps, rmin, rmax, false); + } else { + inflated_.add(z - z_eps, i->second.rmin, i->second.rmax, false); + } + } + } + inflated_.add(z, rmin, rmax, false); + if (apply_inflated_z) { + if (counter + 1 == sz) { + if (rmin < rmax) { + inflated_.add(z + z_eps, rmin, rmax, false); + }else { + inflated_.add(z + z_eps, i->second.rmin, i->second.rmax, false); + } + } + } + counter++; + } + double eps_angle = by_angle_; + if (eps_angle < 0.0) { + eps_angle = r_eps / maxR; + } + if (has_partial_angle()) { + double start_angle = get_start_angle(); + double delta_angle = get_delta_angle(); + if (eps_angle > 0.0) { + start_angle += eps_angle; + delta_angle -= 2 * eps_angle; + if (delta_angle < 0.0) { + start_angle = get_start_angle() + 0.5 * get_delta_angle() - 0.25 * eps_angle; + delta_angle = 0.5 * eps_angle; + } + } + inflated_.set_start_angle(start_angle); + inflated_.set_delta_angle(delta_angle); + } + inflated_._compute_all_(); + inflated_.lock(); + return; + } + + void polycone::compute_deflated(polycone & deflated_, + double by_r_, + double by_z_, + double by_angle_) + { + DT_THROW_IF(! is_valid(), std::logic_error, "Invalid polycone!"); + double r_eps = 0.0; + double z_eps = 0.0; + if (datatools::is_valid(by_r_) and by_r_ > 0.0) r_eps = by_r_; + if (datatools::is_valid(by_z_) and by_z_ > 0.0) z_eps = by_z_; + bool apply_tolerance_z = false; + if (z_eps > 0.0) { + apply_tolerance_z = true; + } + deflated_.reset(); + size_t sz = _points_.size(); + std::size_t counter = 0; + bool skip_next = true; + double maxR = -1.0; + for (polycone::rz_col_type::const_iterator i = _points_.begin(); + i != _points_.end(); + i++) { + double z = i->first; + double rmin = i->second.rmin; + double rmax = i->second.rmax; + rmax -= r_eps; + if (datatools::is_valid(rmin) and rmin > 0.0) { + rmin += r_eps; + } else { + rmin = 0.0; + } + if (maxR < 0.0 or rmax > maxR) { + maxR = rmax; + } + if (rmax < 0.0) rmax = 0.0; + if (rmin < 0.0) rmin = 0.0; + if (rmax < rmin) { + double rmed = 0.5 * (rmax + rmin); + rmax = rmed; + rmin = rmed; + } + double z0 = z; + if (apply_tolerance_z) { + if (skip_next) { + z0 += z_eps; + auto j = i; + j++; + double z1 = j->first; + if (z0 <= z1) skip_next = false; + } + } + deflated_.add(z0, rmin, rmax, false); + counter++; + if (counter == sz / 2) { + break; + } + } + counter = 0; + skip_next = true; + for (polycone::rz_col_type::const_reverse_iterator i = _points_.rbegin (); + i != _points_.rend (); + i++) { + double z = i->first; + double rmin = i->second.rmin; + double rmax = i->second.rmax; + rmax -= r_eps; + if (datatools::is_valid(rmin)) { + rmin -= r_eps; + } else { + rmin = 0.0; + } + if (maxR < 0.0 or rmax > maxR) { + maxR = rmax; + } + if (rmax < 0.0) rmax = 0.0; + if (rmin < 0.0) rmin = 0.0; + double z0 = z; + if (apply_tolerance_z) { + if (skip_next) { + z0 -= z_eps; + auto j = i; + j++; + double z1 = j->first; + if (z0 <= z1) skip_next = false; + } + } + deflated_.add(z0, rmin, rmax, false); + counter++; + if (counter > sz / 2) { + break; + } + } + double eps_angle = by_angle_; + if (eps_angle < 0.0) { + eps_angle = r_eps / maxR; + } + if (has_partial_angle()) { + double start_angle = get_start_angle(); + double delta_angle = get_delta_angle(); + if (eps_angle > 0.0) { + start_angle += eps_angle; + delta_angle -= 2 * eps_angle; + if (delta_angle < 0.0) { + start_angle = get_start_angle() + 0.5 * get_delta_angle() - 0.25 * eps_angle; + delta_angle = 0.5 * eps_angle; + } + } + deflated_.set_start_angle(start_angle); + deflated_.set_delta_angle(delta_angle); + } + deflated_._compute_all_(); + deflated_.lock(); + return; + } + + void polycone::compute_envelope(polycone & envelope_, + double r_tolerance_, + double z_tolerance_, + double angle_tolerance_) + { + compute_inflated(envelope_, r_tolerance_, z_tolerance_, angle_tolerance_); return; } diff --git a/source/bxgeomtools/src/polyhedra.cc b/source/bxgeomtools/src/polyhedra.cc index 647267071..7c165e579 100644 --- a/source/bxgeomtools/src/polyhedra.cc +++ b/source/bxgeomtools/src/polyhedra.cc @@ -1093,6 +1093,213 @@ namespace geomtools { return; } + void polyhedra::compute_inflated(polyhedra & inflated_, + double by_r_, + double by_z_) + { + DT_THROW_IF(! is_valid(), std::logic_error, "Invalid polyhedra!"); + double r_eps = 0.0; + double z_eps = 0.0; + if (datatools::is_valid(by_r_) and by_r_ > 0.0) r_eps = by_r_; + if (datatools::is_valid(by_z_) and by_z_ > 0.0) z_eps = by_z_; + bool apply_inflated_z = false; + if (z_eps > 0.0) { + apply_inflated_z = true; + } + inflated_.reset(); + inflated_.set_n_sides(this->get_n_sides()); + size_t sz = _points_.size(); + std::size_t counter = 0; + double maxR = -1.0; + for (polyhedra::rz_col_type::const_iterator i = _points_.begin(); + i != _points_.end(); + i++) { + double z = i->first; + double rmin = i->second.rmin; + double rmax = i->second.rmax; + rmax += r_eps; + if (datatools::is_valid(rmin) and rmin >= 0.0) { + rmin -= r_eps; + } else { + rmin = 0.0; + } + if (maxR < 0.0 or rmax > maxR) { + maxR = rmax; + } + if (rmax < 0.0) rmax = 0.0; + if (rmin < 0.0) rmin = 0.0; + if (apply_inflated_z) { + if (counter == 0) { + if (rmin < rmax) { + inflated_.add(z - z_eps, rmin, rmax, false); + } else { + inflated_.add(z - z_eps, i->second.rmin, i->second.rmax, false); + } + } + } + inflated_.add(z, rmin, rmax, false); + if (apply_inflated_z) { + if (counter + 1 == sz) { + if (rmin < rmax) { + inflated_.add(z + z_eps, rmin, rmax, false); + }else { + inflated_.add(z + z_eps, i->second.rmin, i->second.rmax, false); + } + } + } + counter++; + } + inflated_._compute_all_(); + inflated_.lock(); + return; + } + + void polyhedra::compute_deflated(polyhedra & deflated_, + double by_r_, + double by_z_) + { + DT_THROW_IF(! is_valid(), std::logic_error, "Invalid polyhedra!"); + double r_eps = 0.0; + double z_eps = 0.0; + if (datatools::is_valid(by_r_) and by_r_ > 0.0) r_eps = by_r_; + if (datatools::is_valid(by_z_) and by_z_ > 0.0) z_eps = by_z_; + bool apply_tolerance_z = false; + if (z_eps > 0.0) { + apply_tolerance_z = true; + } + deflated_.reset(); + deflated_.set_n_sides(this->get_n_sides()); + size_t sz = _points_.size(); + std::size_t counter = 0; + bool skip_next = true; + double maxR = -1.0; + for (polyhedra::rz_col_type::const_iterator i = _points_.begin(); + i != _points_.end(); + i++) { + double z = i->first; + double rmin = i->second.rmin; + double rmax = i->second.rmax; + rmax -= r_eps; + if (datatools::is_valid(rmin) and rmin > 0.0) { + rmin += r_eps; + } else { + rmin = 0.0; + } + if (maxR < 0.0 or rmax > maxR) { + maxR = rmax; + } + if (rmax < 0.0) rmax = 0.0; + if (rmin < 0.0) rmin = 0.0; + if (rmax < rmin) { + double rmed = 0.5 * (rmax + rmin); + rmax = rmed; + rmin = rmed; + } + double z0 = z; + if (apply_tolerance_z) { + if (skip_next) { + z0 += z_eps; + auto j = i; + j++; + double z1 = j->first; + if (z0 <= z1) skip_next = false; + } + } + deflated_.add(z0, rmin, rmax, false); + counter++; + if (counter == sz / 2) { + break; + } + } + counter = 0; + skip_next = true; + for (polyhedra::rz_col_type::const_reverse_iterator i = _points_.rbegin (); + i != _points_.rend (); + i++) { + double z = i->first; + double rmin = i->second.rmin; + double rmax = i->second.rmax; + rmax -= r_eps; + if (datatools::is_valid(rmin)) { + rmin -= r_eps; + } else { + rmin = 0.0; + } + if (maxR < 0.0 or rmax > maxR) { + maxR = rmax; + } + if (rmax < 0.0) rmax = 0.0; + if (rmin < 0.0) rmin = 0.0; + double z0 = z; + if (apply_tolerance_z) { + if (skip_next) { + z0 -= z_eps; + auto j = i; + j++; + double z1 = j->first; + if (z0 <= z1) skip_next = false; + } + } + deflated_.add(z0, rmin, rmax, false); + counter++; + if (counter > sz / 2) { + break; + } + } + deflated_._compute_all_(); + deflated_.lock(); + return; + } + + void polyhedra::compute_envelope(polyhedra & envelope_, + double r_tolerance_, + double z_tolerance_) + { + compute_inflated(envelope_, r_tolerance_, z_tolerance_); + return; + } + + /* + void polyhedra::compute_envelope(polyhedra & op_, + double r_tolerance_, + double z_tolerance_) + { + op_.reset (); + op_.set_n_sides (this->get_n_sides()); + double r_eps = 0.0; + double z_eps = 0.0; + bool apply_tolerance_z = false; + // bool apply_tolerance_r = false; + if (datatools::is_valid(r_tolerance_) and r_tolerance_ > 0.0) { + r_eps = r_tolerance_; + // apply_tolerance_r = true; + } + if (datatools::is_valid(z_tolerance_) and z_tolerance_ > 0.0) { + z_eps = z_tolerance_; + apply_tolerance_z = true; + } + std::size_t counter = 0; + for (polyhedra::rz_col_type::const_iterator i = _points_.begin (); + i != _points_.end (); + i++) { + double z = i->first; + double rmax = i->second.rmax; + rmax += r_eps; + if (apply_tolerance_z and counter == 0) { + op_.add(z - z_eps, 0.0, rmax, false); + } + op_.add(z, 0.0, rmax, false); + if (apply_tolerance_z and (counter + 1) == _points_.size()) { + op_.add(z + z_eps, 0.0, rmax, false); + } + counter++; + } + op_._compute_all_(); + op_.lock(); + return; + } + */ + double polyhedra::get_surface (uint32_t mask_) const { DT_THROW_IF (! is_valid (), std::logic_error, "Polyhedra is not valid !"); diff --git a/source/bxgeomtools/src/rectangle.cc b/source/bxgeomtools/src/rectangle.cc index 37c2d47c0..90a9925f1 100644 --- a/source/bxgeomtools/src/rectangle.cc +++ b/source/bxgeomtools/src/rectangle.cc @@ -304,6 +304,16 @@ namespace geomtools { } uint32_t nsamples_x = nsamples; uint32_t nsamples_y = nsamples; + if (options_ & WR_BASE_BEST_GRID_SAMPLING) { + double lstep =(_x_+_y_) / 3; + int guessed_nsamples_x = (int) (_x_ / lstep); + if (guessed_nsamples_x < 2) guessed_nsamples_x = 2; + nsamples_x = guessed_nsamples_x; + int guessed_nsamples_y = (int) (_y_ / lstep); + if (guessed_nsamples_y < 2) guessed_nsamples_y = 2; + nsamples_y = guessed_nsamples_y; + } + double dx = _x_ / (nsamples_x - 1); double dy = _y_ / (nsamples_y - 1); for (int j = AXIS_X; j <= AXIS_Y; j++) { diff --git a/source/bxgeomtools/src/replicated_boxed_model.cc b/source/bxgeomtools/src/replicated_boxed_model.cc index 6a6024261..b586ecd81 100644 --- a/source/bxgeomtools/src/replicated_boxed_model.cc +++ b/source/bxgeomtools/src/replicated_boxed_model.cc @@ -87,16 +87,14 @@ namespace geomtools { return; } - void replicated_boxed_model::_at_construct (const std::string & name_, - const datatools::properties & config_, + void replicated_boxed_model::_at_construct (const datatools::properties & config_, models_col_type * models_) { DT_LOG_TRACE (get_logging_priority (), "Entering..."); - //set_name (name_); DT_THROW_IF (! config_.has_key ("material.ref"), std::logic_error, - "Missing 'material.ref' property in replicated boxed model '" << name_ << "' !"); + "Missing 'material.ref' property in replicated boxed model '" << get_name() << "' !"); const std::string material_name = config_.fetch_string ("material.ref"); std::string replicated_label = "replicated"; @@ -107,34 +105,34 @@ namespace geomtools { DT_THROW_IF (! config_.has_key ("replicated.axis"), std::logic_error, - "Missing 'replicated.axis' property in replicated boxed model '" << name_ << "' !"); + "Missing 'replicated.axis' property in replicated boxed model '" << get_name() << "' !"); const std::string replicant_axis_label = config_.fetch_string ("replicated.axis"); DT_THROW_IF (! config_.has_key ("replicated.model"), std::logic_error, - "Missing 'replicated.model' property in replicated boxed model '" << name_ << "' !"); + "Missing 'replicated.model' property in replicated boxed model '" << get_name() << "' !"); const std::string boxed_model_name = config_.fetch_string ("replicated.model"); DT_THROW_IF (! config_.has_key ("replicated.number_of_items"), std::logic_error, - "Missing 'replicated.number_of_items' property in replicated boxed model '" << name_ << "' !"); + "Missing 'replicated.number_of_items' property in replicated boxed model '" << get_name() << "' !"); const size_t number_of_items = config_.fetch_integer ("replicated.number_of_items"); - DT_THROW_IF (number_of_items == 0, std::logic_error, "Number of items is zero in replicated boxed model '" << name_ << "' !"); + DT_THROW_IF (number_of_items == 0, std::logic_error, "Number of items is zero in replicated boxed model '" << get_name() << "' !"); set_number_of_items (number_of_items); bool axis_ok = false; if (replicant_axis_label == "x") axis_ok = true; else if (replicant_axis_label == "y") axis_ok = true; else if (replicant_axis_label == "z") axis_ok = true; - DT_THROW_IF (! axis_ok, std::logic_error, "Invalid replicant axis in replicated boxed model '" << name_ << "' !"); + DT_THROW_IF (! axis_ok, std::logic_error, "Invalid replicant axis in replicated boxed model '" << get_name() << "' !"); - DT_THROW_IF (! models_, std::logic_error, "Missing logicals dictionary in replicated boxed model '" << name_ << "' !"); + DT_THROW_IF (! models_, std::logic_error, "Missing logicals dictionary in replicated boxed model '" << get_name() << "' !"); // Boxed model: { models_col_type::const_iterator found = models_->find (boxed_model_name); DT_THROW_IF (found == models_->end (), std::logic_error, - "Cannot find model with name '" << boxed_model_name << "' in replicated boxed model '" << name_ << "' !"); + "Cannot find model with name '" << boxed_model_name << "' in replicated boxed model '" << get_name() << "' !"); set_boxed_model (dynamic_cast(*(found->second))); } @@ -170,9 +168,9 @@ namespace geomtools { _solid_.set_y(_y_); _solid_.set_z(_z_); _solid_.lock(); - DT_THROW_IF (! _solid_.is_valid (), std::logic_error, "Invalid solid in replicated boxed model '" << name_ << "' !"); + DT_THROW_IF (! _solid_.is_valid (), std::logic_error, "Invalid solid in replicated boxed model '" << get_name() << "' !"); - grab_logical ().set_name (i_model::make_logical_volume_name (name_)); + grab_logical ().set_name (i_model::make_logical_volume_name (get_name())); grab_logical ().set_shape (_solid_); // 2013-06-13 FM : we cannot use the boxed model material here // There is no garantee it is the proper one to be used for the envelope solid. diff --git a/source/bxgeomtools/src/replicated_circular_model.cc b/source/bxgeomtools/src/replicated_circular_model.cc index 5d964c6f3..c5fd8191b 100644 --- a/source/bxgeomtools/src/replicated_circular_model.cc +++ b/source/bxgeomtools/src/replicated_circular_model.cc @@ -107,8 +107,7 @@ namespace geomtools { return; } - void replicated_circular_model::_at_construct(const std::string & name_, - const datatools::properties & config_, + void replicated_circular_model::_at_construct(const datatools::properties & config_, models_col_type * models_) { DT_LOG_TRACE(get_logging_priority(), "Entering..."); @@ -127,7 +126,7 @@ namespace geomtools { DT_THROW_IF(! config_.has_key("material.ref"), std::logic_error, - "Missing 'material.ref' property in replicated circular model '" << name_ << "' !"); + "Missing 'material.ref' property in replicated circular model '" << get_name() << "' !"); const std::string material_name = config_.fetch_string("material.ref"); std::string replicated_label = "replicated"; @@ -137,24 +136,24 @@ namespace geomtools { // DT_THROW_IF(! config_.has_key("replicated.rotation_axis"), // std::logic_error, - // "Missing 'rotation.axis' property in replicated circular model '" << name_ << "' !"); + // "Missing 'rotation.axis' property in replicated circular model '" << get_name() << "' !"); // const std::string rotation_axis_label = config_.fetch_string("replicated.rotation_axis"); const std::string rotation_axis_label = "z"; // DT_THROW_IF( rotation_axis_label != "z", // std::logic_error, // "Unsupported '" << rotation_axis_label << "' " - // << "rotation axis in replicated circular model '" << name_ << "' !"); + // << "rotation axis in replicated circular model '" << get_name() << "' !"); DT_THROW_IF(! config_.has_key("replicated.model"), std::logic_error, - "Missing 'replicated.model' property in replicated circular model '" << name_ << "' !"); + "Missing 'replicated.model' property in replicated circular model '" << get_name() << "' !"); const std::string model_name = config_.fetch_string("replicated.model"); DT_THROW_IF(! config_.has_key("replicated.number_of_items"), std::logic_error, - "Missing 'replicated.number_of_items' property in replicated boxed model '" << name_ << "' !"); + "Missing 'replicated.number_of_items' property in replicated boxed model '" << get_name() << "' !"); const size_t number_of_items = config_.fetch_integer("replicated.number_of_items"); - DT_THROW_IF(number_of_items <= 1, std::logic_error, "Number of items is < 1 in replicated boxed model '" << name_ << "' !"); + DT_THROW_IF(number_of_items <= 1, std::logic_error, "Number of items is < 1 in replicated boxed model '" << get_name() << "' !"); bool axis_ok = false; rotation_axis_type replicated_rotation_axis = ROTATION_AXIS_Z; @@ -169,19 +168,19 @@ namespace geomtools { replicated_rotation_axis = ROTATION_AXIS_Z; } DT_THROW_IF(! axis_ok, std::logic_error, "Invalid rotation replicant axis '" << rotation_axis_label<< "' " - << "in replicated circular model '" << name_ << "' !"); + << "in replicated circular model '" << get_name() << "' !"); DT_THROW_IF( replicated_rotation_axis != ROTATION_AXIS_Z, std::logic_error, "Unsupported '" << rotation_axis_label << "' " - << "rotation axis in replicated circular model '" << name_ << "' !"); + << "rotation axis in replicated circular model '" << get_name() << "' !"); - DT_THROW_IF(! models_, std::logic_error, "Missing logicals dictionary in replicated circular model '" << name_ << "' !"); + DT_THROW_IF(! models_, std::logic_error, "Missing logicals dictionary in replicated circular model '" << get_name() << "' !"); // Model: { models_col_type::const_iterator found = models_->find(model_name); DT_THROW_IF(found == models_->end(), std::logic_error, - "Cannot find model with name '" << model_name << "' in replicated circular model '" << name_ << "' !"); + "Cannot find model with name '" << model_name << "' in replicated circular model '" << get_name() << "' !"); set_model(dynamic_cast(*(found->second))); } @@ -189,7 +188,7 @@ namespace geomtools { double replicated_radius; DT_THROW_IF(! config_.has_key("replicated.radius"), std::logic_error, - "Missing 'replicated.radius' property in replicated circular model '" << name_ << "' !"); + "Missing 'replicated.radius' property in replicated circular model '" << get_name() << "' !"); replicated_radius = config_.fetch_real("replicated.radius"); if (! config_.has_explicit_unit("replicated.radius")) { replicated_radius *= default_length_unit; @@ -197,7 +196,7 @@ namespace geomtools { double replicated_step_angle; DT_THROW_IF(! config_.has_key("replicated.step_angle"), std::logic_error, - "Missing 'replicated.step_angle' property in replicated circular model '" << name_ << "' !"); + "Missing 'replicated.step_angle' property in replicated circular model '" << get_name() << "' !"); replicated_step_angle = config_.fetch_real("replicated.step_angle"); if (! config_.has_explicit_unit("replicated.step_angle")) { replicated_step_angle *= default_angle_unit; @@ -220,7 +219,7 @@ namespace geomtools { double mother_z; DT_THROW_IF(! config_.has_key("r_max"), std::logic_error, - "Missing 'r_max' property in replicated circular model '" << name_ << "' !"); + "Missing 'r_max' property in replicated circular model '" << get_name() << "' !"); mother_r_max = config_.fetch_real("r_max"); if (! config_.has_explicit_unit("r_max")) { mother_r_max *= default_length_unit; @@ -233,7 +232,7 @@ namespace geomtools { } DT_THROW_IF(! config_.has_key("z"), std::logic_error, - "Missing 'z' property in replicated circular model '" << name_ << "' !"); + "Missing 'z' property in replicated circular model '" << get_name() << "' !"); mother_z = config_.fetch_real("z"); if (! config_.has_explicit_unit("z")) { mother_z *= default_length_unit; @@ -253,9 +252,9 @@ namespace geomtools { _solid_.set(mother_r_min, mother_r_max, mother_z); _solid_.lock(); DT_THROW_IF(! _solid_.is_valid(), std::logic_error, - "Invalid mother tube solid in replicated circular model '" << name_ << "' !"); + "Invalid mother tube solid in replicated circular model '" << get_name() << "' !"); - grab_logical().set_name(i_model::make_logical_volume_name(name_)); + grab_logical().set_name(i_model::make_logical_volume_name(get_name())); grab_logical().set_shape(_solid_); grab_logical().set_material_ref(material_name); diff --git a/source/bxgeomtools/src/replicated_model.cc b/source/bxgeomtools/src/replicated_model.cc index 20208d0c2..58041d853 100644 --- a/source/bxgeomtools/src/replicated_model.cc +++ b/source/bxgeomtools/src/replicated_model.cc @@ -140,17 +140,15 @@ namespace geomtools { return; } - void replicated_model::_at_construct (const std::string & name_, - const datatools::properties & config_, + void replicated_model::_at_construct (const datatools::properties & config_, models_col_type * models_) { DT_LOG_TRACE (get_logging_priority (), "Entering..."); - //set_name (name_); /*** material ***/ DT_THROW_IF (! config_.has_key ("material.ref"), std::logic_error, - "Missing 'material.ref' property in replicated model '" << name_ << "' !"); + "Missing 'material.ref' property in replicated model '" << get_name() << "' !"); const std::string material_name = config_.fetch_string ("material.ref"); if (config_.has_flag ("replicated.force_stackable")) @@ -161,7 +159,7 @@ namespace geomtools { stackable::STACKABLE_PREFIX); DT_THROW_IF (! _sd_.initialize (stackable_config), std::logic_error, - "Cannot build the stackable data in replicated model '" << name_ << "' !"); + "Cannot build the stackable data in replicated model '" << get_name() << "' !"); } std::string replicated_label = "replicated"; @@ -170,13 +168,13 @@ namespace geomtools { replicated_label = config_.fetch_string ("replicated.label"); } - DT_THROW_IF (! config_.has_key ("replicated.axis"), std::logic_error, "Missing 'replicated.axis' property in replicated model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("replicated.axis"), std::logic_error, "Missing 'replicated.axis' property in replicated model '" << get_name() << "' !"); const std::string replicant_axis_label = config_.fetch_string ("replicated.axis"); - DT_THROW_IF (! config_.has_key ("replicated.number_of_items"), std::logic_error, "Missing 'replicated.number_of_items' property in replicated model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("replicated.number_of_items"), std::logic_error, "Missing 'replicated.number_of_items' property in replicated model '" << get_name() << "' !"); const size_t number_of_items = config_.fetch_integer ("replicated.number_of_items"); - DT_THROW_IF (! config_.has_key ("replicated.model"), std::logic_error, "Missing 'replicated.model' property in replicated model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("replicated.model"), std::logic_error, "Missing 'replicated.model' property in replicated model '" << get_name() << "' !"); const std::string model_name = config_.fetch_string ("replicated.model"); double default_length_unit = CLHEP::mm; @@ -215,22 +213,22 @@ namespace geomtools { if (config_.has_key ("replicated.step")) { _step_ = config_.fetch_real ("replicated.step"); - DT_THROW_IF (_step_ <= 0.0, std::logic_error, "Invalid value for 'replicated.step' property in replicated model '" << name_ << "' !"); + DT_THROW_IF (_step_ <= 0.0, std::logic_error, "Invalid value for 'replicated.step' property in replicated model '" << get_name() << "' !"); if (! config_.has_explicit_unit ("replicated.step")) { _step_ *= default_length_unit; } } - DT_THROW_IF (number_of_items == 0, std::logic_error, "Number of items is zero in replicated model '" << name_ << "' !"); + DT_THROW_IF (number_of_items == 0, std::logic_error, "Number of items is zero in replicated model '" << get_name() << "' !"); set_number_of_items (number_of_items); bool axis_ok = false; if (replicant_axis_label == "x") axis_ok = true; else if (replicant_axis_label == "y") axis_ok = true; else if (replicant_axis_label == "z") axis_ok = true; - DT_THROW_IF (! axis_ok, std::logic_error, "Invalid replicant axis in replicated model '" << name_ << "' !"); + DT_THROW_IF (! axis_ok, std::logic_error, "Invalid replicant axis in replicated model '" << get_name() << "' !"); - DT_THROW_IF (! models_, std::logic_error, "Missing logicals dictionary in replicated model '" << name_ << "' !"); + DT_THROW_IF (! models_, std::logic_error, "Missing logicals dictionary in replicated model '" << get_name() << "' !"); // Stackable model: { @@ -302,9 +300,9 @@ namespace geomtools { _solid_.set_y(_y_); _solid_.set_z(_z_); _solid_.lock(); - DT_THROW_IF (! _solid_.is_valid(), std::logic_error, "Invalid solid in replicated model '" << name_ << "' !"); + DT_THROW_IF (! _solid_.is_valid(), std::logic_error, "Invalid solid in replicated model '" << get_name() << "' !"); - grab_logical().set_name(i_model::make_logical_volume_name(name_)); + grab_logical().set_name(i_model::make_logical_volume_name(get_name())); grab_logical().set_shape(_solid_); grab_logical().set_material_ref(material_name); diff --git a/source/bxgeomtools/src/right_circular_conical_frustrum.cc b/source/bxgeomtools/src/right_circular_conical_frustrum.cc index a7d52ae55..99fa232f4 100644 --- a/source/bxgeomtools/src/right_circular_conical_frustrum.cc +++ b/source/bxgeomtools/src/right_circular_conical_frustrum.cc @@ -1312,5 +1312,157 @@ namespace geomtools { } return; } + + void right_circular_conical_frustrum::compute_deflated(right_circular_conical_frustrum & deflated_, + double by_r_, + double by_z_, + double by_angle_) + { + DT_THROW_IF(! is_valid(), std::logic_error, "Invalid right circular conical frustrum!"); + double r_eps = 0.0; + double z_eps = 0.0; + if (datatools::is_valid(by_r_) and by_r_ > 0.0) r_eps = by_r_; + if (datatools::is_valid(by_z_) and by_z_ > 0.0) z_eps = by_z_; + double z = get_z(); + double rib = get_inner_bottom_radius(); + double rit = get_inner_top_radius(); + double rob = get_outer_bottom_radius(); + double rot = get_outer_top_radius(); + z -= (2 * z_eps); + rib += r_eps; + rit += r_eps; + rob -= r_eps; + rot -= r_eps; + deflated_.reset(); + if (has_inner_bottom_radius()) { + deflated_.set_inner_bottom_radius(rib); + } + if (has_inner_top_radius()) { + deflated_.set_inner_top_radius(rit); + } + deflated_.set_outer_bottom_radius(rob); + deflated_.set_outer_top_radius(rot); + deflated_.set_z(z); + double eps_angle = by_angle_; + if (eps_angle < 0.0) { + double delta_angle_bot = r_eps / rob; + double delta_angle_top = r_eps / rot; + eps_angle = std::max(delta_angle_bot, delta_angle_top); + } + if (has_partial_angle()) { + double start_angle = get_start_angle(); + double delta_angle = get_delta_angle(); + if (eps_angle > 0.0) { + start_angle -= eps_angle; + delta_angle += 2 * eps_angle; + } + if (delta_angle < 0.0) { + start_angle = get_start_angle() + 0.5 * get_delta_angle() - 0.25 * eps_angle; + delta_angle = 0.5 * eps_angle; + } + deflated_.set_start_angle(start_angle); + deflated_.set_delta_angle(delta_angle); + } + deflated_.lock(); + return; + } + + void right_circular_conical_frustrum::compute_inflated(right_circular_conical_frustrum & inflated_, + double by_r_, + double by_z_, + double by_angle_) + { + DT_THROW_IF(! is_valid(), std::logic_error, "Invalid right circular conical frustrum!"); + double r_eps = 0.0; + double z_eps = 0.0; + if (datatools::is_valid(by_r_) and by_r_ > 0.0) r_eps = by_r_; + if (datatools::is_valid(by_z_) and by_z_ > 0.0) z_eps = by_z_; + double z = get_z(); + double rib = get_inner_bottom_radius(); + double rit = get_inner_top_radius(); + double rob = get_outer_bottom_radius(); + double rot = get_outer_top_radius(); + z += (2 * z_eps); + rib -= r_eps; + rit -= r_eps; + rob += r_eps; + rot += r_eps; + inflated_.reset(); + if (has_inner_bottom_radius()) { + inflated_.set_inner_bottom_radius(rib); + } + if (has_inner_top_radius()) { + inflated_.set_inner_top_radius(rit); + } + inflated_.set_outer_bottom_radius(rob); + inflated_.set_outer_top_radius(rot); + inflated_.set_z(z); + double eps_angle = by_angle_; + if (eps_angle < 0.0) { + double delta_angle_bot = r_eps / rob; + double delta_angle_top = r_eps / rot; + eps_angle = std::max(delta_angle_bot, delta_angle_top); + } + if (has_partial_angle()) { + double start_angle = get_start_angle(); + double delta_angle = get_delta_angle(); + if (eps_angle > 0.0) { + start_angle -= eps_angle; + delta_angle += 2 * eps_angle; + } + if (delta_angle < 2 * M_PI) { + inflated_.set_start_angle(start_angle); + inflated_.set_delta_angle(delta_angle); + } + } + inflated_.lock(); + return; + } + + void right_circular_conical_frustrum::compute_envelope(right_circular_conical_frustrum & envelope_, + double r_tolerance_, + double z_tolerance_, + double angle_tolerance_) + { + compute_inflated(envelope_, r_tolerance_, z_tolerance_, angle_tolerance_); + /* + DT_THROW_IF(! is_valid(), std::logic_error, "Invalid right circular conical frustrum!"); + double r_eps = 0.0; + double z_eps = 0.0; + if (datatools::is_valid(by_r_) and by_r_ > 0.0) r_eps = by_r_; + if (datatools::is_valid(by_z_) and by_z_ > 0.0) z_eps = by_z_; + double z = get_z(); + double rob = get_outer_bottom_radius(); + double rot = get_outer_top_radius(); + z += (2 * z_eps); + rib -= r_eps; + rit -= r_eps; + rob += r_eps; + rot += r_eps; + envelope_.reset(); + envelope_.set_outer_bottom_radius(rob); + envelope_.set_outer_top_radius(rot); + envelope_.set_z(z); + double eps_angle = angle_tolerance_; + if (eps_angle_ < 0.0) { + double dangleb = r_eps / rob; + double danglet = r_eps / rot; + doubel eps_angle = std::max(dangleb, danglet); + eps_angle = r_eps / r; + } + if (eps_angle > 0.0 and has_partial_angle()) { + double start_angle = get_start_angle(); + double delta_angle = get_delta_angle(); + start_angle -= eps_angle; + delta_angle += 2 * eps_angle; + if (delta_angle < 2 * M_PI) { + envelope_.set_start_angle(start_angle); + envelope_.set_delta_angle(delta_angle); + } + } + envelope_.lock(); + */ + return; + } } // end of namespace geomtools diff --git a/source/bxgeomtools/src/right_circular_conical_nappe.cc b/source/bxgeomtools/src/right_circular_conical_nappe.cc index fe252a7fc..262095a21 100644 --- a/source/bxgeomtools/src/right_circular_conical_nappe.cc +++ b/source/bxgeomtools/src/right_circular_conical_nappe.cc @@ -502,6 +502,14 @@ namespace geomtools { // std::cerr << "DEVEL: right_circular_conical_nappe::generate_wires_self: " // << "z = " << z // << std::endl; + if (base_options & WR_BASE_BEST_GRID_SAMPLING) { + // double rmax = std::max(rt, rb); + double zstep = 0.5 * (rt+rb); + int guessed_nsamples_z = (int) (z / zstep); + if (guessed_nsamples_z < 2) guessed_nsamples_z = 2; + // Relative sampling density could be addressed here using sampling_level_type ratio computed from the WR_BASE_GRID_XXX_DENSITY option + nsamples_z = guessed_nsamples_z; + } double dz = z / (nsamples_z - 1); // std::cerr << "DEVEL: right_circular_conical_nappe::generate_wires_self: " // << "dz = " << dz diff --git a/source/bxgeomtools/src/rotated_boxed_model.cc b/source/bxgeomtools/src/rotated_boxed_model.cc index 8aeae2190..6162e4e6d 100644 --- a/source/bxgeomtools/src/rotated_boxed_model.cc +++ b/source/bxgeomtools/src/rotated_boxed_model.cc @@ -53,16 +53,14 @@ namespace geomtools { return; } - void rotated_boxed_model::_at_construct (const std::string & name_, - const datatools::properties & config_, + void rotated_boxed_model::_at_construct (const datatools::properties & config_, models_col_type * models_) { DT_LOG_TRACE (get_logging_priority (), "Entering..."); - //set_name (name_); DT_THROW_IF (! config_.has_key ("material.ref"), std::logic_error, - "Missing 'material.ref' property in rotated boxed model '" << name_ << "' !"); + "Missing 'material.ref' property in rotated boxed model '" << get_name() << "' !"); const std::string material_name = config_.fetch_string ("material.ref"); /*** length unit ***/ @@ -87,7 +85,7 @@ namespace geomtools { // fetch the rotation axis: DT_THROW_IF (! config_.has_key ("rotated.axis"), std::logic_error, - "Missing 'rotated.axis' property for model '" << name_ << "' !"); + "Missing 'rotated.axis' property for model '" << get_name() << "' !"); const std::string rotation_axis_label = config_.fetch_string ("rotated.axis"); bool use_special_angle = false; @@ -104,20 +102,19 @@ namespace geomtools { } use_special_angle = false; } else { - DT_THROW_IF (true, - std::logic_error, - "Missing 'rotated.special_angle' or 'rotation.angle' property for model '" << name_ << "' !"); + DT_THROW (std::logic_error, + "Missing 'rotated.special_angle' or 'rotation.angle' property for model '" << get_name() << "' !"); } DT_THROW_IF (! config_.has_key ("rotated.model"), std::logic_error, - "Missing 'boxed_model' property for model '" << name_ << "' !"); + "Missing 'boxed_model' property for model '" << get_name() << "' !"); const std::string boxed_model_name = config_.fetch_string ("rotated.model"); const int rotation_axis = get_rotation_axis_from_label (rotation_axis_label); DT_THROW_IF (! check_rotation_axis (rotation_axis), std::logic_error, - "Invalid rotation axis for model '" << name_ << "' !"); + "Invalid rotation axis for model '" << get_name() << "' !"); // XXXX // dimension of the mother box: @@ -132,7 +129,7 @@ namespace geomtools { get_special_rotation_angle_from_label (special_rotation_angle_label); DT_THROW_IF (! check_special_rotation_angle (special_rotation_angle), std::logic_error, - "Invalid rotation angle (" << special_rotation_angle_label << ") for model '" << name_ << "'!"); + "Invalid rotation angle (" << special_rotation_angle_label << ") in model '" << get_name() << "'!"); } else { // arbitrary angles: if (config_.has_key ("x")) { x = config_.fetch_real ("x"); @@ -142,7 +139,7 @@ namespace geomtools { } else { DT_THROW_IF ((rotation_axis == ROTATION_AXIS_Y) || (rotation_axis == ROTATION_AXIS_Z), std::logic_error, - "Missing 'x' property !"); + "Missing 'x' property in model '" << get_name() << "'!"); } if (config_.has_key ("y")) { @@ -153,7 +150,7 @@ namespace geomtools { } else { DT_THROW_IF ((rotation_axis == ROTATION_AXIS_X) || (rotation_axis == ROTATION_AXIS_Z), std::logic_error, - "Missing 'y' property !"); + "Missing 'y' property in model '" << get_name() << "' !"); } if (config_.has_key ("z")) { @@ -164,23 +161,23 @@ namespace geomtools { } else { DT_THROW_IF ((rotation_axis == ROTATION_AXIS_X) || (rotation_axis == ROTATION_AXIS_Y), std::logic_error, - "Missing 'z' property !"); + "Missing 'z' property in model '" << get_name() << "'!"); } } - DT_THROW_IF (! models_, std::logic_error, "Missing logicals dictionary !"); + DT_THROW_IF (! models_, std::logic_error, "Missing dictionary of models!"); // Boxed model: { models_col_type::const_iterator found = models_->find (boxed_model_name); - i_model * the_model = 0; + i_model * the_model = nullptr; DT_THROW_IF (found == models_->end (), std::logic_error, - "The rotating model '" << the_model->get_name () << "' is not stackable !"); + "The rotating model '" << the_model->get_name() << "' is not stackable in model '" << get_name() << "'!"); the_model = found->second; // check if the model is stackable: DT_THROW_IF (! i_shape_3d::check_stackability(the_model->get_logical().get_shape(), stackable::STACKABILITY_STRONG), std::logic_error, - "The rotating model '" << the_model->get_name () << "' is not stackable on X/Y/Z axis!"); + "The rotating model '" << the_model->get_name() << "' is not stackable on X/Y/Z axis in model '" << get_name() << "'!"); set_boxed_model (*the_model); } @@ -298,9 +295,9 @@ namespace geomtools { _solid_.set_z(z); _solid_.lock(); - DT_THROW_IF (! _solid_.is_valid (), std::logic_error, "Invalid solid !"); + DT_THROW_IF (! _solid_.is_valid (), std::logic_error, "Invalid solid in model '" << get_name() << "'!"); - grab_logical().set_name (i_model::make_logical_volume_name (name_)); + grab_logical().set_name (i_model::make_logical_volume_name (get_name())); grab_logical().set_shape (_solid_); grab_logical().set_material_ref (material_name); // >>> Special treatment: diff --git a/source/bxgeomtools/src/simple_boxed_model.cc b/source/bxgeomtools/src/simple_boxed_model.cc index ac44cf018..995b31f56 100644 --- a/source/bxgeomtools/src/simple_boxed_model.cc +++ b/source/bxgeomtools/src/simple_boxed_model.cc @@ -93,12 +93,9 @@ namespace geomtools { return; } - void simple_boxed_model::_at_construct (const std::string & name_, - const datatools::properties & config_, + void simple_boxed_model::_at_construct (const datatools::properties & config_, models_col_type * /*models_*/) { - //set_name (name_); - double lunit = CLHEP::mm; if (config_.has_key ("length_unit")) { @@ -106,17 +103,17 @@ namespace geomtools { lunit = datatools::units::get_length_unit_from (lunit_str); } - DT_THROW_IF (! config_.has_key ("x"), std::logic_error, "Missing 'x' property in simple boxed model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("x"), std::logic_error, "Missing 'x' property in simple boxed model '" << get_name() << "' !"); double x = config_.fetch_real ("x"); if (! config_.has_explicit_unit ("x")) { x *= lunit; } - DT_THROW_IF (! config_.has_key ("y"), std::logic_error, "Missing 'y' property in simple boxed model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("y"), std::logic_error, "Missing 'y' property in simple boxed model '" << get_name() << "' !"); double y = config_.fetch_real ("y"); if (! config_.has_explicit_unit ("y")) { y *= lunit; } - DT_THROW_IF (! config_.has_key ("z"), std::logic_error, "Missing 'z' property in simple boxed model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("z"), std::logic_error, "Missing 'z' property in simple boxed model '" << get_name() << "' !"); double z = config_.fetch_real ("z"); if (! config_.has_explicit_unit ("z")) { z *= lunit; @@ -124,7 +121,7 @@ namespace geomtools { DT_THROW_IF (! config_.has_key ("material.ref"), std::logic_error, - "Missing 'material.ref' property in simple boxed model '" << name_ << "' !"); + "Missing 'material.ref' property in simple boxed model '" << get_name() << "' !"); const std::string material_name = config_.fetch_string ("material.ref"); set_material_name (material_name); @@ -137,9 +134,9 @@ namespace geomtools { _solid_.set_y(get_y ()); _solid_.set_z(get_z ()); _solid_.lock(); - DT_THROW_IF (! _solid_.is_valid (), std::logic_error, "Invalid box dimensions in simple boxed model '" << name_ << "' !"); + DT_THROW_IF (! _solid_.is_valid (), std::logic_error, "Invalid box dimensions in simple boxed model '" << get_name() << "' !"); - grab_logical ().set_name (i_model::make_logical_volume_name (name_)); + grab_logical ().set_name (i_model::make_logical_volume_name (get_name())); grab_logical ().set_shape (_solid_); grab_logical ().set_material_ref (material_name); diff --git a/source/bxgeomtools/src/simple_shaped_model.cc b/source/bxgeomtools/src/simple_shaped_model.cc index 9e79652f6..9420b755e 100644 --- a/source/bxgeomtools/src/simple_shaped_model.cc +++ b/source/bxgeomtools/src/simple_shaped_model.cc @@ -1,4 +1,4 @@ -/// \file geomtools/simple_shaped_model.cc +// \file geomtools/simple_shaped_model.cc // Ourselves: #include @@ -57,6 +57,18 @@ namespace geomtools { return _internals_; } + const simple_shaped_model::envelope_tolerance_type & + simple_shaped_model::get_envelope_tolerance() const + { + return _envelope_tolerance_; + } + + simple_shaped_model::envelope_tolerance_type & + simple_shaped_model::grab_envelope_tolerance() + { + return _envelope_tolerance_; + } + const MWIM & simple_shaped_model::get_internals () const { return _internals_; @@ -120,15 +132,6 @@ namespace geomtools { simple_shaped_model::simple_shaped_model () : i_model () { _sbm_ = SBM_INVALID; - _box_ = 0; - _cylinder_ = 0; - _tube_ = 0; - _sphere_ = 0; - _polycone_ = 0; - _polyhedra_ = 0; - _solid_ = 0; - _inner_shape_ = 0; - _outer_shape_ = 0; _shape_type_id_ = ""; // no defined shape _material_name_ = ""; // material::material_ref_unknown(); _filled_mode_ = filled_utils::FILLED_NONE; @@ -139,39 +142,32 @@ namespace geomtools { simple_shaped_model::~simple_shaped_model () { if (_sbm_ == SBM_LEGACY) { - if (_inner_shape_ != 0) delete _inner_shape_; - if (_outer_shape_ != 0) delete _outer_shape_; - if (_box_ != 0) delete _box_; - if (_cylinder_ != 0) delete _cylinder_; - if (_tube_ != 0) delete _tube_; - if (_sphere_ != 0) delete _sphere_; - if (_polycone_ != 0) delete _polycone_; - if (_polyhedra_ != 0) delete _polyhedra_; + if (_inner_shape_) _inner_shape_.reset(); + if (_outer_shape_) _outer_shape_.reset(); + if (_box_) _box_.reset(); + if (_cylinder_) _cylinder_.reset(); + if (_tube_) _tube_.reset(); + if (_sphere_) _sphere_.reset(); + if (_polycone_) _polycone_.reset(); + if (_polyhedra_) _polyhedra_.reset(); } - _box_ = 0; - _cylinder_ = 0; - _tube_ = 0; - _sphere_ = 0; - _polycone_ = 0; - _polyhedra_ = 0; - _inner_shape_ = 0; - _outer_shape_ = 0; - _solid_ = 0; + if (_solid_) _solid_.reset(); return; } - void simple_shaped_model::_at_construct (const std::string & name_, - const datatools::properties & config_, + void simple_shaped_model::_at_construct (const datatools::properties & config_, models_col_type * models_) { - DT_LOG_TRACE (get_logging_priority (), "Entering..."); + datatools::logger::priority logging = get_logging_priority(); + logging = datatools::logger::PRIO_DEBUG; + DT_LOG_TRACE(logging, "Entering..."); // Initialization: _filled_material_name_ = material::material_ref_unknown(); // Main shape material: DT_THROW_IF (! config_.has_key ("material.ref"), std::logic_error, - "Missing 'material.ref' property in simple shaped model '" << name_ << "' !"); + "Missing 'material.ref' property in simple shaped model '" << get_name() << "' !"); _material_name_ = config_.fetch_string ("material.ref"); if (config_.has_key("shape_build_mode")) { @@ -182,7 +178,7 @@ namespace geomtools { _sbm_ = SBM_FACTORY; } else { DT_THROW(std::logic_error, - "Invalid label for shape build mode ('" << sbm_label << "') property in simple shaped model '" << name_ << "' !"); + "Invalid label for shape build mode ('" << sbm_label << "') property in simple shaped model '" << get_name() << "' !"); } } if (_sbm_ == SBM_INVALID) { @@ -191,7 +187,7 @@ namespace geomtools { } // Set the logical name: - grab_logical().set_name(i_model::make_logical_volume_name(name_)); + grab_logical().set_name(i_model::make_logical_volume_name(get_name())); // Parsing shape: @@ -231,22 +227,22 @@ namespace geomtools { std::string shape_ref = config_.fetch_string("shape_ref"); DT_THROW_IF(!get_shape_factory().has(shape_ref), std::logic_error, "Shape factory does not contains a solid named '" << shape_ref - << "' for model '" << name_ << "'!"); - _solid_ = dynamic_cast(const_cast(&get_shape_factory().get(shape_ref))); + << "' for model '" << get_name() << "'!"); + _solid_.reset(dynamic_cast(const_cast(&get_shape_factory().get(shape_ref)))); } else { DT_THROW_IF (! config_.has_key ("shape_type"), std::logic_error, - "Missing 'shape_type' property in simple shaped model '" << name_ << "' !"); + "Missing 'shape_type' property in simple shaped model '" << get_name() << "' !"); _shape_type_id_ = config_.fetch_string("shape_type"); datatools::properties shape_config; config_.export_and_rename_starting_with(shape_config, "shape.", ""); std::ostringstream solid_name_oss; - solid_name_oss << name_ << i_model::solid_suffix(); + solid_name_oss << get_name() << i_model::solid_suffix(); i_object_3d & obj3d = grab_shape_factory().create(solid_name_oss.str(), _shape_type_id_, shape_config); // obj3d.set_name(solid_name_oss.str()); DT_THROW_IF(obj3d.get_dimensional() != i_object_3d::DIMENSIONAL_3, std::logic_error, "Object provided by the shape factory (type='" << _shape_type_id_ << "') is not a 3D-shape!"); - _solid_ = dynamic_cast(&obj3d); + _solid_.reset(dynamic_cast(&obj3d)); } // 2015-06-12, FM: Add missing material name in the logical @@ -255,7 +251,7 @@ namespace geomtools { } else { // Legacy solid: DT_THROW_IF(! config_.has_key("shape_type"), std::logic_error, - "Missing 'shape_type' property in simple shaped model '" << name_ << "' !"); + "Missing 'shape_type' property in simple shaped model '" << get_name() << "' !"); _shape_type_id_ = config_.fetch_string("shape_type"); // Shape fill mode: @@ -265,7 +261,7 @@ namespace geomtools { _filled_mode_ = filled_utils::get_filled_mode(filled_mode_label); DT_THROW_IF(_filled_mode_ == filled_utils::FILLED_UNDEFINED, std::logic_error, - "Invalid filled mode '" << filled_mode_label << "' property in simple shaped (tube) model '" << name_ << "' !"); + "Invalid filled mode '" << filled_mode_label << "' property in simple shaped (tube) model '" << get_name() << "' !"); // if (is_filled()) { // DT_LOG_WARNING(get_logging_priority (), // "Filled mode '" << filled_utils::get_filled_mode_label(_filled_mode_) @@ -274,14 +270,71 @@ namespace geomtools { } // Label of the shape in 'filled envelope' mode: - if (is_filled_by_envelope()){ + if (is_filled_by_envelope()) { + DT_LOG_DEBUG(logging, "-> filled_by_envelope"); + + if (config_.has_flag("envelope.deflated")) { + _envelope_tolerance_.deflated_shape = true; + DT_LOG_DEBUG(logging, "Envelope -> deflated"); + } + + if (config_.has_key("envelope.tolerance.r")) { + double r_eps = config_.fetch_real_with_explicit_dimension("envelope.tolerance.r", + "length"); + DT_THROW_IF(r_eps <= 0.0, std::domain_error, + "Invalid envelope radial tolerance!") + _envelope_tolerance_.r_tolerance = r_eps; + DT_LOG_DEBUG(logging, "Envelope -> tolerance.r=" << _envelope_tolerance_.r_tolerance); + } + + if (config_.has_key("envelope.tolerance.x")) { + double x_eps = config_.fetch_real_with_explicit_dimension("envelope.tolerance.x", + "length"); + DT_THROW_IF(x_eps <= 0.0, std::domain_error, + "Invalid envelope tolerance on X-axis!") + _envelope_tolerance_.x_tolerance = x_eps; + } + + if (config_.has_key("envelope.tolerance.y")) { + double y_eps = config_.fetch_real_with_explicit_dimension("envelope.tolerance.y", + "length"); + DT_THROW_IF(y_eps <= 0.0, std::domain_error, + "Invalid envelope tolerance on Y-axis!") + _envelope_tolerance_.y_tolerance = y_eps; + } + + if (config_.has_key("envelope.tolerance.theta")) { + double theta_eps = config_.fetch_real_with_explicit_dimension("envelope.tolerance.theta", + "angle"); + DT_THROW_IF(theta_eps <= 0.0, std::domain_error, + "Invalid envelope tolerance on theta angle (colatitude)!") + _envelope_tolerance_.theta_tolerance = theta_eps; + } + + if (config_.has_key("envelope.tolerance.phi")) { + double phi_eps = config_.fetch_real_with_explicit_dimension("envelope.tolerance.phi", + "angle"); + DT_THROW_IF(phi_eps <= 0.0, std::domain_error, + "Invalid envelope tolerance on phi angle (longitude)!") + _envelope_tolerance_.phi_tolerance = phi_eps; + } + + if (config_.has_key("envelope.tolerance.z")) { + double z_eps = config_.fetch_real_with_explicit_dimension("envelope.tolerance.z", + "length"); + DT_THROW_IF(z_eps <= 0.0, std::domain_error, + "Invalid envelope tolerance on Z-axis!") + _envelope_tolerance_.z_tolerance = z_eps; + DT_LOG_DEBUG(logging, "Envelope -> tolerance.z=" << _envelope_tolerance_.z_tolerance); + } + _filled_label_ = _shape_type_id_ + "_by_envelope"; if (config_.has_key("filled_label")) { _filled_label_ = config_.fetch_string("filled_label"); } DT_THROW_IF(_filled_label_.empty(), std::logic_error, - "Invalid filled label '" << _filled_label_ << "' property in simple shaped (tube) model '" << name_ << "' !"); + "Invalid filled label '" << _filled_label_ << "' property in simple shaped (tube) model '" << get_name() << "' !"); DT_LOG_DEBUG(get_logging_priority(), "Filled label is '" << _filled_label_ << "'!"); } @@ -290,30 +343,30 @@ namespace geomtools { // Parsing material: DT_THROW_IF (! config_.has_key ("material.filled.ref"), std::logic_error, - "Missing 'material.filled.ref' property in simple shaped (tube) model '" << name_ << "' !"); + "Missing 'material.filled.ref' property in simple shaped (tube) model '" << get_name() << "' !"); _filled_material_name_ = config_.fetch_string ("material.filled.ref"); } if (get_shape_type_id () == "box") { // Box case: - _construct_box (name_, config_, models_); + _construct_box (config_, models_); } else if (get_shape_type_id () == "cylinder") { // Cylinder case: - _construct_cylinder (name_, config_, models_); + _construct_cylinder (config_, models_); } else if (get_shape_type_id () == "sphere") { // Sphere case: - _construct_sphere (name_, config_, models_); + _construct_sphere (config_, models_); } else if (get_shape_type_id () == "tube") { // Tube case: - _construct_tube (name_, config_, models_); + _construct_tube (config_, models_); } else if (get_shape_type_id () == "polycone") { // Polycone case: - _construct_polycone (name_, config_, models_); + _construct_polycone (config_, models_); } else if (get_shape_type_id () == "polyhedra") { // Polyhedra case: - _construct_polyhedra (name_, config_, models_); + _construct_polyhedra (config_, models_); } else { - DT_THROW_IF (true, std::logic_error, "Shape '" << get_shape_type_id () << "' is not supported in simple shaped model '" << name_ << "' !"); + DT_THROW_IF (true, std::logic_error, "Shape '" << get_shape_type_id () << "' is not supported in simple shaped model '" << get_name() << "' !"); } } @@ -328,13 +381,12 @@ namespace geomtools { return; } - void simple_shaped_model::_construct_box (const std::string & name_, - const datatools::properties & config_, + void simple_shaped_model::_construct_box (const datatools::properties & config_, models_col_type * /*models_*/) { - DT_LOG_DEBUG(get_logging_priority(), "Construct box named '" << name_ << "'"); + DT_LOG_DEBUG(get_logging_priority(), "Construct box named '" << get_name() << "'"); // Build the box: - _box_ = new box; + _box_.reset(new box); try { DT_LOG_DEBUG(get_logging_priority(), "Initialize box from config: "); if (get_logging_priority() >= datatools::logger::PRIO_DEBUG) { @@ -347,76 +399,72 @@ namespace geomtools { } } catch (std::exception & error) { DT_LOG_ERROR(datatools::logger::PRIO_ERROR, error.what()); - delete _box_; + _box_.reset(); throw error; } DT_THROW_IF (! _box_->is_valid(), std::logic_error, - "Invalid box parameters in simple shaped (box) model '" << name_ << "' !"); + "Invalid box parameters in simple shaped (box) model '" << get_name() << "' !"); DT_LOG_DEBUG(get_logging_priority(), "Box validity: " << _box_->is_valid()); _solid_ = _box_; grab_logical().set_material_ref(_material_name_); return; } - void simple_shaped_model::_construct_cylinder (const std::string & name_, - const datatools::properties & config_, + void simple_shaped_model::_construct_cylinder (const datatools::properties & config_, models_col_type * /*models_*/) { // Build the cylinder: - _cylinder_ = new cylinder; + _cylinder_.reset(new cylinder); try { _cylinder_->initialize(config_); } catch (std::exception & error) { DT_LOG_ERROR(datatools::logger::PRIO_ERROR, error.what()); - delete _cylinder_; + _cylinder_.reset(); throw error; } DT_THROW_IF (! _cylinder_->is_valid(), std::logic_error, - "Invalid cylinder dimensions in simple shaped (cylinder) model '" << name_ << "'"); + "Invalid cylinder dimensions in simple shaped (cylinder) model '" << get_name() << "'"); _solid_ = _cylinder_; grab_logical().set_material_ref(_material_name_); return; } - void simple_shaped_model::_construct_sphere (const std::string & name_, - const datatools::properties & config_, + void simple_shaped_model::_construct_sphere (const datatools::properties & config_, models_col_type* /*models_*/) { // Build the sphere: - _sphere_ = new sphere; + _sphere_.reset(new sphere); try { _sphere_->initialize(config_); } catch (std::exception & error) { DT_LOG_ERROR(datatools::logger::PRIO_ERROR, error.what()); - delete _sphere_; + _sphere_.reset(); throw error; } DT_THROW_IF (! _sphere_->is_valid(), std::logic_error, - "Invalid sphere parameters in simple shaped (sphere) model '" << name_ << "' !"); + "Invalid sphere parameters in simple shaped (sphere) model '" << get_name() << "' !"); _solid_ = _sphere_; grab_logical().set_material_ref(_material_name_); return; } - void simple_shaped_model::_construct_tube (const std::string & name_, - const datatools::properties & config_, - models_col_type* /*models_*/) + void simple_shaped_model::_construct_tube (const datatools::properties & config_, + models_col_type* models_) { // Build the tube: - _tube_ = new tube; + _tube_.reset(new tube); try { _tube_->initialize(config_); - // _tube_->tree_dump(std::cerr, "simple_shaped_model -- Initialized tube: ", "DEVEL: "); } catch (std::exception & error) { DT_LOG_ERROR(datatools::logger::PRIO_ERROR, error.what()); - delete _tube_; + _tube_.reset(); throw error; } DT_THROW_IF (! _tube_->is_valid(), std::logic_error, - "Invalid tube dimensions in simple shaped (tube) model '" << name_ << "' !"); + "Invalid tube dimensions in simple shaped (tube) model '" << get_name() << "' !"); // Use the plain tube as solid envelope of the model: if (_filled_mode_ == filled_utils::FILLED_NONE) { @@ -426,7 +474,7 @@ namespace geomtools { DT_THROW_IF(_filled_mode_ == filled_utils::FILLED_BY_EXTRUSION, std::logic_error, - "No support for tube construction 'by extrusion' in simple shaped (tube) model '" << name_ << "' !"); + "No support for tube construction 'by extrusion' in simple shaped (tube) model '" << get_name() << "' !"); /* * _____________________ @@ -441,7 +489,7 @@ namespace geomtools { // Make the envelope a cylinder: _cylinder_ = new cylinder; _tube_->compute_outer_cylinder (*_cylinder_); - DT_THROW_IF (! _cylinder_->is_valid (), std::logic_error, "Invalid 'outer' cylinder dimensions in simple shaped (tube) model '" << name_ << "' !"); + DT_THROW_IF (! _cylinder_->is_valid (), std::logic_error, "Invalid 'outer' cylinder dimensions in simple shaped (tube) model '" << get_name() << "' !"); _solid_ = _cylinder_; grab_logical ().set_material_ref (_material_name_); grab_logical ().set_effective_shape (*_tube_); @@ -455,7 +503,7 @@ namespace geomtools { if (! inner_cyl->is_valid ()) { delete inner_cyl; DT_THROW_IF (true, std::logic_error, - "Invalid 'inner' cylinder dimensions in simple shaped (tube) model '" << name_ << "' !"); + "Invalid 'inner' cylinder dimensions in simple shaped (tube) model '" << get_name() << "' !"); } _inner_shape_ = inner_cyl; // Inner placement for the extrusion: @@ -477,48 +525,67 @@ namespace geomtools { // Build the tube as a child of a mother cylinder: if (_filled_mode_ == filled_utils::FILLED_BY_ENVELOPE) { // std::cerr << "DEVEL: geomtools::simple_shaped_model::_construct_tube: FILLED_BY_ENVELOPE" << std::endl; + double r_eps = 0.0; + if (_envelope_tolerance_.has_r_tolerance()) { + r_eps = _envelope_tolerance_.r_tolerance; + } + double z_eps = 0.0; + if (_envelope_tolerance_.has_z_tolerance()) { + z_eps = _envelope_tolerance_.z_tolerance; + } + double in_r = datatools::invalid_real(); + double out_r = _tube_->get_outer_r(); + double z = _tube_->get_z(); // Make the envelope a cylinder: - _cylinder_ = new cylinder; - _tube_->compute_outer_cylinder(*_cylinder_); - DT_THROW_IF (! _cylinder_->is_valid(), std::logic_error, - "Invalid 'outer' cylinder dimensions in simple shaped (tube) model '" << name_ << "' !"); + _cylinder_.reset(new cylinder); + if (_envelope_tolerance_.deflated_shape) { + std::shared_ptr deflated_tube; + if (_tube_->has_inner_r()) { + in_r = _tube_->get_inner_r(); + deflated_tube.reset(new tube(in_r, out_r - r_eps, z - 2 * z_eps)); + } else { + deflated_tube.reset(new tube(out_r - r_eps, z - 2 * z_eps)); + } + _tube_->compute_outer_cylinder(*_cylinder_); + // Replace the original tube by the deflated one: + _tube_ = deflated_tube; + } else { + // Build the inflated cylinder envelope: + _tube_->compute_envelope(*_cylinder_, r_eps, z_eps); + DT_THROW_IF (! _cylinder_->is_valid(), std::logic_error, + "Invalid 'outer' cylinder dimensions in simple shaped (tube) model '" << get_name() << "' !"); + } _solid_ = _cylinder_; grab_logical().set_material_ref(_filled_material_name_); - //grab_logical().set_effective_shape(*_tube_); - //grab_logical().set_effective_material_ref(_material_name_); // If the tube is extruded, add the tube within the 'outer' envelope cylinder: - _inner_placement_.set(0, 0, 0, 0, 0, 0); - //const std::string inner_name = "__" + get_logical ().get_name () + "." + _filled_label_; - const std::string inner_name = "__" + get_name() + "." + _filled_label_; - _inner_logical_.set_name(i_model::make_logical_volume_name(inner_name)); - _inner_logical_.set_material_ref(_material_name_); - _inner_logical_.set_shape(*_tube_); - _inner_logical_.set_geometry_model(*this); + _inner_placement_.set(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); + std::string model_basename = extract_basename_from_model_name(get_name()); + const std::string inner_name = "__" + model_basename + "." + _filled_label_; + _inner_model_.set_solid(*_tube_); + _inner_model_.set_material_name(_material_name_); + _inner_model_.construct(inner_name, models_); _inner_phys_.set_name(i_model::make_physical_volume_name(_filled_label_)); _inner_phys_.set_placement(_inner_placement_); - _inner_phys_.set_logical(_inner_logical_); + _inner_phys_.set_logical(_inner_model_.get_logical()); _inner_phys_.set_mother(this->get_logical()); } - - // _tube_->tree_dump(std::cerr, "simple_shaped_model -- Constructed tube: ", "DEVEL: "); return; } - void simple_shaped_model::_construct_polycone (const std::string & name_, - const datatools::properties & config_, - models_col_type* /*models_*/) + void simple_shaped_model::_construct_polycone (const datatools::properties & config_, + models_col_type * models_) { // Build the polycone: - _polycone_ = new polycone; + _polycone_.reset(new polycone); try { _polycone_->initialize(config_); } catch (std::exception & error) { DT_LOG_ERROR(datatools::logger::PRIO_ERROR, error.what()); - delete _polycone_; + _polycone_.reset(); throw error; } DT_THROW_IF (! _polycone_->is_valid (), std::logic_error, - "Invalid polycone build parameters in simple shaped (polycone) model '" << name_ << "' !"); + "Invalid polycone build parameters in simple shaped (polycone) model '" << get_name() << "' !"); DT_LOG_TRACE (get_logging_priority (), "Polycone:"); if (get_logging_priority () >= datatools::logger::PRIO_TRACE) { @@ -533,7 +600,7 @@ namespace geomtools { /* DT_THROW_IF(_filled_mode_ == filled_utils::FILLED_BY_EXTRUSION, std::runtime_error, - "No support for polycone construction 'by extrusion' in simple shaped (polycone) model '" << name_ << "' !"); + "No support for polycone construction 'by extrusion' in simple shaped (polycone) model '" << get_name() << "' !"); // Build the polycone model by extrusion of a mother polycone: if (_filled_mode_ == filled_utils::FILLED_BY_EXTRUSION) { @@ -541,7 +608,7 @@ namespace geomtools { polycone * envelope_polycone = new polycone; _polycone_->compute_outer_polycone (*envelope_polycone); DT_THROW_IF (! envelope_polycone->is_valid (), std::logic_error, - "Invalid envelope polycone in simple shaped (polycone) model '" << name_ << "' !"); + "Invalid envelope polycone in simple shaped (polycone) model '" << get_name() << "' !"); _outer_shape_ = envelope_polycone; _solid_ = _outer_shape_; grab_logical ().set_material_ref (_material_name_); @@ -556,7 +623,7 @@ namespace geomtools { if (! inner_pol->is_valid ()) { delete inner_pol; DT_THROW_IF (true, std::logic_error, - "Invalid 'inner' polycone dimensions in simple shaped (polycone) model '" << name_ << "' !"); + "Invalid 'inner' polycone dimensions in simple shaped (polycone) model '" << get_name() << "' !"); } _inner_shape_ = inner_pol; // Inner placement for the extrusion: @@ -577,26 +644,47 @@ namespace geomtools { // Build the polycone as a filled child of a mother filled polycone: if (_filled_mode_ == filled_utils::FILLED_BY_ENVELOPE) { - // Make the envelope a cylinder: - polycone * outer_polycone = new polycone; - _polycone_->compute_outer_polycone (*outer_polycone); - DT_THROW_IF (! outer_polycone->is_valid (), std::logic_error, "Invalid 'outer' cylinder dimensions in simple shaped (polycone) model '" << name_ << "' !"); - _outer_shape_ = outer_polycone; + double r_eps = 0.0; + if (_envelope_tolerance_.has_r_tolerance()) { + r_eps = _envelope_tolerance_.r_tolerance; + } + double z_eps = 0.0; + if (_envelope_tolerance_.has_z_tolerance()) { + z_eps = _envelope_tolerance_.z_tolerance; + } + double theta_eps = 0.0; + if (_envelope_tolerance_.has_theta_tolerance()) { + theta_eps = _envelope_tolerance_.theta_tolerance; + } + + // Make the envelope a polycone: + polycone outer_polycone; + _polycone_->compute_outer_polycone(outer_polycone); + std::shared_ptr envelope_polycone(new polycone); + if ((r_eps or z_eps) and _envelope_tolerance_.deflated_shape) { + outer_polycone.compute_envelope(*envelope_polycone, 0.0, 0.0, 0.0); + std::shared_ptr deflated_polycone(new polycone); + _polycone_->compute_deflated(*deflated_polycone, r_eps, z_eps, theta_eps); + // Replace the original polycone by the deflated one: + _polycone_ = deflated_polycone; + } else { + outer_polycone.compute_envelope(*envelope_polycone, r_eps, z_eps, theta_eps); + } + _outer_shape_ = envelope_polycone; _solid_ = _outer_shape_; grab_logical ().set_material_ref (_filled_material_name_); - //grab_logical ().set_effective_shape (*_polycone_); - //grab_logical ().set_effective_material_ref (_material_name_); // If the polycone is extruded, add the 'inner' polycone // within the 'outer' envelope polycone: - _inner_placement_.set (0, 0, 0, 0, 0, 0); - const std::string inner_name = "__" + get_name () + "." + _filled_label_; - _inner_logical_.set_name (i_model::make_logical_volume_name (inner_name)); - _inner_logical_.set_material_ref (_material_name_); - _inner_logical_.set_shape (*_polycone_); - _inner_logical_.set_geometry_model(*this); + _inner_placement_.set(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); + std::string model_basename = extract_basename_from_model_name(get_name()); + const std::string inner_name = "__" + model_basename + "." + _filled_label_; + _inner_model_.set_solid(*_polycone_); + _inner_model_.set_material_name(_material_name_); + _inner_model_.construct(inner_name, models_); + _inner_phys_.set_name (i_model::make_physical_volume_name (_filled_label_)); _inner_phys_.set_placement (_inner_placement_); - _inner_phys_.set_logical (_inner_logical_); + _inner_phys_.set_logical (_inner_model_.get_logical()); _inner_phys_.set_mother (this->get_logical ()); } @@ -604,21 +692,20 @@ namespace geomtools { } - void simple_shaped_model::_construct_polyhedra (const std::string & name_, - const datatools::properties & config_, - models_col_type* /*models_*/) + void simple_shaped_model::_construct_polyhedra (const datatools::properties & config_, + models_col_type* models_) { - _polyhedra_ = new polyhedra; + _polyhedra_.reset(new polyhedra); try { _polyhedra_->initialize(config_); } catch (std::exception & error) { DT_LOG_ERROR(datatools::logger::PRIO_ERROR, error.what()); - delete _polyhedra_; + _polyhedra_.reset(); throw error; } _polyhedra_->initialize (config_); DT_THROW_IF (! _polyhedra_->is_valid (), std::logic_error, - "Invalid polyhedra build parameters in simple shaped (polyhedra) model '" << name_ << "' !"); + "Invalid polyhedra build parameters in simple shaped (polyhedra) model '" << get_name() << "' !"); DT_LOG_TRACE (get_logging_priority (), "Polyhedra:"); if (get_logging_priority () >= datatools::logger::PRIO_TRACE) { @@ -632,7 +719,7 @@ namespace geomtools { DT_THROW_IF(_filled_mode_ == filled_utils::FILLED_BY_EXTRUSION, std::runtime_error, - "No support for polyhedra construction 'by extrusion' in simple shaped (polyhedra) model '" << name_ << "' !"); + "No support for polyhedra construction 'by extrusion' in simple shaped (polyhedra) model '" << get_name() << "' !"); // build the polyhedra by extrusion of a mother polyhedra: /* @@ -640,7 +727,7 @@ namespace geomtools { // make the envelope a polyhedra: polyhedra * envelope_polyhedra = new polyhedra; _polyhedra_->compute_outer_polyhedra (*envelope_polyhedra); - DT_THROW_IF (! envelope_polyhedra->is_valid (), std::logic_error, "Invalid envelope polyhedra in simple shaped (polyhedra) model '" << name_ << "' !"); + DT_THROW_IF (! envelope_polyhedra->is_valid (), std::logic_error, "Invalid envelope polyhedra in simple shaped (polyhedra) model '" << get_name() << "' !"); _outer_shape_ = envelope_polyhedra; _solid_ = _outer_shape_; grab_logical ().set_material_ref (_material_name_); @@ -655,7 +742,7 @@ namespace geomtools { _polyhedra_->compute_inner_polyhedra (*inner_pol); if (! inner_pol->is_valid ()) { delete inner_pol; - DT_THROW_IF (true, std::logic_error, "Invalid 'inner' polyhedra dimensions in simple shaped (polyhedra) model '" << name_ << "' !"); + DT_THROW_IF (true, std::logic_error, "Invalid 'inner' polyhedra dimensions in simple shaped (polyhedra) model '" << get_name() << "' !"); } _inner_shape_ = inner_pol; // inner placement for the extrusion: @@ -676,26 +763,43 @@ namespace geomtools { // build the polyhedra as a filled child of a mother filled polyhedra: if (_filled_mode_ == filled_utils::FILLED_BY_ENVELOPE) { - // make the envelope a cylinder: - polyhedra * outer_polyhedra = new polyhedra; - _polyhedra_->compute_outer_polyhedra (*outer_polyhedra); - DT_THROW_IF (! outer_polyhedra->is_valid (), std::logic_error, "Invalid 'outer' cylinder dimensions in simple shaped (polyhedra) model '" << name_ << "' !"); - _outer_shape_ = outer_polyhedra; + double r_eps = 0.0; + if (_envelope_tolerance_.has_r_tolerance()) { + r_eps = _envelope_tolerance_.r_tolerance; + } + double z_eps = 0.0; + if (_envelope_tolerance_.has_z_tolerance()) { + z_eps = _envelope_tolerance_.z_tolerance; + } + + // Make the envelope a polyhedra: + polyhedra outer_polyhedra; + _polyhedra_->compute_outer_polyhedra(outer_polyhedra); + std::shared_ptr envelope_polyhedra(new polyhedra); + if ((r_eps or z_eps) and _envelope_tolerance_.deflated_shape) { + outer_polyhedra.compute_envelope(*envelope_polyhedra, 0.0, 0.0); + std::shared_ptr deflated_polyhedra(new polyhedra); + _polyhedra_->compute_deflated(*deflated_polyhedra, r_eps, z_eps); + // Replace the original polyhedra by the deflated one: + _polyhedra_ = deflated_polyhedra; + } else { + outer_polyhedra.compute_envelope(*envelope_polyhedra, r_eps, z_eps); + } + _outer_shape_ = envelope_polyhedra; _solid_ = _outer_shape_; grab_logical ().set_material_ref (_filled_material_name_); - //grab_logical ().set_effective_shape (*_polyhedra_); - //grab_logical ().set_effective_material_ref (_material_name_); - // if the polyhedra is extruded, add the polyhedra - // within the 'outer' envelope polyhedra: - _inner_placement_.set (0, 0, 0, 0, 0, 0); - const std::string inner_name = "__" + get_name () + _filled_label_; - _inner_logical_.set_name (i_model::make_logical_volume_name (inner_name)); - _inner_logical_.set_material_ref (_material_name_); - _inner_logical_.set_shape (*_polyhedra_); - _inner_logical_.set_geometry_model(*this); + // If the polycone is extruded, add the 'inner' polycone + // within the 'outer' envelope polycone: + _inner_placement_.set(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); + std::string model_basename = extract_basename_from_model_name(get_name()); + const std::string inner_name = "__" + model_basename + "." + _filled_label_; + _inner_model_.set_solid(*_polyhedra_); + _inner_model_.set_material_name(_material_name_); + _inner_model_.construct(inner_name, models_); + _inner_phys_.set_name (i_model::make_physical_volume_name (_filled_label_)); _inner_phys_.set_placement (_inner_placement_); - _inner_phys_.set_logical (_inner_logical_); + _inner_phys_.set_logical (_inner_model_.get_logical()); _inner_phys_.set_mother (this->get_logical ()); } @@ -754,7 +858,7 @@ namespace geomtools { std::ostringstream log_params_desc; log_params_desc << "Auxiliary properties for shape logical volume in model '" << get_name() << "'"; - _inner_logical_.grab_parameters().set_description(log_params_desc.str()); + _inner_model_.grab_logical().grab_parameters().set_description(log_params_desc.str()); } std::vector exported_prefixes; if (setup_.has_key(i_model::exported_properties_prefixes_key())) { @@ -775,7 +879,7 @@ namespace geomtools { // Only 'top' properties : tmp_params.erase_all_starting_with(filled_topic_prefix); // Inner logical inherits the 'top' properties : - tmp_params.export_starting_with(_inner_logical_.grab_parameters(), topic_prefix); + tmp_params.export_starting_with(_inner_model_.grab_logical().grab_parameters(), topic_prefix); // Top logical inherits the 'filled' properties : grab_logical().grab_parameters().erase_all_starting_with(filled_topic_prefix); grab_logical().grab_parameters().erase_all_starting_with(topic_prefix); @@ -798,13 +902,13 @@ namespace geomtools { << _filled_internals_.get_number_of_items()); DT_LOG_DEBUG (log_level, "Processing internal items in shape..."); - _internals_.plug_internal_models(_inner_logical_.get_parameters(), - _inner_logical_, + _internals_.plug_internal_models(_inner_model_.get_logical().get_parameters(), + _inner_model_.grab_logical(), models_); DT_LOG_DEBUG (log_level, "Number of items in shape : " << _internals_.get_number_of_items()); } - _inner_logical_.lock(); + // _inner_logical_.lock(); } else { DT_LOG_DEBUG (log_level, "Processing internal items (none)..."); // Top logical is the shape : @@ -891,7 +995,7 @@ namespace geomtools { std::ostringstream indent_oss; indent_oss << indent; indent_oss << datatools::i_tree_dumpable::skip_tag; - _inner_logical_.tree_dump(out_, "",indent_oss.str ()); + _inner_model_.get_logical().tree_dump(out_, "",indent_oss.str ()); out_ << indent << datatools::i_tree_dumpable::tag << "Number of internal items within cavity: '" << _filled_internals_.get_number_of_items() << "'" << std::endl; diff --git a/source/bxgeomtools/src/simple_world_model.cc b/source/bxgeomtools/src/simple_world_model.cc index 450bc3d30..7964e4f4e 100644 --- a/source/bxgeomtools/src/simple_world_model.cc +++ b/source/bxgeomtools/src/simple_world_model.cc @@ -2,9 +2,13 @@ /* simple_world_model.cc */ +// Ourselves: #include +// Standard library: #include + +// This project: #include #include @@ -34,12 +38,10 @@ namespace geomtools { return; } - void simple_world_model::_at_construct (const std::string & name_, - const datatools::properties & config_, + void simple_world_model::_at_construct (const datatools::properties & config_, models_col_type * models_) { DT_LOG_TRACE (get_logging_priority (), "Entering..."); - //set_name (name_); double length_unit = CLHEP::mm; if (config_.has_key ("length_unit")) { @@ -109,15 +111,15 @@ namespace geomtools { material = config_.fetch_string ("material.ref"); } - DT_THROW_IF (! config_.has_key ("setup.model"), std::logic_error, "Missing 'setup_model' property in simple world model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("setup.model"), std::logic_error, "Missing 'setup_model' property in simple world model '" << get_name() << "' !"); const std::string setup_model_name = config_.fetch_string ("setup.model"); - DT_THROW_IF (! models_, std::logic_error, "Missing logicals dictionary in simple world model '" << name_ << "' !"); + DT_THROW_IF (! models_, std::logic_error, "Missing logicals dictionary in simple world model '" << get_name() << "' !"); // Setup model: { models_col_type::const_iterator found = models_->find (setup_model_name); - DT_THROW_IF (found == models_->end (), std::logic_error, "Cannot find setup model with name '"<< setup_model_name << "' in simple world model '" << name_ << "' !"); + DT_THROW_IF (found == models_->end (), std::logic_error, "Cannot find setup model with name '"<< setup_model_name << "' in simple world model '" << get_name() << "' !"); //_setup_model_ = (dynamic_cast (found->second)); _setup_model_ = found->second; } @@ -164,7 +166,7 @@ namespace geomtools { DT_THROW_IF (!_solid_.is_valid (), std::logic_error, "Invalid solid !"); - grab_logical ().set_name (i_model::make_logical_volume_name (name_)); + grab_logical ().set_name (i_model::make_logical_volume_name (get_name())); grab_logical ().set_shape (_solid_); grab_logical ().set_material_ref(material); diff --git a/source/bxgeomtools/src/spherical_extrusion_box_model.cc b/source/bxgeomtools/src/spherical_extrusion_box_model.cc index f55403c96..207991d7e 100644 --- a/source/bxgeomtools/src/spherical_extrusion_box_model.cc +++ b/source/bxgeomtools/src/spherical_extrusion_box_model.cc @@ -58,8 +58,7 @@ namespace geomtools { return; } - void spherical_extrusion_box_model::_at_construct (const std::string & name_, - const datatools::properties & config_, + void spherical_extrusion_box_model::_at_construct (const datatools::properties & config_, geomtools::models_col_type * /*models_*/) { DT_LOG_TRACE (get_logging_priority (), "Entering..."); @@ -72,26 +71,26 @@ namespace geomtools { lunit = datatools::units::get_length_unit_from (lunit_str); } - DT_THROW_IF (! config_.has_key ("material.ref"), std::logic_error, "Missing 'material.ref' property in spherical extrusion box model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("material.ref"), std::logic_error, "Missing 'material.ref' property in spherical extrusion box model '" << get_name() << "' !"); _material_ = config_.fetch_string ("material.ref"); - DT_THROW_IF (! config_.has_key ("x"), std::logic_error, "Missing 'x' property in spherical extrusion box model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("x"), std::logic_error, "Missing 'x' property in spherical extrusion box model '" << get_name() << "' !"); double x = config_.fetch_real ("x"); if (! config_.has_explicit_unit ("x")) x *= lunit; - DT_THROW_IF (! config_.has_key ("y"), std::logic_error, "Missing 'y' property in spherical extrusion box model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("y"), std::logic_error, "Missing 'y' property in spherical extrusion box model '" << get_name() << "' !"); double y = config_.fetch_real ("y"); if (! config_.has_explicit_unit ("y")) y *= lunit; - DT_THROW_IF (! config_.has_key ("z"), std::logic_error, "Missing 'z' property in spherical extrusion box model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("z"), std::logic_error, "Missing 'z' property in spherical extrusion box model '" << get_name() << "' !"); double z = config_.fetch_real ("z"); if (! config_.has_explicit_unit ("z")) z *= lunit; - DT_THROW_IF (! config_.has_key ("r_extrusion"), std::logic_error, "Missing 'r_extrusion' property in spherical extrusion box model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("r_extrusion"), std::logic_error, "Missing 'r_extrusion' property in spherical extrusion box model '" << get_name() << "' !"); double re = config_.fetch_real ("r_extrusion"); if (! config_.has_explicit_unit ("r_extrusion")) re *= lunit; - DT_THROW_IF (! config_.has_key ("r_sphere"), std::logic_error, "Missing 'r_sphere' property in spherical extrusion box model '" << name_ << "' !"); + DT_THROW_IF (! config_.has_key ("r_sphere"), std::logic_error, "Missing 'r_sphere' property in spherical extrusion box model '" << get_name() << "' !"); double rs = config_.fetch_real ("r_sphere"); if (! config_.has_explicit_unit ("r_sphere")) rs *= lunit; @@ -108,17 +107,17 @@ namespace geomtools { DT_THROW_IF (_r_extrusion_ > _x_ || _r_extrusion_ > _y_, std::logic_error, - "Extrusion radius is larger than mother box dimension in spherical extrusion box model '" << name_ << "' !"); + "Extrusion radius is larger than mother box dimension in spherical extrusion box model '" << get_name() << "' !"); DT_THROW_IF (_r_extrusion_ > _r_sphere_, std::logic_error, - "Extrusion radius is larger than the spherical radius in spherical extrusion box model '" << name_ << "' !"); + "Extrusion radius is larger than the spherical radius in spherical extrusion box model '" << get_name() << "' !"); _mother_.set_x (_x_); _mother_.set_y (_y_); _mother_.set_z (_z_); _mother_.lock(); - DT_THROW_IF (! _mother_.is_valid (), std::logic_error, "Invalid dimension(s) for the mother box in spherical extrusion box model '" << name_ << "' !"); + DT_THROW_IF (! _mother_.is_valid (), std::logic_error, "Invalid dimension(s) for the mother box in spherical extrusion box model '" << get_name() << "' !"); _extrusion_.set (_r_sphere_); _extrusion_.lock(); @@ -126,7 +125,7 @@ namespace geomtools { const double a = std::sqrt (_r_sphere_ * _r_sphere_ - _r_extrusion_ * _r_extrusion_); const double c = _r_sphere_ - a; - DT_THROW_IF (c > _z_, std::logic_error, "Mother box is not long enough (Z ) to host the extrusion in spherical extrusion box model '" << name_ << "' !"); + DT_THROW_IF (c > _z_, std::logic_error, "Mother box is not long enough (Z ) to host the extrusion in spherical extrusion box model '" << get_name() << "' !"); _h_ = _z_ - c; double zsphere = 0.5 * _z_ + a; if (_bottom_) zsphere *= -1; @@ -175,7 +174,7 @@ namespace geomtools { _solid_.set_wires_drawer(*_drawer_); _solid_.lock(); - grab_logical ().set_name (i_model::make_logical_volume_name (name_)); + grab_logical ().set_name (i_model::make_logical_volume_name (get_name())); grab_logical ().set_shape (_solid_); grab_logical ().set_material_ref (_material_); diff --git a/source/bxgeomtools/src/spherical_extrusion_cylinder_model.cc b/source/bxgeomtools/src/spherical_extrusion_cylinder_model.cc index 4d7440e54..a8ed9efef 100644 --- a/source/bxgeomtools/src/spherical_extrusion_cylinder_model.cc +++ b/source/bxgeomtools/src/spherical_extrusion_cylinder_model.cc @@ -56,14 +56,11 @@ namespace geomtools { return; } - void spherical_extrusion_cylinder_model::_at_construct(const std::string & name_, - const datatools::properties & config_, + void spherical_extrusion_cylinder_model::_at_construct(const datatools::properties & config_, geomtools::models_col_type * /*models_*/) { DT_LOG_TRACE(get_logging_priority(), "Entering..."); - //set_name(name_); - // Parse properties: double lunit = CLHEP::mm; @@ -72,22 +69,22 @@ namespace geomtools { lunit = datatools::units::get_length_unit_from(lunit_str); } - DT_THROW_IF(!config_.has_key("material.ref"), std::logic_error, "Missing 'material.ref' property in spherical extrusion cylinder model '" << name_ << "' !"); + DT_THROW_IF(!config_.has_key("material.ref"), std::logic_error, "Missing 'material.ref' property in spherical extrusion cylinder model '" << get_name() << "' !"); _material_ = config_.fetch_string("material.ref"); - DT_THROW_IF(! config_.has_key("z"), std::logic_error, "Missing 'z' property in spherical extrusion cylinder model '" << name_ << "' !"); + DT_THROW_IF(! config_.has_key("z"), std::logic_error, "Missing 'z' property in spherical extrusion cylinder model '" << get_name() << "' !"); double z = config_.fetch_real("z"); if (! config_.has_explicit_unit("z")) z *= lunit; - DT_THROW_IF(! config_.has_key("r"), std::logic_error, "Missing 'r' property in spherical extrusion cylinder model '" << name_ << "' !"); + DT_THROW_IF(! config_.has_key("r"), std::logic_error, "Missing 'r' property in spherical extrusion cylinder model '" << get_name() << "' !"); double r = config_.fetch_real("r"); if (! config_.has_explicit_unit("r")) r *= lunit; - DT_THROW_IF(! config_.has_key("r_extrusion"), std::logic_error, "Missing 'r_extrusion' property in spherical extrusion cylinder model '" << name_ << "' !"); + DT_THROW_IF(! config_.has_key("r_extrusion"), std::logic_error, "Missing 'r_extrusion' property in spherical extrusion cylinder model '" << get_name() << "' !"); double re = config_.fetch_real("r_extrusion"); if (! config_.has_explicit_unit("r_extrusion")) re *= lunit; - DT_THROW_IF(! config_.has_key("r_sphere"), std::logic_error, "Missing 'r_sphere' property in spherical extrusion cylinder model '" << name_ << "' !"); + DT_THROW_IF(! config_.has_key("r_sphere"), std::logic_error, "Missing 'r_sphere' property in spherical extrusion cylinder model '" << get_name() << "' !"); double rs = config_.fetch_real("r_sphere"); if (! config_.has_explicit_unit("r_sphere")) rs *= lunit; @@ -102,13 +99,13 @@ namespace geomtools { _r_extrusion_ = re; _r_sphere_ = rs; - DT_THROW_IF(_r_extrusion_ > _r_, std::logic_error, "Extrusion radius is larger than mother cylinder radius in spherical extrusion cylinder model '" << name_ << "' !"); - DT_THROW_IF(_r_extrusion_ > _r_sphere_, std::logic_error, "Extrusion radius is larger than the spherical radius in spherical extrusion cylinder model '" << name_ << "' !"); + DT_THROW_IF(_r_extrusion_ > _r_, std::logic_error, "Extrusion radius is larger than mother cylinder radius in spherical extrusion cylinder model '" << get_name() << "' !"); + DT_THROW_IF(_r_extrusion_ > _r_sphere_, std::logic_error, "Extrusion radius is larger than the spherical radius in spherical extrusion cylinder model '" << get_name() << "' !"); _mother_.set_r(_r_); _mother_.set_z(_z_); _mother_.lock(); - DT_THROW_IF(! _mother_.is_valid(), std::logic_error, "Invalid dimension(s) for the mother cylinder in spherical extrusion cylinder model '" << name_ << "' !"); + DT_THROW_IF(! _mother_.is_valid(), std::logic_error, "Invalid dimension(s) for the mother cylinder in spherical extrusion cylinder model '" << get_name() << "' !"); _extrusion_.set(_r_sphere_); _extrusion_.lock(); @@ -116,7 +113,7 @@ namespace geomtools { const double a = std::sqrt(_r_sphere_ * _r_sphere_ - _r_extrusion_ * _r_extrusion_); const double c = _r_sphere_ - a; - DT_THROW_IF(c > _z_, std::logic_error, "Mother cylinder is not long enough (Z) to host the extrusion in spherical extrusion cylinder model '" << name_ << "' !"); + DT_THROW_IF(c > _z_, std::logic_error, "Mother cylinder is not long enough (Z) to host the extrusion in spherical extrusion cylinder model '" << get_name() << "' !"); const double h = _z_ - c; double zsphere = 0.5 * _z_ + a; if (_bottom_) zsphere *= -1; @@ -168,7 +165,7 @@ namespace geomtools { _solid_.set_wires_drawer(*_drawer_); _solid_.lock(); - grab_logical().set_name(i_model::make_logical_volume_name(name_)); + grab_logical().set_name(i_model::make_logical_volume_name(get_name())); grab_logical().set_shape(_solid_); grab_logical().set_material_ref(_material_); diff --git a/source/bxgeomtools/src/stacked_model.cc b/source/bxgeomtools/src/stacked_model.cc index d8f66b2bf..fe9687bc3 100644 --- a/source/bxgeomtools/src/stacked_model.cc +++ b/source/bxgeomtools/src/stacked_model.cc @@ -264,17 +264,15 @@ namespace geomtools { return; } - void stacked_model::_at_construct (const std::string & name_, - const datatools::properties & config_, + void stacked_model::_at_construct (const datatools::properties & config_, models_col_type * models_) { DT_LOG_TRACE (get_logging_priority (), "Entering..."); - // set_name (name_); /*** material ***/ DT_THROW_IF (! config_.has_key ("material.ref"), std::logic_error, - "Missing 'material.ref' property in stacked model '" << name_ << "' !"); + "Missing 'material.ref' property in stacked model '" << get_name() << "' !"); const std::string material_name = config_.fetch_string ("material.ref"); set_material_name (material_name); @@ -310,12 +308,12 @@ namespace geomtools { if (! config_.has_explicit_unit ("numerics_play")) numerics_play *= lunit; DT_THROW_IF (numerics_play < 0.0, std::logic_error, - "Numerics play '" << numerics_play / CLHEP::mm << "' mm cannot be negative in stacked model '" << name_ << "' !"); + "Numerics play '" << numerics_play / CLHEP::mm << "' mm cannot be negative in stacked model '" << get_name() << "' !"); _numerics_play_ = numerics_play; } /*** Stacking axis ***/ - DT_THROW_IF (!config_.has_key ("stacked.axis"), std::logic_error, "Missing 'stacked.axis' property in stacked model '" << name_ << "' !"); + DT_THROW_IF (!config_.has_key ("stacked.axis"), std::logic_error, "Missing 'stacked.axis' property in stacked model '" << get_name() << "' !"); const std::string stacking_axis_label = config_.fetch_string ("stacked.axis"); int stacking_axis; if (stacking_axis_label == "x") { @@ -325,7 +323,7 @@ namespace geomtools { } else if (stacking_axis_label == "z") { stacking_axis = STACKING_ALONG_Z; } else { - DT_THROW_IF (true, std::logic_error, "Unknown axis label '" << stacking_axis_label << "' in stacked model '" << name_ << "' !"); + DT_THROW_IF (true, std::logic_error, "Unknown axis label '" << stacking_axis_label << "' in stacked model '" << get_name() << "' !"); } set_stacking_axis (stacking_axis); // std::cerr << "DEVEL: stacked_model::_at_construct: stacking axis = " << stacking_axis_label << std::endl; @@ -333,11 +331,11 @@ namespace geomtools { /*** number of stacked stacked models ***/ DT_THROW_IF (! config_.has_key ("stacked.number_of_items"), std::logic_error, - "Missing 'stacked.number_of_items' property in stacked model '" << name_ << "' !"); + "Missing 'stacked.number_of_items' property in stacked model '" << get_name() << "' !"); const size_t number_of_items = config_.fetch_integer ("stacked.number_of_items"); /*** check models ***/ - DT_THROW_IF (! models_, std::logic_error, "Missing logicals dictionary in stacked model '" << name_ << "' !"); + DT_THROW_IF (! models_, std::logic_error, "Missing logicals dictionary in stacked model '" << get_name() << "' !"); /*** loop over models to be stacked ***/ for (size_t i = 0; i < number_of_items; i++) { @@ -345,7 +343,7 @@ namespace geomtools { stacked_item_prop << STACKED_MODEL_PROPERTY_PREFIX << i; DT_THROW_IF(! config_.has_key(stacked_item_prop.str()), std::logic_error, - "Missing '" << stacked_item_prop.str() << "' property in stacked model '" << name_ << "' !"); + "Missing '" << stacked_item_prop.str() << "' property in stacked model '" << get_name() << "' !"); const std::string stacked_model_name = config_.fetch_string(stacked_item_prop.str()); // attempt to extract a user defined label: @@ -359,7 +357,7 @@ namespace geomtools { models_col_type::const_iterator found = models_->find(stacked_model_name); DT_THROW_IF(found == models_->end(), std::logic_error, - "Cannot find model with name '" << stacked_model_name << "' in stacked model '" << name_ << "' !"); + "Cannot find model with name '" << stacked_model_name << "' in stacked model '" << get_name() << "' !"); stackable::stackability_mode sdsm = stackable::STACKABILITY_NONE; if (stacking_axis == STACKING_ALONG_X) { @@ -399,7 +397,7 @@ namespace geomtools { if (! stackability) { // found->second->get_logical().get_shape().tree_dump(std::cerr, "No required stackability for shape: ", "[devel] "); DT_THROW(std::logic_error, - "The embedded model '" << found->second->get_name() << "' doesn't match the required stackability in stacked model '" << name_ << "' !"); + "The embedded model '" << found->second->get_name() << "' doesn't match the required stackability in stacked model '" << get_name() << "' !"); } const i_model * geo_model = found->second; @@ -491,16 +489,16 @@ namespace geomtools { DT_THROW_IF(! the_shape.has_bounding_data(), std::logic_error, "Cannot find bounding data in shape '" << the_shape.get_shape_name() - << "' in stacked model '" << name_ << "' !"); + << "' in stacked model '" << get_name() << "' !"); // Try to get a stackable data from the shape: stackable_data the_SD; DT_THROW_IF(! i_shape_3d::pickup_stackable(the_shape, the_SD), std::logic_error, "Cannot stack non-stackable model of shape '" << the_shape.get_shape_name() - << "' in stacked model '" << name_ << "' !"); + << "' in stacked model '" << get_name() << "' !"); DT_LOG_TRACE(get_logging_priority(), "Dump stackable data for '" << the_stacked_model->get_name() << - "' from '" << name_ << "'..."); + "' from '" << get_name() << "'..."); if(datatools::logger::is_trace(get_logging_priority())) { the_SD.tree_dump(std::clog, "", "[trace]: "); } @@ -613,7 +611,7 @@ namespace geomtools { std::logic_error, "Cannot stack '" << the_shape.get_shape_name() << "' shape in stacked model '" - << name_ << "' !"); + << get_name() << "' !"); double gxmin = the_SD.get_xmin(); double gymin = the_SD.get_ymin(); double gzmin = the_SD.get_zmin(); @@ -766,7 +764,7 @@ namespace geomtools { DT_THROW_IF(x < stacked_x, std::logic_error, "Enforced X dimension '" << x / CLHEP::mm << "' mm (<" << stacked_x / CLHEP::mm << ") " << - "is too small for stacked components to fit in stacked model '" << name_ << "' !"); + "is too small for stacked components to fit in stacked model '" << get_name() << "' !"); dim_x = x; } @@ -776,7 +774,7 @@ namespace geomtools { DT_THROW_IF(y < stacked_y, std::logic_error, "Enforced Y dimension '" << y / CLHEP::mm << "' mm (<" << stacked_y / CLHEP::mm << ") " << - "is too small for stacked components to fit in stacked model '" << name_ << "' !"); + "is too small for stacked components to fit in stacked model '" << get_name() << "' !"); dim_y = y; } dim_r = 0.5 * std::max(dim_x, dim_y); @@ -787,11 +785,11 @@ namespace geomtools { DT_THROW_IF(r < 0.5 * stacked_x, std::logic_error, "Enforced R dimension '" << r / CLHEP::mm << "' mm (<" << 0.5 * stacked_x / CLHEP::mm << ") " << - "is too small for stacked components to fit in stacked model '" << name_ << "' !"); + "is too small for stacked components to fit in stacked model '" << get_name() << "' !"); DT_THROW_IF(r < 0.5 * stacked_y, std::logic_error, "Enforced R dimension '" << r / CLHEP::mm << "' mm (<" << 0.5 * stacked_y / CLHEP::mm << ") " << - "is too small for stacked components to fit in stacked model '" << name_ << "' !"); + "is too small for stacked components to fit in stacked model '" << get_name() << "' !"); dim_r = r; dim_x = 2 * r; dim_y = 2 * r; @@ -804,7 +802,7 @@ namespace geomtools { DT_THROW_IF(z < stacked_z, std::logic_error, "Enforced Z dimension '" << z / CLHEP::mm << "' mm (<" << stacked_z / CLHEP::mm << ") " << - "is too small for stacked components to fit in stacked model '" << name_ << "' !"); + "is too small for stacked components to fit in stacked model '" << get_name() << "' !"); dim_z = z; } @@ -848,16 +846,16 @@ namespace geomtools { _solid_.set_z(dim_z); _solid_.lock(); DT_THROW_IF (! _solid_.is_valid (), std::logic_error, - "Invalid box solid in stacked model '" << name_ << "' !"); + "Invalid box solid in stacked model '" << get_name() << "' !"); _cyl_solid_.reset(); if (is_cylinder_solid()) { _cyl_solid_.set_r(dim_r); _cyl_solid_.set_z(dim_z); _cyl_solid_.lock(); DT_THROW_IF (! _cyl_solid_.is_valid (), std::logic_error, - "Invalid cylinder solid in stacked model '" << name_ << "' !"); + "Invalid cylinder solid in stacked model '" << get_name() << "' !"); } - grab_logical().set_name (i_model::make_logical_volume_name (name_)); + grab_logical().set_name (i_model::make_logical_volume_name (get_name())); if (is_box_solid()) { grab_logical().set_shape(_solid_); } else if (is_cylinder_solid()) { diff --git a/source/bxgeomtools/src/surrounded_boxed_model.cc b/source/bxgeomtools/src/surrounded_boxed_model.cc index 14612a6c8..f4503dfc3 100644 --- a/source/bxgeomtools/src/surrounded_boxed_model.cc +++ b/source/bxgeomtools/src/surrounded_boxed_model.cc @@ -197,17 +197,15 @@ namespace geomtools { return; } - void surrounded_boxed_model::_at_construct (const std::string & name_, - const datatools::properties & config_, + void surrounded_boxed_model::_at_construct (const datatools::properties & config_, models_col_type * models_) { DT_LOG_TRACE (get_logging_priority (), "Entering..."); - //set_name (name_); // material: DT_THROW_IF (! config_.has_key ("material.ref"), std::logic_error, - "Missing 'material.ref' property in surrounded boxed model '" << name_ << "' !"); + "Missing 'material.ref' property in surrounded boxed model '" << get_name() << "' !"); const std::string material_name = config_.fetch_string ("material.ref"); set_material_name (material_name); @@ -221,7 +219,7 @@ namespace geomtools { // Surrounded model: DT_THROW_IF (! config_.has_key ("surrounded.model"), std::logic_error, - "Missing 'surrounded.model' property in surrounded boxed model '" << name_ << "' !"); + "Missing 'surrounded.model' property in surrounded boxed model '" << get_name() << "' !"); const std::string surrounded_model_name = config_.fetch_string ("surrounded.model"); // Surrounded label: @@ -247,21 +245,21 @@ namespace geomtools { } // check models: - DT_THROW_IF (! models_, std::logic_error, "Missing logicals dictionary in surrounded boxed model '" << name_ << "' !"); + DT_THROW_IF (! models_, std::logic_error, "Missing logicals dictionary in surrounded boxed model '" << get_name() << "' !"); // check if surrounded model exists: { models_col_type::const_iterator found = models_->find(surrounded_model_name); DT_THROW_IF (found == models_->end (), std::logic_error, - "Cannot find surrounded model with name '" << surrounded_model_name << "' in surrounded boxed model '" << name_ << "' !"); + "Cannot find surrounded model with name '" << surrounded_model_name << "' in surrounded boxed model '" << get_name() << "' !"); // Check if the surrounded model's stackability: // 2017-02-23, FM: For now we check full stackability on all directions around the volume. // In principle, we should only check directions with a surrounding volume. DT_THROW_IF (! i_shape_3d::check_stackability(found->second->get_logical().get_shape(), stackable::STACKABILITY_STRONG), std::logic_error, - "The surrounded model '" << found->second->get_name() << "' is not stackable in surrounded boxed model '" << name_ << "' !"); + "The surrounded model '" << found->second->get_name() << "' is not stackable in surrounded boxed model '" << get_name() << "' !"); set_surrounded_model(*(found->second)); } @@ -291,7 +289,7 @@ namespace geomtools { models_col_type::const_iterator found = models_->find (surrounding_model_name); DT_THROW_IF (found == models_->end (), std::logic_error, - "Cannot find surrounding model with name '"<< surrounding_model_name << "' in surrounded boxed model '" << name_ << "' !"); + "Cannot find surrounding model with name '"<< surrounding_model_name << "' in surrounded boxed model '" << get_name() << "' !"); // check the surrounding model's stackability:: stackable::stackability_mode sdsm = stackable::STACKABILITY_NONE; @@ -313,7 +311,7 @@ namespace geomtools { DT_THROW_IF (! i_shape_3d::check_stackability(found->second->get_logical().get_shape(), sdsm), std::logic_error, "The " << *ilabel << " surrounding model '" << found->second->get_name () - << "' has no required stackability for surrounded boxed model '" << name_ << "' !"); + << "' has no required stackability for surrounded boxed model '" << get_name() << "' !"); add_surrounding_model(ipos, *(found->second), label_name); } // end of for } @@ -332,7 +330,7 @@ namespace geomtools { stackable_data the_SD; DT_THROW_IF ((! i_shape_3d::pickup_stackable(the_shape, the_SD)), std::logic_error, - "Cannot surround/stack the '" << the_shape.get_shape_name () << "' shape in surrounded boxed model '" << name_ << "' !"); + "Cannot surround/stack the '" << the_shape.get_shape_name () << "' shape in surrounded boxed model '" << get_name() << "' !"); const double gxmin = the_SD.get_xmin (); const double gxmax = the_SD.get_xmax (); const double gymin = the_SD.get_ymin (); @@ -367,7 +365,7 @@ namespace geomtools { DT_THROW_IF ((! i_shape_3d::pickup_stackable (the_surrounding_shape, the_SD2)), std::logic_error, "Cannot surround/stack the '" - << the_surrounding_shape.get_shape_name () << "' surrounding shape in surrounded boxed model '" << name_ << "' !"); + << the_surrounding_shape.get_shape_name () << "' surrounding shape in surrounded boxed model '" << get_name() << "' !"); const double g2xmin = the_SD2.get_xmin (); const double g2xmax = the_SD2.get_xmax (); const double g2ymin = the_SD2.get_ymin (); @@ -472,7 +470,7 @@ namespace geomtools { DT_THROW_IF (x < dim_x, std::logic_error, "Enforced X dimension '" << x / CLHEP::mm - << "' mm (<" << dim_x / CLHEP::mm << ") is too small for surrounded components to fit in surrounded boxed model '" << name_ << "' !"); + << "' mm (<" << dim_x / CLHEP::mm << ") is too small for surrounded components to fit in surrounded boxed model '" << get_name() << "' !"); dim_x = x; } @@ -494,7 +492,7 @@ namespace geomtools { DT_THROW_IF (z < dim_z, std::logic_error, "Enforced Z dimension '" << z / CLHEP::mm - << "' mm (<" << dim_z / CLHEP::mm << ") is too small for surrounded components to fit in surrounded boxed model '" << name_ << "' !"); + << "' mm (<" << dim_z / CLHEP::mm << ") is too small for surrounded components to fit in surrounded boxed model '" << get_name() << "' !"); dim_z = z; } @@ -504,9 +502,9 @@ namespace geomtools { _solid_.set_y(dim_y); _solid_.set_z(dim_z); _solid_.lock(); - DT_THROW_IF (! _solid_.is_valid (), std::logic_error, "Invalid solid in surrounded boxed model '" << name_ << "' !"); + DT_THROW_IF (! _solid_.is_valid (), std::logic_error, "Invalid solid in surrounded boxed model '" << get_name() << "' !"); - grab_logical ().set_name (i_model::make_logical_volume_name (name_)); + grab_logical ().set_name (i_model::make_logical_volume_name (get_name())); grab_logical ().set_shape (_solid_); grab_logical ().set_material_ref (_material_name_); diff --git a/source/bxgeomtools/src/tube.cc b/source/bxgeomtools/src/tube.cc index baae4cddb..de8f7da7f 100644 --- a/source/bxgeomtools/src/tube.cc +++ b/source/bxgeomtools/src/tube.cc @@ -820,8 +820,8 @@ namespace geomtools { void tube::compute_inner_cylinder (cylinder & ic_) { + DT_THROW_IF(! is_valid(), std::logic_error, "Invalid tube!"); ic_.reset(); - DT_THROW_IF (! is_valid (),logic_error, "Tube is not valid !"); ic_.set(get_inner_r (), get_z ()); ic_.lock(); return; @@ -831,12 +831,130 @@ namespace geomtools { { DT_THROW_IF(! is_valid(), std::logic_error, "Invalid tube!"); oc_.reset (); - DT_THROW_IF (! is_valid (),logic_error, "Tube is not valid !"); - oc_.set (get_outer_r (), get_z ()); + oc_.set(get_outer_r(), get_z()); oc_.lock(); return; } + void tube::compute_deflated(tube & deflated_, + double by_r_, + double by_z_, + double by_angle_) + { + DT_THROW_IF(! is_valid(), std::logic_error, "Invalid tube!"); + double r_eps = 0.0; + double z_eps = 0.0; + if (datatools::is_valid(by_r_) and by_r_ > 0.0) r_eps = by_r_; + if (datatools::is_valid(by_z_) and by_z_ > 0.0) z_eps = by_z_; + double rmax = get_outer_r(); + double z = get_z(); + double rmin = get_inner_r(); + rmax -= r_eps; + if (has_inner_r()) { + rmin += r_eps; + } + z -= (2 * z_eps); + deflated_.reset(); + if (has_inner_r()) { + deflated_.set(rmin, rmax, z); + } else { + deflated_.set(rmax, z); + } + double eps_angle = by_angle_; + if (eps_angle < 0.0) { + eps_angle = r_eps / rmax; + } + if (has_partial_phi()) { + double start_phi = get_start_phi(); + double delta_phi = get_delta_phi(); + if (eps_angle > 0.0) { + start_phi += eps_angle; + delta_phi -= 2 * eps_angle; + if (delta_phi < 0.0) { + // DT_THROW_IF(std::range_error, "Cannot compute deflated tube!"); + start_phi = get_start_phi() + 0.5 * get_delta_phi() - 0.25 * eps_angle; + delta_phi = 0.5 * eps_angle; + } + } + deflated_.set_start_phi(start_phi); + deflated_.set_delta_phi(delta_phi); + } + deflated_.lock(); + return; + } + + void tube::compute_inflated(tube & inflated_, + double by_r_, + double by_z_, + double by_angle_) + { + DT_THROW_IF(! is_valid(), std::logic_error, "Invalid tube!"); + double r_eps = 0.0; + double z_eps = 0.0; + if (datatools::is_valid(by_r_) and by_r_ > 0.0) r_eps = by_r_; + if (datatools::is_valid(by_z_) and by_z_ > 0.0) z_eps = by_z_; + double rmax = get_outer_r(); + double z = get_z(); + double rmin = get_inner_r(); + rmax += r_eps; + if (has_inner_r()) { + rmin -= r_eps; + } + z += (2 * z_eps); + inflated_.reset(); + if (has_inner_r() and rmin > 0.0) { + inflated_.set(rmin, rmax, z); + } else { + inflated_.set(rmax, z); + } + double eps_angle = by_angle_; + if (eps_angle < 0.0) { + eps_angle = r_eps / rmax; + } + if (has_partial_phi()) { + double start_phi = get_start_phi(); + double delta_phi = get_delta_phi(); + if (eps_angle > 0.0) { + start_phi -= eps_angle; + delta_phi += 2 * eps_angle; + } + if (delta_phi < 2 * M_PI) { + inflated_.set_start_phi(start_phi); + inflated_.set_delta_phi(delta_phi); + } + } + inflated_.lock(); + return; + } + + void tube::compute_envelope(tube & envelope_, + double r_tolerance_, + double z_tolerance_, + double angle_tolerance_) + { + compute_inflated(envelope_, r_tolerance_, z_tolerance_, angle_tolerance_); + return; + } + + void tube::compute_envelope(cylinder & envelope_, + double r_tolerance_, + double z_tolerance_) + { + DT_THROW_IF(! is_valid(), std::logic_error, "Invalid tube!"); + double r_eps = 0.0; + double z_eps = 0.0; + if (datatools::is_valid(r_tolerance_) and r_tolerance_ > 0.0) r_eps = r_tolerance_; + if (datatools::is_valid(z_tolerance_) and z_tolerance_ > 0.0) z_eps = z_tolerance_; + double rmax = get_outer_r(); + double z = get_z(); + rmax += r_eps; + z += (2 * z_eps); + envelope_.reset(); + envelope_.set(rmax, z); + envelope_.lock(); + return; + } + void tube::_build_bounding_data() { // std::cerr << "DEVEL: tube::_build_bounding_data: " diff --git a/source/bxgeomtools/testing/config/test_geometry_models.conf b/source/bxgeomtools/testing/config/test_geometry_models.conf index 8fcb86cb6..7df427b14 100644 --- a/source/bxgeomtools/testing/config/test_geometry_models.conf +++ b/source/bxgeomtools/testing/config/test_geometry_models.conf @@ -103,10 +103,12 @@ visibility.color : string = "red" [name="PMT.model" type="geomtools::simple_shaped_model"] -# logging.priority : string = "debug" +logging.priority : string = "debug" shape_type : string = "polycone" filled_mode : string = "by_envelope" +envelope.tolerance.r : real as length = 5 mm +envelope.tolerance.z : real as length = 5 mm length_unit : string = "mm" material.ref : string = "glass" @@ -115,15 +117,15 @@ material.filled.ref : string = "vacuum" build_mode : string = "datafile" datafile : string = "${GEOMTOOLS_TESTING_DIR}/data/test_hamamatsu_R5912MOD_polycone.data" -visibility.hidden : boolean = 0 -visibility.hidden_envelope : boolean = 0 +visibility.hidden : boolean = true +visibility.hidden_envelope : boolean = false visibility.color : string = "magenta" -visibility.daughters.hidden : boolean = 0 +visibility.daughters.hidden : boolean = false -visibility.filled.hidden : boolean = 0 -visibility.filled.hidden_envelope : boolean = 0 -visibility.filled.color : string = "grey" -visibility.filled.daughters.hidden : boolean = 0 +visibility.filled.hidden : boolean = false +visibility.filled.hidden_envelope : boolean = false +visibility.filled.color : string = "blue" +visibility.filled.daughters.hidden : boolean = false internal_item.filled.labels : string[12] = \ "focusing_electrode" \ diff --git a/source/bxgeomtools/testing/geomtools_test_model_1.cc b/source/bxgeomtools/testing/geomtools_test_model_1.cc index 3e7bf8f63..eb83e5e75 100644 --- a/source/bxgeomtools/testing/geomtools_test_model_1.cc +++ b/source/bxgeomtools/testing/geomtools_test_model_1.cc @@ -29,13 +29,11 @@ namespace geomtools { { } - void test_model_1::_at_construct (const string & name_, - const datatools::properties & config_, + void test_model_1::_at_construct (const datatools::properties & config_, models_col_type * /* models_ */) { bool devel = false; if (devel) clog << "DEVEL: test_model_1::_at_construct: Entering..." << endl; - set_name (name_); double width = 1.0 * CLHEP::mm; double height = 1.0 * CLHEP::mm; string material; @@ -76,7 +74,7 @@ namespace geomtools { } // initialize the 'logical_volume' of this model: - grab_logical ().set_name (i_model::make_logical_volume_name (name_)); + grab_logical ().set_name (i_model::make_logical_volume_name (get_name())); grab_logical ().set_shape (_solid_); grab_logical ().set_material_ref (material); diff --git a/source/bxgeomtools/testing/geomtools_test_model_1.h b/source/bxgeomtools/testing/geomtools_test_model_1.h index 0f0329cfe..9879e8e48 100644 --- a/source/bxgeomtools/testing/geomtools_test_model_1.h +++ b/source/bxgeomtools/testing/geomtools_test_model_1.h @@ -48,8 +48,7 @@ namespace geomtools { protected: - virtual void _at_construct (const string & name_, - const datatools::properties & config_, + virtual void _at_construct (const datatools::properties & config_, models_col_type * models_ = 0); private: diff --git a/source/bxgeomtools/testing/geomtools_test_model_2.cc b/source/bxgeomtools/testing/geomtools_test_model_2.cc index 056bbb9dd..448c334d3 100644 --- a/source/bxgeomtools/testing/geomtools_test_model_2.cc +++ b/source/bxgeomtools/testing/geomtools_test_model_2.cc @@ -32,13 +32,11 @@ namespace geomtools { return; } - void test_model_2::_at_construct (const string & name_, - const datatools::properties & config_, + void test_model_2::_at_construct (const datatools::properties & config_, models_col_type * models_) { bool devel = false; if (devel) clog << "DEVEL: test_model_2::_at_construct: Entering..." << endl; - set_name (name_); double gas_pressure = 1. * CLHEP::atmosphere; double gas_temperature = 300. * CLHEP::kelvin; double distance = 50. * CLHEP::mm; @@ -183,7 +181,7 @@ namespace geomtools { } // initialize the 'logical_volume' of this model: - grab_logical ().set_name (i_model::make_logical_volume_name (name_)); + grab_logical ().set_name (i_model::make_logical_volume_name (get_name())); grab_logical ().set_shape (_solid_); grab_logical ().set_material_ref (material); diff --git a/source/bxgeomtools/testing/geomtools_test_model_2.h b/source/bxgeomtools/testing/geomtools_test_model_2.h index 9f797e83f..0bdc54ea5 100644 --- a/source/bxgeomtools/testing/geomtools_test_model_2.h +++ b/source/bxgeomtools/testing/geomtools_test_model_2.h @@ -51,9 +51,8 @@ namespace geomtools { protected: - virtual void _at_construct (const std::string & name_, - const datatools::properties & config_, - models_col_type * models_ = 0); + virtual void _at_construct (const datatools::properties & config_, + models_col_type * models_ = nullptr); private: double _distance_; diff --git a/source/bxgeomtools/testing/geomtools_test_world_model.cc b/source/bxgeomtools/testing/geomtools_test_world_model.cc index 8ac21b72b..01f5a605d 100644 --- a/source/bxgeomtools/testing/geomtools_test_world_model.cc +++ b/source/bxgeomtools/testing/geomtools_test_world_model.cc @@ -31,13 +31,11 @@ namespace geomtools { { } - void test_world_model::_at_construct (const string & name_, - const datatools::properties & config_, + void test_world_model::_at_construct (const datatools::properties & config_, models_col_type * models_) { bool devel = false; if (devel) clog << "DEVEL: test_world_model::_at_construct: Entering..." << endl; - set_name (name_); string material = "vacuum"; string setup_model_name; double phi = 0. * CLHEP::degree; @@ -132,7 +130,7 @@ namespace geomtools { throw runtime_error ("test_world_model::_at_construct: Invalid solid !"); } - grab_logical ().set_name (i_model::make_logical_volume_name (name_)); + grab_logical ().set_name (i_model::make_logical_volume_name (get_name())); grab_logical ().set_shape (__solid); grab_logical ().set_material_ref (material); diff --git a/source/bxgeomtools/testing/geomtools_test_world_model.h b/source/bxgeomtools/testing/geomtools_test_world_model.h index cd63c30fc..dcecf4795 100644 --- a/source/bxgeomtools/testing/geomtools_test_world_model.h +++ b/source/bxgeomtools/testing/geomtools_test_world_model.h @@ -58,8 +58,7 @@ namespace geomtools { protected: - virtual void _at_construct (const std::string & name_, - const datatools::properties & setup_, + virtual void _at_construct (const datatools::properties & setup_, models_col_type * models_ = 0); public: diff --git a/source/bxgeomtools/testing/test_polycone.cxx b/source/bxgeomtools/testing/test_polycone.cxx index 213d9e60b..74b457412 100644 --- a/source/bxgeomtools/testing/test_polycone.cxx +++ b/source/bxgeomtools/testing/test_polycone.cxx @@ -45,6 +45,9 @@ int main (int argc_, char ** argv_) bool locate_bulk = false; bool draw = false; // Interactive plot bool do_intercept = true; + bool do_envelope = false; + bool do_deflated = false; + bool do_inflated = false; int iarg = 1; while (iarg < argc_) { @@ -65,6 +68,9 @@ int main (int argc_, char ** argv_) // if (arg == "-T" || arg == "--no-top") do_no_top = true; if (arg == "-L" || arg == "--no-locate") do_locate = false; if (arg == "-P" || arg == "--no-intercept") do_intercept = false; + if (arg == "-e" || arg == "--envelope") do_envelope = true; + if (arg == "-f" || arg == "--deflated") do_deflated = true; + if (arg == "-F" || arg == "--inflated") do_inflated = true; iarg++; } @@ -291,7 +297,83 @@ int main (int argc_, char ** argv_) tmp_file.out() << std::endl << std::endl; data_index["draw2"] = gpindex++; std::clog << "INFO: Draw solid again done." << std::endl; - } + } + + if (do_envelope) { + tmp_file.out() << "# polycone envelope (index 4):" << std::endl; + geomtools::polycone my_polycone_envelope; + my_solid.compute_envelope(my_polycone_envelope, 1.0, 1.0); + // Draw envelope : + geomtools::wires_type envelope_wires; + my_polycone_envelope.generate_wires(envelope_wires, + my_solid_placement, + geomtools::i_wires_3d_rendering::WR_NONE + | geomtools::i_wires_3d_rendering::WR_BASE_GRID + | geomtools::i_wires_3d_rendering::WR_BASE_BEST_GRID_SAMPLING + // | geomtools::i_wires_3d_rendering::WR_BASE_GRID_HIGH_DENSITY + //| geomtools::i_wires_3d_rendering::WR_BASE_BOUNDINGS + // | geomtools::i_wires_3d_rendering::WR_BASE_EXPLODE + // | geomtools::tube::WR_TUBE_NO_BOTTOM_FACE + // | geomtools::tube::WR_TUBE_NO_TOP_FACE + // | geomtools::tube::WR_TUBE_NO_INNER_FACE + // | geomtools::tube::WR_TUBE_NO_OUTER_FACE + ); + geomtools::gnuplot_draw::draw_wires(tmp_file.out(), envelope_wires); + tmp_file.out() << std::endl << std::endl; + data_index["envelope"] = gpindex++; + + } + + if (do_deflated) { + tmp_file.out() << "# polycone deflated (index 5):" << std::endl; + geomtools::polycone my_polycone_deflated; + my_solid.compute_deflated(my_polycone_deflated, 2.0, 2.0, -1.0); + // Draw deflated envelope : + geomtools::wires_type deflated_wires; + my_polycone_deflated.generate_wires(deflated_wires, + my_solid_placement, + geomtools::i_wires_3d_rendering::WR_NONE + | geomtools::i_wires_3d_rendering::WR_BASE_GRID + | geomtools::i_wires_3d_rendering::WR_BASE_BEST_GRID_SAMPLING + // | geomtools::i_wires_3d_rendering::WR_BASE_GRID_HIGH_DENSITY + //| geomtools::i_wires_3d_rendering::WR_BASE_BOUNDINGS + // | geomtools::i_wires_3d_rendering::WR_BASE_EXPLODE + // | geomtools::tube::WR_TUBE_NO_BOTTOM_FACE + // | geomtools::tube::WR_TUBE_NO_TOP_FACE + // | geomtools::tube::WR_TUBE_NO_INNER_FACE + // | geomtools::tube::WR_TUBE_NO_OUTER_FACE + ); + geomtools::gnuplot_draw::draw_wires(tmp_file.out(), deflated_wires); + tmp_file.out() << std::endl << std::endl; + data_index["deflated"] = gpindex++; + + } + + if (do_inflated) { + tmp_file.out() << "# polycone inflated (index 6):" << std::endl; + geomtools::polycone my_polycone_inflated; + my_solid.compute_inflated(my_polycone_inflated, 2.0, 2.0, -1.0); + // Draw inflated envelope : + geomtools::wires_type inflated_wires; + my_polycone_inflated.generate_wires(inflated_wires, + my_solid_placement, + geomtools::i_wires_3d_rendering::WR_NONE + | geomtools::i_wires_3d_rendering::WR_BASE_GRID + | geomtools::i_wires_3d_rendering::WR_BASE_BEST_GRID_SAMPLING + // | geomtools::i_wires_3d_rendering::WR_BASE_GRID_HIGH_DENSITY + //| geomtools::i_wires_3d_rendering::WR_BASE_BOUNDINGS + // | geomtools::i_wires_3d_rendering::WR_BASE_EXPLODE + // | geomtools::tube::WR_TUBE_NO_BOTTOM_FACE + // | geomtools::tube::WR_TUBE_NO_TOP_FACE + // | geomtools::tube::WR_TUBE_NO_INNER_FACE + // | geomtools::tube::WR_TUBE_NO_OUTER_FACE + ); + geomtools::gnuplot_draw::draw_wires(tmp_file.out(), inflated_wires); + tmp_file.out() << std::endl << std::endl; + data_index["inflated"] = gpindex++; + + } + my_solid.tree_dump (std::clog, "Polycone"); if (draw) { @@ -346,6 +428,36 @@ int main (int argc_, char ** argv_) geomtools::gnuplot_drawer::wait_for_key(); usleep(2); } + + if (do_envelope) { + std::ostringstream plot_cmd; + plot_cmd << "splot '" << tmp_file.get_filename () << "' index " << data_index["draw2"] << " title 'Polycone' with lines "; + plot_cmd << " , '' index " << data_index["envelope"] << " title 'Envelope' with lines "; + g1.cmd (plot_cmd.str ()); + g1.showonscreen (); // window output + geomtools::gnuplot_drawer::wait_for_key (); + usleep (200); + } + + if (do_deflated) { + std::ostringstream plot_cmd; + plot_cmd << "splot '" << tmp_file.get_filename () << "' index " << data_index["draw2"] << " title 'Polycone' with lines "; + plot_cmd << " , '' index " << data_index["deflated"] << " title 'Deflated outer' with lines "; + g1.cmd (plot_cmd.str ()); + g1.showonscreen (); // window output + geomtools::gnuplot_drawer::wait_for_key (); + usleep (200); + } + + if (do_inflated) { + std::ostringstream plot_cmd; + plot_cmd << "splot '" << tmp_file.get_filename () << "' index " << data_index["draw2"] << " title 'Polycone' with lines "; + plot_cmd << " , '' index " << data_index["inflated"] << " title 'Inflated' with lines "; + g1.cmd (plot_cmd.str ()); + g1.showonscreen (); // window output + geomtools::gnuplot_drawer::wait_for_key (); + usleep (200); + } #endif // GEOMTOOLS_WITH_GNUPLOT_DISPLAY == 1 } diff --git a/source/bxgeomtools/testing/test_tube.cxx b/source/bxgeomtools/testing/test_tube.cxx index 929dd8f72..6061e1576 100644 --- a/source/bxgeomtools/testing/test_tube.cxx +++ b/source/bxgeomtools/testing/test_tube.cxx @@ -17,6 +17,8 @@ // This project: #include #include +#include +#include #if GEOMTOOLS_WITH_GNUPLOT_DISPLAY == 1 #include #include @@ -39,6 +41,7 @@ int main (int argc_, char ** argv_) bool do_locate = true; bool do_sector = false; bool do_hole = false; + bool do_envelope = false; bool draw = false; int iarg = 1; @@ -58,6 +61,7 @@ int main (int argc_, char ** argv_) if (arg == "-t" || arg == "--no-top") top = false; if (arg == "-s" || arg == "--no-start") start = false; if (arg == "-p" || arg == "--no-stop") stop = false; + if (arg == "-e" || arg == "--envelope") do_envelope = true; iarg++; } @@ -177,7 +181,7 @@ int main (int argc_, char ** argv_) geomtools::gnuplot_draw::draw_wires(tmp_file.out(), tube_wires); tmp_file.out() << std::endl << std::endl; } - + { std::clog << "test 3: Intercept..." << std::endl; @@ -217,7 +221,30 @@ int main (int argc_, char ** argv_) } tmp_file.out() << std::endl << std::endl; } + + if (do_envelope) { + tmp_file.out() << "# tube envelope (index 4):" << std::endl; + geomtools::cylinder my_tube_envelope; + my_tube.compute_envelope(my_tube_envelope, 0.2, 0.2); + // Draw envelope : + geomtools::wires_type cylinder_wires; + my_tube_envelope.generate_wires(cylinder_wires, + tube_placement, + geomtools::i_wires_3d_rendering::WR_NONE + | geomtools::i_wires_3d_rendering::WR_BASE_GRID + | geomtools::i_wires_3d_rendering::WR_BASE_GRID_HIGH_DENSITY + //| geomtools::i_wires_3d_rendering::WR_BASE_BOUNDINGS + // | geomtools::i_wires_3d_rendering::WR_BASE_EXPLODE + // | geomtools::tube::WR_TUBE_NO_BOTTOM_FACE + // | geomtools::tube::WR_TUBE_NO_TOP_FACE + // | geomtools::tube::WR_TUBE_NO_INNER_FACE + // | geomtools::tube::WR_TUBE_NO_OUTER_FACE + ); + geomtools::gnuplot_draw::draw_wires(tmp_file.out(), cylinder_wires); + tmp_file.out() << std::endl << std::endl; + } + // if (interactive) { // std::clog << "Enter a tube (example: '{tube 900 1000 1000}'): "; @@ -270,7 +297,17 @@ int main (int argc_, char ** argv_) geomtools::gnuplot_drawer::wait_for_key (); usleep (200); } - + + if (do_envelope) { + std::ostringstream plot_cmd; + plot_cmd << "splot '" << tmp_file.get_filename () << "' index 0 title 'Tube' with lines "; + plot_cmd << " , '' index 4 title 'Envelope' with lines "; + g1.cmd (plot_cmd.str ()); + g1.showonscreen (); // window output + geomtools::gnuplot_drawer::wait_for_key (); + usleep (200); + } + #endif } From b9aaeeb9bdef8ef3209e005ba4050ab73855dea1 Mon Sep 17 00:00:00 2001 From: Francois Mauger Date: Mon, 3 May 2021 09:20:23 +0200 Subject: [PATCH 2/7] Bump to version 3.5 and update release notes --- CMakeLists.txt | 2 +- cmake/BxPackageVersions.db | 3 +- release_notes.rst | 56 +++++++++++++++++++++++++++++++++----- 3 files changed, 52 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 58aceed70..274286a44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,7 +55,7 @@ include(BxVersionManager) # - Versioning only giving major and minor. Patch number is # automatically deduced from an external file. -bx_version_set(Bayeux 3 4) +bx_version_set(Bayeux 3 5) message(STATUS "[info] Project version = '${PROJECT_VERSION}'") #----------------------------------------------------------------------- diff --git a/cmake/BxPackageVersions.db b/cmake/BxPackageVersions.db index 353f4c340..169942ac0 100644 --- a/cmake/BxPackageVersions.db +++ b/cmake/BxPackageVersions.db @@ -4,6 +4,7 @@ 3.1.2 3.2.0 3.3.0 -3.4.5 +3.4.4 +3.5.0 #4.0.0 # end \ No newline at end of file diff --git a/release_notes.rst b/release_notes.rst index fda4f27a8..f6656045f 100644 --- a/release_notes.rst +++ b/release_notes.rst @@ -1,8 +1,8 @@ ============================= -Bayeux 3.4.5 Release Notes +Bayeux 3.5.0 Release Notes ============================= -Bayeux 3.4.5 adds some new features as well as fixes for reported issues. +Bayeux 3.5.0 adds some new features as well as fixes for reported issues. For information on changes made in previous versions, please see the `release notes archive`_. @@ -14,7 +14,7 @@ the `release notes archive`_. Requirements ============ -Bayeux 3.4.5 requires Linux (recommended Ubuntu >=18.04 (preferred +Bayeux 3.5.0 requires Linux (recommended Ubuntu >=18.04 (preferred 20.04), CentOS >=7.5), or macOS 10. @@ -35,15 +35,15 @@ Additions object (like in ``geomtools::model_with_internal_items_tools::plug_internal_models``). * Add ranking features in the datatools variant system. Some dedicated - metadata are parsed from any CSV file used for large enumeration of - string values for an enumerated string parameter. A few levels of UI + auxiliary data are parsed from any CSV file used for large enumeration of + string values for an enumerated string variant parameter. A few levels of UI ranking directives are available (``rank=highlight|first|second|third|last``). The variant GUI now provides a check box per variant registry panel to inhibit the display of values of *secondary* interest in combo boxes (for string parameters only). * Add support for ``GNUPLOT_DRAWER_DEBUG`` environment variable for - debugging in the ``geomtools::gnuplot_drawer``. + debug print from the ``geomtools::gnuplot_drawer``. Removals @@ -54,7 +54,49 @@ Changes ======= * Better support for model cleaning in ``geomtools::model_factory``. - +* The interface of the ``geomtools::i_model`` abstract class has been + changed. + + - the ``geomtools::i_model::_at_construct`` protected method has a + simpler signature. It does not use the model name parameter anymore, + because it was unused and confusing. All model classes have been + updated to take into account this interface change. + - the ``geomtools::i_model::_at_destroy`` and + ``geomtools::i_model::destroy`` methods have been added to fullfil + some possible needs at destruction stage in some geometry models. +* The ``geomtools::simple_shaped_model`` class has been refactored for + a better management of some internals for the tube, polycone and + polyhedra shapes when using the *filled_by_envelope* mode. It is + now possible to define some envelope geometrical tolerance and + automatically generate an envelope with some margins along the main + axis of the shape (X, Y, Z, radial...), typically at submicrometer + scale in the geometry setup, to avoid rounding issues during + tracking of particle (Geant4). The envelope can be defined by + inflation (default) of the contained shape, or by deflation of the + contained shape. This experimental feature is rather tricky to use + so it will need to be checked in real situations in Geant4 + (Falaise). Not all shapes can be addressed safely through this mechanism due + to the simplicity of topological approach used to build the envelope + by inflation or deflation of the contained shape. + + New properties are thus available from the model configuration. By + default, none of these properties are defined and the envelope is + build with zero margin with respect to the contained shape (tube, + polycone or polyhedra) : + + .. code:: + + filled_mode : string = "by_envelope" + envelope.tolerance.r : real as length = 0.1 um # Radial distance + envelope.tolerance.x : real as length = 0.1 um # X-axis distance + envelope.tolerance.y : real as length = 0.1 um # Y-axis distance + envelope.tolerance.z : real as length = 0.1 um # Z-axis distance + envelope.tolerance.phi : real as angle = 0.1 degree # Longitude angular tolerance + envelope.tolerance.theta : real as angle = 0.1 degree # Colatitude angular tolerance + envelope.deflated : boolean = false # Envelope defined by an inflated version + # of the contained shape outer bounds (default) + .. + Fixes ===== From 15edec43fb793140cef5f98739c0bac99880d1b1 Mon Sep 17 00:00:00 2001 From: Francois Mauger Date: Mon, 3 May 2021 09:20:50 +0200 Subject: [PATCH 3/7] Add a header include --- source/bxdatatools/include/datatools/properties.h | 1 + 1 file changed, 1 insertion(+) diff --git a/source/bxdatatools/include/datatools/properties.h b/source/bxdatatools/include/datatools/properties.h index 87c997737..468560862 100644 --- a/source/bxdatatools/include/datatools/properties.h +++ b/source/bxdatatools/include/datatools/properties.h @@ -48,6 +48,7 @@ // This Project: #include +#include #include #include #include From c2bd4a3c2be868745a4a71540b650aba0d04bb6f Mon Sep 17 00:00:00 2001 From: Francois Mauger Date: Sun, 9 May 2021 14:16:45 +0200 Subject: [PATCH 4/7] [geomtools] Add print option to tessallated_solid --- .../include/geomtools/tessellation.h | 13 ++ source/bxgeomtools/src/tessellation.cc | 118 ++++++++---------- 2 files changed, 66 insertions(+), 65 deletions(-) diff --git a/source/bxgeomtools/include/geomtools/tessellation.h b/source/bxgeomtools/include/geomtools/tessellation.h index f52c3187a..eefd879df 100644 --- a/source/bxgeomtools/include/geomtools/tessellation.h +++ b/source/bxgeomtools/include/geomtools/tessellation.h @@ -442,6 +442,13 @@ namespace geomtools { /// Check the validity bool is_valid() const override; + /// \brief Print options + enum tessella_print_option_type { + PRINT_VERTEXES = 0x1, + PRINT_SEGMENTS = 0x2, + PRINT_FACETS = 0x4 + }; + /// Smart print void tree_dump(std::ostream & a_out = std::clog, const std::string & a_title = "", @@ -498,6 +505,12 @@ namespace geomtools { /// Check internal data bool _check_(); + public: + + void set_full_print(); + + uint16_t print_options = 0; + private: bool _consistent_; //!< Flag to tag coherence of the tessellated solid diff --git a/source/bxgeomtools/src/tessellation.cc b/source/bxgeomtools/src/tessellation.cc index 6149319b1..1a936aa7b 100644 --- a/source/bxgeomtools/src/tessellation.cc +++ b/source/bxgeomtools/src/tessellation.cc @@ -1190,30 +1190,6 @@ namespace geomtools { return _zrange_.get_max(); } - // // virtual - // void tessellated_solid::compute_bounding_box(box & bb_) - // { - // this->i_object_3d::compute_bounding_box(bb_); - // if (_xrange_.is_valid() && _yrange_.is_valid() && _zrange_.is_valid()) { - // double x = std::abs(_xrange_.get_min()); - // if (std::abs(_xrange_.get_max()) > x) { - // x = std::abs(_xrange_.get_max()); - // } - // double y = std::abs(_yrange_.get_min()); - // if (std::abs(_yrange_.get_max()) > y) { - // y = std::abs(_yrange_.get_max()); - // } - // double z = std::abs(_zrange_.get_min()); - // if (std::abs(_zrange_.get_max()) > z) { - // z = std::abs(_zrange_.get_max()); - // } - // bb_.set_x(2 * x); - // bb_.set_y(2 * y); - // bb_.set_z(2 * z); - // } - // return; - // } - void tessellated_solid::compute_bounding_box() { _xrange_.reset(); @@ -1357,13 +1333,19 @@ namespace geomtools { // Remove the facet from the dictionnary of facets : //facet_found->second = 0; - _facets_.erase (facet_found); + _facets_.erase(facet_found); // Delete the facet : //delete the_facet_ptr; return; } + void tessellated_solid::set_full_print() + { + print_options = PRINT_VERTEXES | PRINT_SEGMENTS | PRINT_FACETS; + return; + } + void tessellated_solid::tree_dump(std::ostream & a_out, const std::string & a_title, const std::string & a_indent, @@ -1373,20 +1355,22 @@ namespace geomtools { a_out << a_indent << datatools::i_tree_dumpable::tag << "Vertices: " << _vertices_.size () << std::endl; - for (vertices_col_type::const_iterator i = _vertices_.begin (); - i != _vertices_.end (); - i++) { - a_out << a_indent << datatools::i_tree_dumpable::skip_tag; - { - vertices_col_type::const_iterator j = i; - if (++j == _vertices_.end ()) { - a_out << datatools::i_tree_dumpable::last_tag; - } else { - a_out << datatools::i_tree_dumpable::tag; + if (print_options & PRINT_VERTEXES) { + for (vertices_col_type::const_iterator i = _vertices_.begin (); + i != _vertices_.end (); + i++) { + a_out << a_indent << datatools::i_tree_dumpable::skip_tag; + { + vertices_col_type::const_iterator j = i; + if (++j == _vertices_.end ()) { + a_out << datatools::i_tree_dumpable::last_tag; + } else { + a_out << datatools::i_tree_dumpable::tag; + } } + a_out << "Vertex[" << i->first << "] : "; + i->second.print(a_out); } - a_out << "Vertex[" << i->first << "] : "; - i->second.print(a_out); } a_out << a_indent << datatools::i_tree_dumpable::tag @@ -1406,42 +1390,46 @@ namespace geomtools { a_out << a_indent << datatools::i_tree_dumpable::tag << "Facet segments: " << _facet_segments_.size() << std::endl; - for (facet_segments_col_type::const_iterator i = _facet_segments_.begin (); - i != _facet_segments_.end (); - i++) { - a_out << a_indent << datatools::i_tree_dumpable::skip_tag; - { - facet_segments_col_type::const_iterator j = i; - if (++j == _facet_segments_.end ()) { - a_out << datatools::i_tree_dumpable::last_tag; - } else { - a_out << datatools::i_tree_dumpable::tag; + if (print_options & PRINT_SEGMENTS) { + for (facet_segments_col_type::const_iterator i = _facet_segments_.begin (); + i != _facet_segments_.end (); + i++) { + a_out << a_indent << datatools::i_tree_dumpable::skip_tag; + { + facet_segments_col_type::const_iterator j = i; + if (++j == _facet_segments_.end ()) { + a_out << datatools::i_tree_dumpable::last_tag; + } else { + a_out << datatools::i_tree_dumpable::tag; + } } + a_out << "Facet segment[" << i->first << "] : "; + const facet_segment & fseg = i->second; + a_out << "from vertex [#" << fseg.vertex0_key << "] to vertex [#" + << fseg.vertex1_key << "] with facets [#" << fseg.facet0_key + << "/#" << fseg.facet1_key << "]" + << std::endl; } - a_out << "Facet segment[" << i->first << "] : "; - const facet_segment & fseg = i->second; - a_out << "from vertex [#" << fseg.vertex0_key << "] to vertex [#" - << fseg.vertex1_key << "] with facets [#" << fseg.facet0_key - << "/#" << fseg.facet1_key << "]" - << std::endl; } a_out << a_indent << datatools::i_tree_dumpable::inherit_tag(a_inherit) << "Facets: " << _facets_.size () << std::endl; - for (facets_col_type::const_iterator i = _facets_.begin (); - i != _facets_.end (); - i++) { - a_out << a_indent << datatools::i_tree_dumpable::inherit_skip_tag(a_inherit); - { - facets_col_type::const_iterator j = i; - if (++j == _facets_.end ()) { - a_out << datatools::i_tree_dumpable::last_tag; - } else { - a_out << datatools::i_tree_dumpable::tag; + if (print_options & PRINT_FACETS) { + for (facets_col_type::const_iterator i = _facets_.begin (); + i != _facets_.end (); + i++) { + a_out << a_indent << datatools::i_tree_dumpable::inherit_skip_tag(a_inherit); + { + facets_col_type::const_iterator j = i; + if (++j == _facets_.end ()) { + a_out << datatools::i_tree_dumpable::last_tag; + } else { + a_out << datatools::i_tree_dumpable::tag; + } } + a_out << "Facet[" << i->first << "] : "; + i->second.print(a_out); } - a_out << "Facet[" << i->first << "] : "; - i->second.print(a_out); } return; From 3390c44334ba1baa16b2fa248d9e946f0e0943b9 Mon Sep 17 00:00:00 2001 From: Francois Mauger Date: Sun, 9 May 2021 14:29:22 +0200 Subject: [PATCH 5/7] [geomtools] Force logical volume to 'shown' in the drawer --- source/bxgeomtools/src/gnuplot_drawer.cc | 28 +++++++++++++++++------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/source/bxgeomtools/src/gnuplot_drawer.cc b/source/bxgeomtools/src/gnuplot_drawer.cc index f4cba9678..b1abfc40a 100644 --- a/source/bxgeomtools/src/gnuplot_drawer.cc +++ b/source/bxgeomtools/src/gnuplot_drawer.cc @@ -572,6 +572,12 @@ namespace geomtools { shown = get_properties().fetch_boolean(force_show_property_name()); } + // Add 2021-05-05 (FM) + if (!shown) { + DT_LOG_DEBUG(local_priority, "force show flag for logical volume " << log_.get_name()); + shown = true; + } + // Default envelope visibility for the logical volume: if (visibility::is_hidden_envelope(log_visu_config)) { DT_LOG_DEBUG(local_priority, "found hidden envelope directive in log visu config"); @@ -793,7 +799,10 @@ namespace geomtools { DT_LOG_DEBUG(local_priority, "found hidden envelope directive in visu config (unused)"); //shown_envelope = false; } - + if (!shown) { + DT_LOG_DEBUG(local_priority, "force show flag for logical volume " << log_.get_name()); + shown = true; + } color::code_type color = color::COLOR_DEFAULT; color::code_type former_color = color::get_color(color::default_color()); if (visibility::has_color (visu_config)) { @@ -813,13 +822,16 @@ namespace geomtools { gnuplot_drawer::_draw_(log_, p_, max_display_level); } - _xrange_.min = BB.get_x_range().get_min (); - _xrange_.max = BB.get_x_range().get_max (); - _yrange_.min = BB.get_y_range().get_min (); - _yrange_.max = BB.get_y_range().get_max (); - _zrange_.min = BB.get_z_range().get_min (); - _zrange_.max = BB.get_z_range().get_max (); - + try { + _xrange_.min = BB.get_x_range().get_min (); + _xrange_.max = BB.get_x_range().get_max (); + _yrange_.min = BB.get_y_range().get_min (); + _yrange_.max = BB.get_y_range().get_max (); + _zrange_.min = BB.get_z_range().get_min (); + _zrange_.max = BB.get_z_range().get_max (); + } catch (std::exception & error) { + DT_THROW(std::logic_error, error.what()); + } double dx = _xrange_.max - _xrange_.min; double dy = _yrange_.max - _yrange_.min; double dz = _zrange_.max - _zrange_.min; From 408960c410ce4d7529cbbf0f3992ae3bceecb11d Mon Sep 17 00:00:00 2001 From: Francois Mauger Date: Sun, 9 May 2021 14:30:14 +0200 Subject: [PATCH 6/7] [geomtools] Minor mod --- source/bxgeomtools/src/gnuplot_draw.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/bxgeomtools/src/gnuplot_draw.cc b/source/bxgeomtools/src/gnuplot_draw.cc index ef9616758..306c4d216 100644 --- a/source/bxgeomtools/src/gnuplot_draw.cc +++ b/source/bxgeomtools/src/gnuplot_draw.cc @@ -141,7 +141,7 @@ namespace geomtools { { // std::cerr << "DEVEL: gnuplot_draw::bounding_box: Entering..." << std::endl; static boost::scoped_ptr _xyz_instance; - if (_xyz_instance.get() == 0 ) { + if (_xyz_instance.get() == nullptr ) { // std::cerr << "DEVEL: gnuplot_draw::bounding_box: Allocating a new BB..." << std::endl; _xyz_instance.reset(new gnuplot_draw::xyz_range); } From c7cd2b591d832f49ebe68e420088ea4030499aa1 Mon Sep 17 00:00:00 2001 From: Francois Mauger Date: Sun, 9 May 2021 14:30:52 +0200 Subject: [PATCH 7/7] [mygsl] Add missing default virtual dtor --- source/bxmygsl/include/mygsl/min_max.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/bxmygsl/include/mygsl/min_max.h b/source/bxmygsl/include/mygsl/min_max.h index f82a6139d..a708172f4 100644 --- a/source/bxmygsl/include/mygsl/min_max.h +++ b/source/bxmygsl/include/mygsl/min_max.h @@ -55,6 +55,9 @@ namespace mygsl { /// Default constructor min_max(); + /// Desctructor + ~min_max() override = default; + /// Reset void reset();