646 " no valid mother physical volume provided");
650 this->placement_configs_->mother = mother;
651 return this->shared_from_this();
655 template <
typename U>
656 DERIVED BASE::ForkAndReset(
const G4String &new_name)
const {
657 NoNameCheck(new_name,
"CopySolidBuilder");
659 copy->SetName(new_name);
660 copy->SetBooleanName(
"");
664 template <
typename U>
665 DERIVED BASE::ForkForFinalSolid(
const G4String &new_name) {
666 NoNameCheck(new_name,
"ForkForFinalSolid");
671 copy->SetName(new_name);
672 copy->SetBooleanName(
"");
674 copy->solid_ptr_.Link(this->solid_ptr_);
678 template <
typename U>
679 DERIVED BASE::ForkForLogicalVolume(
const G4String &new_name) {
680 NoNameCheck(new_name,
"ForkForLogicalVolume");
681 if (!final_solid_ptr_ && placement_configs_->is_builder) {
682 [[maybe_unused]]
auto discard = GetFinalSolid();
685 copy->SetName(new_name);
686 copy->SetBooleanName(
"");
688 if (solid_ptr_ && placement_configs_->is_builder) {
689 copy->solid_ptr_.Link(this->solid_ptr_);
691 if (final_solid_ptr_ && placement_configs_->is_builder) {
692 copy->final_solid_ptr_.Link(this->final_solid_ptr_);
697 template <
typename U>
698 DERIVED BASE::ForkForPlacement(std::optional<int> copy_no,
699 const G4String &name_override,
bool parent_name_was_set) {
701 if (!logicvol_ptr_ && placement_configs_->is_builder) {
705 copy->explicit_copyno_set_ =
static_cast<bool>(copy_no);
706 copy->explicit_physical_copy_name_set_ = !name_override.empty() || parent_name_was_set;
707 copy->placement_name_override_ = name_override;
709 copy->placement_configs_->copy_no = PlacementNameRegistry::IncrementNameCount(
710 GetPlacementBaseName());
712 copy->placement_configs_->copy_no = copy_no.value_or(copy->placement_configs_->copy_no);
715 copy->solid_ptr_.Link(this->solid_ptr_);
716 copy->final_solid_ptr_.Link(this->final_solid_ptr_);
717 copy->logicvol_ptr_.Link(this->logicvol_ptr_);
723 template <
typename U>
724 DERIVED BASE::SetAutoPlacementNaming(
const bool set) {
725 placement_configs_->auto_copy_name = set;
727 placement_configs_->auto_copyno =
false;
729 return this->shared_from_this();
732 template <
typename U>
734 placement_configs_->auto_copyno = set;
736 placement_configs_->auto_copy_name =
false;
738 return this->shared_from_this();
743 template <
typename U>
744 G4String BASE::GetPlacementBaseName()
const {
747 G4String base_name = boolean_configs_->boolean_name;
748 if (base_name.empty()) {
749 if (builder_configs_->name.empty()) {
750 if (placement_name_override_.empty()) {
751 throw std::runtime_error(
"Err in DLG4::VolumeBuilders::"
752 "for builder named: \"" + builder_configs_->name +
754 "GetPlacementBaseName\n"
755 "No names are defined. Cannot build");
757 base_name = placement_name_override_;
760 base_name = builder_configs_->name;
764 if (!placement_configs_->parent_name.empty()) {
765 base_name = placement_configs_->parent_name +
":" + base_name;
771 template <
typename U>
773 this->placement_configs_ = other->placement_configs_;
777 return this->shared_from_this();
780 template <
typename U>
784 auto name = this->builder_configs_->name;
785 auto booleans = this->boolean_configs_->booleans;
786 this->lv_configs_ = other->lv_configs_;
788 this->builder_configs_->name = name;
789 this->boolean_configs_->booleans = booleans;
790 return this->shared_from_this();
794 template <
typename U>
795 void BASE::make_persistent(
const std::shared_ptr<void> &obj) {
800 template <
typename U>
801 void BASE::ValidateSolidNotBuilt(
const std::string &operation)
const {
803 throw std::runtime_error(
"Cannot " + operation +
" - solid already built "
804 "for builder named: \"" + builder_configs_->name +
"\"\n"
809 template <
typename U>
810 void BASE::ValidateBooleanNotBuilt(
const std::string &operation)
const {
811 if (final_solid_ptr_) {
812 throw std::runtime_error(
"Cannot " + operation +
" - boolean already built!"
813 "for builder named: \"" + builder_configs_->name +
"\"\n"
818 template <
typename U>
819 void BASE::ValidateLogicalNotBuilt(
const std::string &operation)
const {
821 throw std::runtime_error(
"Cannot " + operation +
" - logical volume already built!"
822 "for builder named: \"" + builder_configs_->name +
"\"\n"
827 template <
typename U>
828 void BASE::ValidatePlacementNotBuilt(
const std::string &operation)
const {
830 throw std::runtime_error(
"Cannot " + operation +
" - placement already built!"
831 "for builder named: \"" + builder_configs_->name +
"\"\n"
839 template <
typename U>
840 void BASE::ValidateForPVBuild(std::string
const &site) {
842 throw std::runtime_error(
">>> Error in " + site +
" Physical Volume was already built\n"
843 "for builder named: \"" + builder_configs_->name +
"\"\n"
844 "Use ForkForPlacement to copy and rebuild.");
847 if (!logicvol_ptr_ && enable_full_lazy_builds && placement_configs_->is_builder) {
850 if (!logicvol_ptr_ && placement_configs_->is_builder) {
851 throw std::runtime_error(
852 "Error in " + site +
": LogicVolume is null after MakeLogicalVolume()."
853 "for builder named: \"" + builder_configs_->name +
"\"\n"
858 template <
typename U>
859 void BASE::ValidateForVolumeBuild(std::string
const &site) {
861 std::string error =
"Error in " + site +
" Booleans were already built\n"
862 "for builder named: \"" + builder_configs_->name +
"\"\n"
863 "You can copy and rename the builder to reset it and build again.\n";
864 throw std::runtime_error(error);
867 if (!final_solid_ptr_ && enable_full_lazy_builds && placement_configs_->is_builder) {
870 if (!final_solid_ptr_ && placement_configs_->is_builder) {
872 throw std::runtime_error(
873 "Error in ValidateForVolumeBuild from " + site +
874 "for builder named: \"" + builder_configs_->name +
"\"\n"
875 ": It's not possible to produce this error.");
879 template <
typename U>
880 void BASE::ValidateForBooleanBuild(std::string
const &site) {
881 if (final_solid_ptr_) {
882 std::string error =
"Error in " + site +
" A solid was already built\n"
883 "for builder named: \"" + builder_configs_->name +
"\"\n"
884 "You can copy and rename the builder to reset it and build again.";
885 throw std::runtime_error(error);
888 if (!solid_ptr_ && enable_full_lazy_builds && placement_configs_->is_builder) {
891 if (!solid_ptr_ && placement_configs_->is_builder) {
892 throw std::runtime_error(
"Error in " + site +
": "
893 "for builder named: \"" + builder_configs_->name +
"\"\n"
894 "Solid is null after MakeSolid().");
898 template <
typename U>
900 this->builder_configs_->default_unit = unit.
Native();
901 return this->shared_from_this();
904 template <
typename U>
906 auto temp = builder_configs_.get();
907 auto local = temp->default_unit;
909 auto global = DLG4::Units::global_default_unit<DLG4::Units::Length>;
910 G4double default_unit = local.value_or(global);
914 template <
typename U>
916 if (final_solid_ptr_) {
917 throw std::runtime_error(
"Error VolumeBuilderBase::ReflectZFinalSolid, \n"
918 "The final solid is already built. \n");
920 boolean_configs_->reflect_z =
true;
921 return this->shared_from_this();
924 template <
typename U>
926 if (final_solid_ptr_) {
927 throw std::runtime_error(
"Error VolumeBuilderBase::ReflectZBaseSolid, \n"
928 "The base solid is already built. \n");
930 builder_configs_->reflect_base_solid_z =
true;
931 return this->shared_from_this();
934 template <
typename U>
937 G4String final_name = GetBuilderName();
938 if (builder_configs_->reflect_base_solid_z) {
939 solid = SolidConstructor(final_name +
"_proto_solid");
940 solid =
new G4ReflectedSolid(final_name, solid, G4ReflectZ3D(0));
942 solid = SolidConstructor(final_name);
944 solid_ptr_.LinkToRaw(solid);
945 return this->shared_from_this();
951 template <
typename U>
957 template <
typename U>
958 void BASE::StoreIStructurePtr(
const IStructurePtr &istructure_ptr) {
960 builder_configs_->istructure_ptr =
IStructurePtr(istructure_ptr);
963 template <
typename U>
964 void BASE::StoreBuilderView(
const VolumeBuilder &builder_view) {
966 builder_configs_->builder_view = builder_view;
969 template <
typename U>
970 G4String BASE::GetBuilderName()
const {
971 return this->builder_configs_->name;
974 template <
typename U>
978 std::shared_ptr<U> builder_std_ptr =
979 std::const_pointer_cast<U>(this->shared_from_this());
980 auto x = DerivedPtr(builder_std_ptr);
984 template <
typename U>
987 std::shared_ptr<U> builder_std_ptr =
988 std::const_pointer_cast<U>(this->shared_from_this());
989 auto x = DerivedPtr(builder_std_ptr);
993 template <
typename U>
995 const U &derived_ref =
static_cast<const U &
>(*this);
996 auto retval =
new U(derived_ref);