G4OCCT 0.1.0
Geant4 interface to Open CASCADE Technology (OCCT) geometry definitions
Loading...
Searching...
No Matches
main.cc
Go to the documentation of this file.
1// SPDX-License-Identifier: LGPL-2.1-or-later
2// Copyright (C) 2026 G4OCCT Contributors
3
15
18
19#include <FTFP_BERT.hh>
20#include <G4RunManagerFactory.hh>
21#include <G4UIExecutive.hh>
22#include <G4UIcommand.hh>
23#include <G4UImanager.hh>
24#include <G4VisExecutive.hh>
25
26#include <algorithm>
27#include <cctype>
28#include <string>
29#include <vector>
30
31namespace {
32
33void PrintUsage(const char* prog) {
34 G4cerr << "Usage: " << prog
35 << " [-m macro] [-u UIsession] [-t nThreads]"
36 " [file.step|file.stp ...] [file.xml ...]"
37 << G4endl;
38 G4cerr << " -m macro Execute Geant4 macro file (batch mode)." << G4endl;
39 G4cerr << " -u UIsession Select UI session (Qt, Xm, tcsh, …)." << G4endl;
40 G4cerr << " -t nThreads Number of worker threads (multi-threaded builds only)." << G4endl;
41 G4cerr << " file.step Load STEP file (solid or assembly, auto-detected)." << G4endl;
42 G4cerr << " file.xml Load G4OCCT material-map XML file." << G4endl;
43}
44
46std::string FileExtension(const std::string& path) {
47 auto dot = path.rfind('.');
48 if (dot == std::string::npos)
49 return {};
50 std::string ext = path.substr(dot);
51 std::transform(ext.begin(), ext.end(), ext.begin(),
52 [](unsigned char c) { return std::tolower(c); });
53 return ext;
54}
55
56} // namespace
57
58int main(int argc, char** argv) {
59 G4String macro;
60 G4String session;
61#ifdef G4MULTITHREADED
62 G4int nThreads = 0;
63#endif
64 std::vector<std::string> stepFiles;
65 std::vector<std::string> materialFiles;
66
67 // ── Parse arguments ────────────────────────────────────────────────────────
68 for (G4int i = 1; i < argc; ++i) {
69 const std::string arg(argv[i]);
70
71 if (arg == "-m") {
72 if (++i >= argc) {
73 PrintUsage(argv[0]);
74 return 1;
75 }
76 macro = argv[i];
77 } else if (arg == "-u") {
78 if (++i >= argc) {
79 PrintUsage(argv[0]);
80 return 1;
81 }
82 session = argv[i];
83 } else if (arg == "-t") {
84 // Require an explicit value for -t in all builds, and ensure we don't
85 // accidentally treat the next option token (e.g. "-m") as that value.
86 if (i + 1 >= argc) {
87 PrintUsage(argv[0]);
88 return 1;
89 }
90 const std::string nextArg(argv[i + 1]);
91 if (nextArg[0] == '-') {
92 PrintUsage(argv[0]);
93 return 1;
94 }
95 ++i; // move to the value for -t
96#ifdef G4MULTITHREADED
97 nThreads = G4UIcommand::ConvertToInt(argv[i]);
98#else
99 G4cerr << "Warning: -t option (" << argv[i]
100 << ") ignored (Geant4 built without multi-threading)." << G4endl;
101#endif
102 } else if (arg[0] == '-') {
103 G4cerr << "Unknown option: " << arg << G4endl;
104 PrintUsage(argv[0]);
105 return 1;
106 } else {
107 // Positional argument — classify by extension
108 const auto ext = FileExtension(arg);
109 if (ext == ".step" || ext == ".stp") {
110 stepFiles.push_back(arg);
111 } else if (ext == ".xml") {
112 materialFiles.push_back(arg);
113 } else {
114 G4cerr << "Unrecognised file type (expected .step, .stp, or .xml): " << arg << G4endl;
115 PrintUsage(argv[0]);
116 return 1;
117 }
118 }
119 }
120
121 // ── Interactive mode: create UI executive before run manager ──────────────
122 G4UIExecutive* ui = nullptr;
123 if (macro.empty()) {
124 ui = new G4UIExecutive(argc, argv, session);
125 }
126
127 // ── Run manager ───────────────────────────────────────────────────────────
128 auto* runManager = G4RunManagerFactory::CreateRunManager(G4RunManagerType::Default);
129#ifdef G4MULTITHREADED
130 if (nThreads > 0) {
131 runManager->SetNumberOfThreads(nThreads);
132 }
133#endif
134
135 // ── Detector construction ─────────────────────────────────────────────────
136 auto* detConstruction = new G4OCCTDetectorConstruction;
137
138 // Pre-load material maps so they are available when Construct() is called.
139 for (const auto& f : materialFiles) {
140 detConstruction->LoadMaterial(f);
141 }
142 // Queue STEP files for loading during Construct().
143 for (const auto& f : stepFiles) {
144 detConstruction->AddSTEP(f);
145 }
146
147 runManager->SetUserInitialization(detConstruction);
148 runManager->SetUserInitialization(new FTFP_BERT(/*verbosity=*/0));
149 runManager->SetUserInitialization(new G4OCCTActionInitialization);
150
151 // ── Visualisation ─────────────────────────────────────────────────────────
152 // Only initialize vis in interactive mode; batch runs don't require it and
153 // may run in environments without display/vis support.
154 G4VisExecutive* visManager = nullptr;
155 if (ui != nullptr) {
156 visManager = new G4VisExecutive("Quiet");
157 visManager->Initialize();
158 }
159
160 // ── Macro search path ─────────────────────────────────────────────────────
161 // Register the installed data directory first, then the build-tree copy.
162 // This satisfies both `make install` users and in-tree development/testing.
163 auto* UImanager = G4UImanager::GetUIpointer();
164 UImanager->SetMacroSearchPath(G4String(G4OCCT_MACRO_DIR_INSTALL) + ":" + G4OCCT_MACRO_DIR_BUILD);
165
166 // ── Execute macro or start interactive session ────────────────────────────
167 int exitCode = 0;
168
169 if (!macro.empty()) {
170 exitCode = UImanager->ApplyCommand("/control/execute " + macro);
171 } else {
172 UImanager->ApplyCommand("/control/execute init_vis.mac");
173 if (ui->IsGUI()) {
174 UImanager->ApplyCommand("/control/execute gui.mac");
175 }
176 ui->SessionStart();
177 delete ui;
178 }
179
180 delete visManager;
181 delete runManager;
182 return exitCode != 0 ? 1 : 0;
183}
Minimal user action initialisation for the g4occt executable.
Dynamic detector construction for the g4occt interactive tool.
Action initialisation for the g4occt interactive tool.
Dynamically constructs a Geant4 world from STEP solids and assemblies.
void LoadMaterial(G4String xmlFile)
Queue a material-map XML file to be loaded at construction time.
int main(int argc, char **argv)
Definition main.cc:58