|
|
|||
File indexing completed on 2026-05-10 08:39:32
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // Copyright (C) 2026 G4OCCT Contributors 0003 0004 /// @file G4OCCTAssemblyVolume.hh 0005 /// @brief Declaration of G4OCCTAssemblyVolume. 0006 0007 #ifndef G4OCCT_G4OCCTAssemblyVolume_hh 0008 #define G4OCCT_G4OCCTAssemblyVolume_hh 0009 0010 #include "G4OCCT/G4OCCTLogicalVolume.hh" 0011 #include "G4OCCT/G4OCCTMaterialMap.hh" 0012 #include "G4OCCT/G4OCCTSensitiveDetectorMap.hh" 0013 0014 #include <G4AssemblyVolume.hh> 0015 #include <G4String.hh> 0016 0017 // OCCT (forward-declared where possible; full includes in .cc) 0018 #include <TDF_Label.hxx> 0019 #include <gp_Trsf.hxx> 0020 0021 #include <map> 0022 #include <string> 0023 0024 /** 0025 * @brief Extends Geant4's G4AssemblyVolume with an OCCT XDE label reference. 0026 * 0027 * Imports a STEP assembly file using the OCCT Extended Data Exchange (XDE) 0028 * layer and constructs the corresponding Geant4 volume hierarchy. 0029 * 0030 * ## OCCT XDE to Geant4 mapping 0031 * 0032 * | XDE entity | Geant4 result | 0033 * |-------------------------------------|-------------------------------------| 0034 * | Top-level assembly label | `G4OCCTAssemblyVolume` (this class) | 0035 * | Simple-shape label (first use) | `G4OCCTSolid` + `G4OCCTLogicalVolume` | 0036 * | Simple-shape label (repeated use) | Shared `G4OCCTLogicalVolume` | 0037 * | Reference label + TopLoc_Location | `AddPlacedVolume()` on parent assembly | 0038 * | XDE name attribute | Volume name string | 0039 * | XDE material attribute (if present) | `G4Material*` via `G4OCCTMaterialMap` | 0040 * | Part name (fallback when no mat attr) | `G4Material*` via `G4OCCTMaterialMap` | 0041 * 0042 * ## Instance sharing 0043 * 0044 * When the same XDE shape label is referenced from multiple locations the 0045 * corresponding `G4OCCTLogicalVolume` is created only once and reused for 0046 * each placement (incrementing the copy number each time). This mirrors 0047 * Geant4's own convention. 0048 * 0049 * ## Thread safety 0050 * 0051 * This class constructs the Geant4 geometry during `FromSTEP()` and is 0052 * subsequently read-only. It inherits `G4AssemblyVolume`'s thread-safety 0053 * guarantees after construction. 0054 * 0055 * ## Usage 0056 * ```cpp 0057 * G4OCCTMaterialMap matMap; 0058 * matMap.Add("Al 6061-T6", G4NistManager::Instance()->FindOrBuildMaterial("G4_Al")); 0059 * 0060 * auto* assembly = G4OCCTAssemblyVolume::FromSTEP("detector.step", matMap); 0061 * 0062 * // In ConstructSDandField(): 0063 * G4OCCTSensitiveDetectorMap sdMap; 0064 * sdMap.Add("Absorber", myAbsoSD); 0065 * assembly->ApplySDMap(sdMap); 0066 * 0067 * // Imprint into the world logical volume 0068 * G4ThreeVector pos; 0069 * G4RotationMatrix rot; 0070 * assembly->MakeImprint(worldLV, pos, &rot); 0071 * ``` 0072 * 0073 * See docs/step_assembly_import.md for the full design and background. 0074 */ 0075 class G4OCCTAssemblyVolume : public G4AssemblyVolume { 0076 public: 0077 G4OCCTAssemblyVolume() = default; 0078 ~G4OCCTAssemblyVolume() = default; 0079 0080 /** 0081 * Import a STEP assembly file and construct the Geant4 volume hierarchy. 0082 * 0083 * Reads the STEP file at @p path using `STEPCAFControl_Reader` (the OCCT 0084 * XDE reader that preserves assembly structure, names, and material 0085 * attributes). The label tree is traversed depth-first; each simple-shape 0086 * leaf creates a `G4OCCTSolid` + `G4OCCTLogicalVolume`, and each placement 0087 * is recorded via `AddPlacedVolume()` on the top-level assembly. 0088 * 0089 * Every material name encountered in the STEP file must be present in 0090 * @p materialMap; an unresolved name triggers a fatal `G4Exception`. 0091 * When a shape carries no XDE material attribute, its part (label) name 0092 * is used as the lookup key instead, accommodating STEP writers that do 0093 * not write material attributes. 0094 * 0095 * The leaf shapes are recentered (bounding-box centroid moved to the OCCT 0096 * origin) before being wrapped in `G4OCCTSolid`; the recentering offset is 0097 * absorbed into the placement transformation so that parts appear at their 0098 * correct world positions. 0099 * 0100 * @param path Filesystem path to the STEP file. 0101 * @param materialMap Map from STEP material name or part name to `G4Material*`. 0102 * @return Pointer to a newly heap-allocated `G4OCCTAssemblyVolume` owned by 0103 * the caller. The returned object already contains all child 0104 * volumes; call `MakeImprint()` to place it in the world. 0105 * @throws std::runtime_error if the file cannot be read or yields no shapes. 0106 */ 0107 static G4OCCTAssemblyVolume* FromSTEP(const std::string& path, 0108 const G4OCCTMaterialMap& materialMap); 0109 0110 /** 0111 * Return all logical volumes created during import, keyed by part name. 0112 * 0113 * The map is populated during `FromSTEP()`. When two STEP parts share 0114 * the same name the later name is suffixed with `_<n>` so that every entry 0115 * is unique. 0116 */ 0117 const std::map<G4String, G4OCCTLogicalVolume*>& GetLogicalVolumes() const { 0118 return fLogicalVolumes; 0119 } 0120 0121 /** 0122 * Assign sensitive detectors to all logical volumes whose names match 0123 * entries in @p sdMap. 0124 * 0125 * Iterates all logical volumes created during `FromSTEP()` and calls 0126 * `sdMap.Resolve(name)` for each. When a non-null sensitive detector is 0127 * returned, `G4LogicalVolume::SetSensitiveDetector()` is called on the 0128 * corresponding logical volume. 0129 * 0130 * @param sdMap Map from volume-name patterns to sensitive detector pointers. 0131 * @return Number of logical volumes for which a sensitive detector was assigned. 0132 * 0133 * @note Call this from `G4VUserDetectorConstruction::ConstructSDandField()` 0134 * **after** both `FromSTEP()` and the SD objects have been created and 0135 * registered with `G4SDManager`. 0136 */ 0137 std::size_t ApplySDMap(const G4OCCTSensitiveDetectorMap& sdMap); 0138 0139 private: 0140 /// All G4OCCTLogicalVolume objects created during import, keyed by unique name. 0141 std::map<G4String, G4OCCTLogicalVolume*> fLogicalVolumes; 0142 0143 /// Build context passed through the recursive traversal. 0144 struct BuildContext; 0145 0146 /** 0147 * Recursively import an XDE label into the Geant4 hierarchy. 0148 * 0149 * @param label XDE label to import (assembly, simple shape, or reference). 0150 * @param parentAssembly Non-null assembly to add child volumes to; may be 0151 * @c this (the top-level) or an intermediate 0152 * `G4AssemblyVolume`. 0153 * @param composedTrsf Accumulated rigid-body transformation from the root 0154 * to this label's coordinate frame. 0155 * @param ctx Mutable build context (prototype map, copy counter, …). 0156 */ 0157 static void ImportLabel(const TDF_Label& label, G4AssemblyVolume* parentAssembly, 0158 const gp_Trsf& composedTrsf, BuildContext& ctx); 0159 }; 0160 0161 #endif // G4OCCT_G4OCCTAssemblyVolume_hh
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|