1 | <HTML> |
---|
2 | <TITLE>Controlling Visualization from Compiled Code |
---|
3 | </TITLE> |
---|
4 | <!-- Changed by: Katsuya Dosanjh, 15-Jul-2000 --> |
---|
5 | <!-- Changed by: Dennis Wright, 27-Nov-2001 --> |
---|
6 | |
---|
7 | |
---|
8 | <!-- Proof read by: Joe Chuma, 6-Jul-1999 --> |
---|
9 | |
---|
10 | <!-- --> |
---|
11 | <!-- *spell, *tag, *contents, *s --> |
---|
12 | <BODY> |
---|
13 | |
---|
14 | <TABLE WIDTH="100%" > |
---|
15 | <TR> |
---|
16 | <TD> |
---|
17 | </A> |
---|
18 | <A HREF="index.html"> |
---|
19 | <IMG SRC="../../../../resources/html/IconsGIF/Contents.gif" ALT="Contents" HEIGHT=16 WIDTH=59></A> |
---|
20 | <A HREF="commandcontrol.html"> |
---|
21 | <IMG SRC="../../../../resources/html/IconsGIF/Previous.gif" ALT="Previous" HEIGHT=16 WIDTH=59></A> |
---|
22 | <a href="attributes.html"> |
---|
23 | <IMG SRC="../../../../resources/html/IconsGIF/Next.gif" ALT="Next" HEIGHT=16 WIDTH=59></a> |
---|
24 | </TD> |
---|
25 | |
---|
26 | <TD ALIGN="Right"><FONT COLOR="#238E23"><FONT SIZE=-1> |
---|
27 | <B>Geant4 User's Guide</B> <BR> |
---|
28 | <B>For Application Developers</B> <BR> |
---|
29 | <B>Visualization</B> </FONT></FONT> </TD> |
---|
30 | </TR> |
---|
31 | </TABLE> |
---|
32 | |
---|
33 | <CENTER><FONT COLOR="#238E23"><FONT SIZE=+3> |
---|
34 | <b>8.5 Controlling Visualization from Compiled Code</b><BR> |
---|
35 | </FONT></FONT></CENTER> |
---|
36 | <BR> |
---|
37 | |
---|
38 | <HR ALIGN="Center" SIZE="7%"><BR> |
---|
39 | |
---|
40 | While a Geant4 simulation is running, visualization can be performed without |
---|
41 | user intervention. This is accomplished by calling methods of the |
---|
42 | Visualization Manager from methods of the user action classes |
---|
43 | (<i>G4UserRunAction</i> and <i>G4UserEventAction</i>, for example). |
---|
44 | In this section methods of the class <i>G4VVisManager</i>, which is part of |
---|
45 | the <tt>graphics_reps</tt> category, are described and examples of their use are |
---|
46 | given. |
---|
47 | |
---|
48 | |
---|
49 | <h4>8.5.1 Class <i>G4VVisManager</i></h4> |
---|
50 | |
---|
51 | The Visualization Manager is implemented by classes <i>G4VisManager</i> and |
---|
52 | <i>G4VisExecutive</i>. See Section 8.2 "<b>Making a Visualization Executable</b>". |
---|
53 | In order that your Geant4 be compilable either with or without the visualization |
---|
54 | category, you should not use these classes directly in your C++ source code, |
---|
55 | other than in the <tt>main()</tt> function. |
---|
56 | Instead, you should use their abstract base class <i>G4VVisManager</i>, defined in |
---|
57 | the <tt>intercoms</tt> category. |
---|
58 | <P> |
---|
59 | The pointer to the concrete instance of the real |
---|
60 | Visualization Manager can be obtained as follows: |
---|
61 | <PRE> |
---|
62 | //----- Getting a pointer to the concrete Visualization Manager instance |
---|
63 | G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance(); |
---|
64 | </PRE> |
---|
65 | <P> |
---|
66 | The method <tt>G4VVisManager::GetConcreteInstance()</tt> returns <tt>NULL</tt> if Geant4 is |
---|
67 | not ready for visualization. Thus your C++ source code should be protected as follows: |
---|
68 | <PRE> |
---|
69 | //----- How to protect your C++ source codes in visualization |
---|
70 | if (pVVisManager) { |
---|
71 | .... |
---|
72 | pVVisManager ->Draw (...); |
---|
73 | .... |
---|
74 | } |
---|
75 | </PRE> |
---|
76 | <P> |
---|
77 | |
---|
78 | <P> |
---|
79 | |
---|
80 | <h4>8.5.2 Visualization of detector components</h4> |
---|
81 | |
---|
82 | If you have already constructed detector components with logical volumes |
---|
83 | to which visualization attributes are properly assigned, you are almost ready |
---|
84 | for visualizing detector components. |
---|
85 | All you have to do is to describe proper visualization commands |
---|
86 | within your C++ codes, using the <tt>ApplyCommand()</tt> method. |
---|
87 | |
---|
88 | <P> |
---|
89 | For example, |
---|
90 | the following is sample C++ source codes |
---|
91 | to visualize the detector components: |
---|
92 | <PRE> |
---|
93 | //----- C++ source code: How to visualize detector components (2) |
---|
94 | // ... using visualization commands in source codes |
---|
95 | |
---|
96 | G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance() ; |
---|
97 | |
---|
98 | if(pVVisManager) |
---|
99 | { |
---|
100 | ... (camera setting etc) ... |
---|
101 | G4UImanager::GetUIpointer()->ApplyCommand("/vis/drawVolume"); |
---|
102 | G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/flush"); |
---|
103 | } |
---|
104 | |
---|
105 | //----- end of C++ source code |
---|
106 | </PRE> |
---|
107 | In the above, you should also describe |
---|
108 | <tt>/vis/open</tt> command somewhere in your C++ codes or |
---|
109 | execute the command from (G)UI at the executing stage. |
---|
110 | <P> |
---|
111 | |
---|
112 | <h4>8.5.3 Visualization of trajectories</h4> |
---|
113 | |
---|
114 | In order to visualize trajectories, you can use the method |
---|
115 | <tt>void G4Trajectory::DrawTrajectory()</tt> defined in the tracking |
---|
116 | category. |
---|
117 | In the implementation of this method, the following drawing method of |
---|
118 | <i>G4VVisManager</i> is used: |
---|
119 | <PRE> |
---|
120 | //----- A drawing method of G4Polyline |
---|
121 | virtual void G4VVisManager::Draw (const G4Polyline&, ...) ; |
---|
122 | </PRE> |
---|
123 | The real implementation of this method is described in the class <i>G4VisManager</i>. |
---|
124 | <P> |
---|
125 | At the end of one event, a set of trajectories can be stored as a list of |
---|
126 | <i>G4Trajectory</i> objects. |
---|
127 | Therefore you can visualize trajectories, for example, at the end of each event, |
---|
128 | by implementing the method <tt>MyEventAction::EndOfEventAction()</tt> as follows: |
---|
129 | <PRE> |
---|
130 | //----- C++ source codes |
---|
131 | void ExN03EventAction::EndOfEventAction(const G4Event* evt) |
---|
132 | { |
---|
133 | ..... |
---|
134 | // extract the trajectories and draw them |
---|
135 | if (G4VVisManager::GetConcreteInstance()) |
---|
136 | { |
---|
137 | G4TrajectoryContainer* trajectoryContainer = evt->GetTrajectoryContainer(); |
---|
138 | G4int n_trajectories = 0; |
---|
139 | if (trajectoryContainer) n_trajectories = trajectoryContainer->entries(); |
---|
140 | |
---|
141 | for (G4int i=0; i < n_trajectories; i++) |
---|
142 | { G4Trajectory* trj=(G4Trajectory*)((*(evt->GetTrajectoryContainer()))[i]); |
---|
143 | if (drawFlag == "all") trj->DrawTrajectory(50); |
---|
144 | else if ((drawFlag == "charged")&&(trj->GetCharge() != 0.)) |
---|
145 | trj->DrawTrajectory(50); |
---|
146 | else if ((drawFlag == "neutral")&&(trj->GetCharge() == 0.)) |
---|
147 | trj->DrawTrajectory(50); |
---|
148 | } |
---|
149 | } |
---|
150 | } |
---|
151 | //----- end of C++ source codes |
---|
152 | </PRE> |
---|
153 | |
---|
154 | <P> |
---|
155 | <h4>8.5.4 Enhanced trajectory drawing</h4> |
---|
156 | It is possible to use the enhanced trajectory drawing functionality in compiled code as well as from commands. |
---|
157 | Multiple trajectory models can be instantiated, configured and registered with G4VisManager. |
---|
158 | For details, see the section on <A HREF="enhanceddrawing.html#compiledcontrol">Enhanced Trajectory Drawing</a>. |
---|
159 | |
---|
160 | <h4>8.5.5 HepRep Attributes for Trajectories</h4> |
---|
161 | The HepRep file formats, HepRepFile and HepRepXML, attach various attributes to trajectories |
---|
162 | such that you can view these attributes, label trajectories by these attributes |
---|
163 | or make visibility cuts based on these attributes. |
---|
164 | If you use the default Geant4 trajectory class, from /tracking/src/G4Trajectory.cc, |
---|
165 | available attributes will be: |
---|
166 | <UL> |
---|
167 | <LI>Track ID</li> |
---|
168 | <LI>Parent ID</li> |
---|
169 | <LI>Particle Name</li> |
---|
170 | <LI>Charge</li> |
---|
171 | <LI>PDG Encoding</li> |
---|
172 | <LI>Momentum 3-Vector</li> |
---|
173 | <LI>Momentum magnitude</li> |
---|
174 | <LI>Number of points</li> |
---|
175 | </UL> |
---|
176 | You can add additional attributes of your choosing by modifying the relevant part of G4Trajectory |
---|
177 | (look for the methods GetAttDefs and CreateAttValues). |
---|
178 | If you are using your own trajectory class, |
---|
179 | you may want to consider copying these methods from G4Trajectory. |
---|
180 | |
---|
181 | <h4>8.5.6 Visualization of hits</h4> |
---|
182 | |
---|
183 | Hits are visualized with classes <i>G4Square</i> or <i>G4Circle</i>, or other |
---|
184 | user-defined classes inheriting the abstract base class <i>G4VMarker</i>. |
---|
185 | Drawing methods for hits are not supported by default. |
---|
186 | Instead, ways of their implementation are guided by virtual methods, |
---|
187 | <tt>G4VHit::Draw()</tt> and <tt>G4VHitsCollection::DrawAllHits()</tt>, of the |
---|
188 | abstract base classes <i>G4VHit</i> and <i>G4VHitsCollection</i>. |
---|
189 | These methods are defined as empty functions in the <tt>digits+hits</tt> category. |
---|
190 | You can overload these methods, using the following drawing methods of class |
---|
191 | <i>G4VVisManager</i>, in order to visualize hits: |
---|
192 | <PRE> |
---|
193 | //----- Drawing methods of G4Square and G4Circle |
---|
194 | virtual void G4VVisManager::Draw (const G4Circle&, ...) ; |
---|
195 | virtual void G4VVisManager::Draw (const G4Square&, ...) ; |
---|
196 | </PRE> |
---|
197 | The real implementations of these <tt>Draw()</tt> methods are described in class |
---|
198 | <i>G4VisManager</i>. |
---|
199 | <P> |
---|
200 | The overloaded implementation of <tt>G4VHits::Draw()</tt> will be held by, for example, |
---|
201 | class <i>MyTrackerHits</i> inheriting <i>G4VHit</i> as follows: |
---|
202 | <PRE> |
---|
203 | //----- C++ source codes: An example of giving concrete implementation of |
---|
204 | // G4VHit::Draw(), using class MyTrackerHit : public G4VHit {...} |
---|
205 | // |
---|
206 | void MyTrackerHit::Draw() |
---|
207 | { |
---|
208 | G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance(); |
---|
209 | if(pVVisManager) |
---|
210 | { |
---|
211 | // define a circle in a 3D space |
---|
212 | G4Circle circle(pos); |
---|
213 | circle.SetScreenSize(0.3); |
---|
214 | circle.SetFillStyle(G4Circle::filled); |
---|
215 | |
---|
216 | // make the circle red |
---|
217 | G4Colour colour(1.,0.,0.); |
---|
218 | G4VisAttributes attribs(colour); |
---|
219 | circle.SetVisAttributes(attribs); |
---|
220 | |
---|
221 | // make a 3D data for visualization |
---|
222 | pVVisManager->Draw(circle); |
---|
223 | } |
---|
224 | } |
---|
225 | |
---|
226 | //----- end of C++ source codes |
---|
227 | </PRE> |
---|
228 | <P> |
---|
229 | The overloaded implementation of <tt>G4VHitsCollection::DrawAllHits()</tt> will be held |
---|
230 | by, for example, class <i>MyTrackerHitsCollection</i> inheriting class |
---|
231 | <i>G4VHitsCollection</i> as follows: |
---|
232 | <PRE> |
---|
233 | //----- C++ source codes: An example of giving concrete implementation of |
---|
234 | // G4VHitsCollection::Draw(), |
---|
235 | // using class MyTrackerHit : public G4VHitsCollection{...} |
---|
236 | // |
---|
237 | void MyTrackerHitsCollection::DrawAllHits() |
---|
238 | { |
---|
239 | G4int n_hit = theCollection.entries(); |
---|
240 | for(G4int i=0;i < n_hit;i++) |
---|
241 | { |
---|
242 | theCollection[i].Draw(); |
---|
243 | } |
---|
244 | } |
---|
245 | |
---|
246 | //----- end of C++ source codes |
---|
247 | </PRE> |
---|
248 | <P> |
---|
249 | Thus, you can visualize hits as well as trajectories, for example, |
---|
250 | at the end of each event by implementing the method |
---|
251 | <tt>MyEventAction::EndOfEventAction()</tt> as follows: |
---|
252 | <PRE> |
---|
253 | void MyEventAction::EndOfEventAction() |
---|
254 | { |
---|
255 | const G4Event* evt = fpEventManager->get_const_currentEvent(); |
---|
256 | |
---|
257 | G4SDManager * SDman = G4SDManager::get_SDMpointer(); |
---|
258 | G4String colNam; |
---|
259 | G4int trackerCollID = SDman->get_collectionID(colNam="TrackerCollection"); |
---|
260 | G4int calorimeterCollID = SDman->get_collectionID(colNam="CalCollection"); |
---|
261 | |
---|
262 | G4TrajectoryContainer * trajectoryContainer = evt->get_trajectoryContainer(); |
---|
263 | G4int n_trajectories = 0; |
---|
264 | if(trajectoryContainer) |
---|
265 | { n_trajectories = trajectoryContainer->entries(); } |
---|
266 | |
---|
267 | G4HCofThisEvent * HCE = evt->get_HCofThisEvent(); |
---|
268 | G4int n_hitCollection = 0; |
---|
269 | if(HCE) |
---|
270 | { n_hitCollection = HCE->get_capacity(); } |
---|
271 | |
---|
272 | G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance(); |
---|
273 | |
---|
274 | if(pVVisManager) |
---|
275 | { |
---|
276 | |
---|
277 | // Declare begininng of visualization |
---|
278 | G4UImanager::GetUIpointer()->ApplyCommand("/vis/scene/notifyHandlers"); |
---|
279 | |
---|
280 | // Draw trajectories |
---|
281 | for(G4int i=0; i < n_trajectories; i++) |
---|
282 | { |
---|
283 | (*(evt->get_trajectoryContainer()))[i]->DrawTrajectory(); |
---|
284 | } |
---|
285 | |
---|
286 | // Construct 3D data for hits |
---|
287 | MyTrackerHitsCollection* THC |
---|
288 | = (MyTrackerHitsCollection*)(HCE->get_HC(trackerCollID)); |
---|
289 | if(THC) THC->DrawAllHits(); |
---|
290 | MyCalorimeterHitsCollection* CHC |
---|
291 | = (MyCalorimeterHitsCollection*)(HCE->get_HC(calorimeterCollID)); |
---|
292 | if(CHC) CHC->DrawAllHits(); |
---|
293 | |
---|
294 | // Declare end of visualization |
---|
295 | G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/update"); |
---|
296 | |
---|
297 | } |
---|
298 | |
---|
299 | } |
---|
300 | |
---|
301 | //----- end of C++ codes |
---|
302 | </PRE> |
---|
303 | <P> |
---|
304 | You can re-visualize a physical volume, where a hit is detected, with a highlight |
---|
305 | color, in addition to the whole set of detector components. It is done by calling a |
---|
306 | drawing method of a physical volume directly. The method is: |
---|
307 | <PRE> |
---|
308 | //----- Drawing methods of a physical volume |
---|
309 | virtual void Draw (const G4VPhysicalVolume&, ...) ; |
---|
310 | </PRE> |
---|
311 | <P> |
---|
312 | This method is, for example, called in a method <tt>MyXXXHit::Draw()</tt>, describing |
---|
313 | the visualization of hits with markers. The following is an example for this: |
---|
314 | <PRE> |
---|
315 | //----- C++ source codes: An example of visualizing hits with |
---|
316 | void MyCalorimeterHit::Draw() |
---|
317 | { |
---|
318 | G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance(); |
---|
319 | if(pVVisManager) |
---|
320 | { |
---|
321 | G4Transform3D trans(rot,pos); |
---|
322 | G4VisAttributes attribs; |
---|
323 | G4LogicalVolume* logVol = pPhys->GetLogicalVolume(); |
---|
324 | const G4VisAttributes* pVA = logVol->GetVisAttributes(); |
---|
325 | if(pVA) attribs = *pVA; |
---|
326 | G4Colour colour(1.,0.,0.); |
---|
327 | attribs.SetColour(colour); |
---|
328 | attribs.SetForceSolid(true); |
---|
329 | |
---|
330 | //----- Re-visualization of a selected physical volume with red color |
---|
331 | pVVisManager->Draw(*pPhys,attribs,trans); |
---|
332 | |
---|
333 | } |
---|
334 | } |
---|
335 | |
---|
336 | //----- end of C++ codes |
---|
337 | </PRE> |
---|
338 | <P> |
---|
339 | |
---|
340 | <h4>8.5.7 HepRep Attributes for Hits</h4> |
---|
341 | The HepRep file formats, HepRepFile and HepRepXML, attach various attributes to hits |
---|
342 | such that you can view these attributes, label trajectories by these attributes |
---|
343 | or make visibility cuts based on these attributes. |
---|
344 | Examples of adding HepRep attributes to hit classes can be found in examples |
---|
345 | /extended/analysis/A01 and /extended/runAndEvent/RE01. |
---|
346 | <P> |
---|
347 | For example, in example RE01's class RE01CalorimeterHit.cc, |
---|
348 | available attributes will be: |
---|
349 | <UL> |
---|
350 | <LI>Hit Type</li> |
---|
351 | <LI>Track ID</li> |
---|
352 | <LI>Z Cell ID</li> |
---|
353 | <LI>Phi Cell ID</li> |
---|
354 | <LI>Energy Deposited</li> |
---|
355 | <LI>Energy Deposited by Track</li> |
---|
356 | <LI>Position</li> |
---|
357 | <LI>Logical Volume</li> |
---|
358 | </UL> |
---|
359 | You can add additional attributes of your choosing by modifying the relevant part of the hit class |
---|
360 | (look for the methods GetAttDefs and CreateAttValues). |
---|
361 | |
---|
362 | <h4>8.5.8 Visualization of text</h4> |
---|
363 | |
---|
364 | In Geant4 Visualization, a text, i.e., a character string, is described by class |
---|
365 | <i>G4Text</i> inheriting <i>G4VMarker</i> as well as <i>G4Square</i> and <i>G4Circle</i>. |
---|
366 | Therefore, the way to visualize text is the same as for hits. |
---|
367 | The corresponding drawing method of <i>G4VVisManager</i> is: |
---|
368 | <PRE> |
---|
369 | //----- Drawing methods of G4Text |
---|
370 | virtual void G4VVisManager::Draw (const G4Text&, ...); |
---|
371 | </PRE> |
---|
372 | The real implementation of this method is described in class <i>G4VisManager</i>. |
---|
373 | <P> |
---|
374 | |
---|
375 | <h4>8.5.9 Visualization of polylines and tracking steps</h4> |
---|
376 | |
---|
377 | Polylines, i.e., sets of successive line segments, are described by class |
---|
378 | <i>G4Polyline</i>. For <i>G4Polyline</i>, the following drawing method of |
---|
379 | class <i>G4VVisManager</i> is prepared: |
---|
380 | <PRE> |
---|
381 | //----- A drawing method of G4Polyline |
---|
382 | virtual void G4VVisManager::Draw (const G4Polyline&, ...) ; |
---|
383 | </PRE> |
---|
384 | The real implementation of this method is described in class <i>G4VisManager</i>. |
---|
385 | <P> |
---|
386 | Using this method, C++ source codes to visualize <i>G4Polyline</i> are described |
---|
387 | as follows: |
---|
388 | <PRE> |
---|
389 | //----- C++ source code: How to visualize a polyline |
---|
390 | G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance(); |
---|
391 | |
---|
392 | if (pVVisManager) { |
---|
393 | G4Polyline polyline ; |
---|
394 | |
---|
395 | ..... (C++ source codes to set vertex positions, color, etc) |
---|
396 | |
---|
397 | pVVisManager -> Draw(polyline); |
---|
398 | |
---|
399 | } |
---|
400 | |
---|
401 | //----- end of C++ source codes |
---|
402 | </PRE> |
---|
403 | <P> |
---|
404 | Tracking steps are able to be visualized based on the above visualization of |
---|
405 | <i>G4Polyline</i>. You can visualize tracking steps at each step automatically |
---|
406 | by writing a proper implementation of class <i>MySteppingAction</i> inheriting |
---|
407 | <i>G4UserSteppingAction</i>, and also with the help of the Run Manager. |
---|
408 | <P> |
---|
409 | First, you must implement a method, <tt>MySteppingAction::UserSteppingAction()</tt>. |
---|
410 | A typical implementation of this method is as follows: |
---|
411 | <PRE> |
---|
412 | //----- C++ source code: An example of visualizing tracking steps |
---|
413 | void MySteppingAction::UserSteppingAction() |
---|
414 | { |
---|
415 | G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance(); |
---|
416 | |
---|
417 | if (pVVisManager) { |
---|
418 | |
---|
419 | //----- Get the Stepping Manager |
---|
420 | const G4SteppingManager* pSM = GetSteppingManager(); |
---|
421 | |
---|
422 | //----- Define a line segment |
---|
423 | G4Polyline polyline; |
---|
424 | G4double charge = pSM->GetTrack()->GetDefinition()->GetPDGCharge(); |
---|
425 | G4Colour colour; |
---|
426 | if (charge < 0.) colour = G4Colour(1., 0., 0.); |
---|
427 | else if (charge < 0.) colour = G4Colour(0., 0., 1.); |
---|
428 | else colour = G4Colour(0., 1., 0.); |
---|
429 | G4VisAttributes attribs(colour); |
---|
430 | polyline.SetVisAttributes(attribs); |
---|
431 | polyline.push_back(pSM->GetStep()->GetPreStepPoint()->GetPosition()); |
---|
432 | polyline.push_back(pSM->GetStep()->GetPostStepPoint()->GetPosition()); |
---|
433 | |
---|
434 | //----- Call a drawing method for G4Polyline |
---|
435 | pVVisManager -> Draw(polyline); |
---|
436 | |
---|
437 | } |
---|
438 | } |
---|
439 | |
---|
440 | //----- end of C++ source code |
---|
441 | </PRE> |
---|
442 | <P> |
---|
443 | Next, in order that the above C++ source code works, you have to pass |
---|
444 | the information of the <i>MySteppingAction</i> to the Run Manager in the <tt>main()</tt> function: |
---|
445 | <PRE> |
---|
446 | //----- C++ source code: Passing what to do at each step to the Run Manager |
---|
447 | |
---|
448 | int main() |
---|
449 | { |
---|
450 | ... |
---|
451 | |
---|
452 | // Run Manager |
---|
453 | G4RunManager * runManager = new G4RunManager; |
---|
454 | |
---|
455 | // User initialization classes |
---|
456 | ... |
---|
457 | runManager->SetUserAction(new MySteppingAction); |
---|
458 | ... |
---|
459 | } |
---|
460 | |
---|
461 | //----- end of C++ source code |
---|
462 | </PRE> |
---|
463 | <P> |
---|
464 | Thus you can visualize tracking steps with various visualization attributes, |
---|
465 | e.g., color, at each step, automatically. |
---|
466 | <P> |
---|
467 | As well as tracking steps, you can visualize any kind 3D object made of |
---|
468 | line segments, using class <i>G4Polyline</i> and its drawing method, defined in class |
---|
469 | <i>G4VVisManager</i>. |
---|
470 | See, for example, the implementation of the <tt>/vis/scene/add/axes</tt> command. |
---|
471 | <P> |
---|
472 | |
---|
473 | <h4>8.5.10 Visualization User Action</h4> |
---|
474 | |
---|
475 | You can implement the <tt>Draw</tt> method of <tt>G4VUserVisAction</tt>, e.g., the class definition could be: |
---|
476 | <PRE> |
---|
477 | class StandaloneVisAction: public G4VUserVisAction { |
---|
478 | void Draw(); |
---|
479 | }; |
---|
480 | </PRE> |
---|
481 | and the implementation: |
---|
482 | <PRE> |
---|
483 | void StandaloneVisAction::Draw() { |
---|
484 | G4VVisManager* pVisManager = G4VVisManager::GetConcreteInstance(); |
---|
485 | if (pVisManager) { |
---|
486 | |
---|
487 | // Simple box... |
---|
488 | pVisManager->Draw(G4Box("box",2*m,2*m,2*m), |
---|
489 | G4VisAttributes(G4Colour(1,1,0))); |
---|
490 | |
---|
491 | // Boolean solid... |
---|
492 | G4Box boxA("boxA",3*m,3*m,3*m); |
---|
493 | G4Box boxB("boxB",1*m,1*m,1*m); |
---|
494 | G4SubtractionSolid subtracted("subtracted_boxes",&boxA,&boxB, |
---|
495 | G4Translate3D(3*m,3*m,3*m)); |
---|
496 | pVisManager->Draw(subtracted, |
---|
497 | G4VisAttributes(G4Colour(0,1,1)), |
---|
498 | G4Translate3D(6*m,6*m,6*m)); |
---|
499 | } |
---|
500 | } |
---|
501 | </PRE> |
---|
502 | Explicit use of polyhedron objects is equivalent, e.g.: |
---|
503 | <PRE> |
---|
504 | // Same, but explicit polyhedron... |
---|
505 | G4Polyhedron* pA = G4Box("boxA",3*m,3*m,3*m).CreatePolyhedron(); |
---|
506 | G4Polyhedron* pB = G4Box("boxB",1*m,1*m,1*m).CreatePolyhedron(); |
---|
507 | pB->Transform(G4Translate3D(3*m,3*m,3*m)); |
---|
508 | G4Polyhedron* pSubtracted = new G4Polyhedron(pA->subtract(*pB)); |
---|
509 | G4VisAttributes subVisAtts(G4Colour(0,1,1)); |
---|
510 | pSubtracted->SetVisAttributes(&subVisAtts); |
---|
511 | pVisManager->Draw(*pSubtracted,G4Translate3D(6*m,6*m,6*m)); |
---|
512 | delete pA; |
---|
513 | delete pB; |
---|
514 | delete pSubtracted; |
---|
515 | </PRE> |
---|
516 | If efficiency is an issue, create the objects in the constructor, |
---|
517 | delete them in the destructor and draw them in your <tt>Draw</tt> |
---|
518 | method. Anyway, an instance of your class needs to be registered with |
---|
519 | the vis manager, e.g.: |
---|
520 | <PRE> |
---|
521 | ... |
---|
522 | G4VisManager* visManager = new G4VisExecutive; |
---|
523 | visManager->Initialize (); |
---|
524 | |
---|
525 | visManager->SetUserAction |
---|
526 | (new StandaloneVisAction, |
---|
527 | G4VisExtent(-5*m,5*m,-5*m,5*m,-5*m,5*m)); // 2nd argument optional. |
---|
528 | ... |
---|
529 | </PRE> |
---|
530 | then activate by adding to a scene, e.g: |
---|
531 | <PRE> |
---|
532 | /control/verbose 2 |
---|
533 | /vis/verbose c |
---|
534 | /vis/open OGLSXm |
---|
535 | /vis/scene/create |
---|
536 | #/vis/scene/add/userAction |
---|
537 | /vis/scene/add/userAction -10 10 -10 10 -10 10 m |
---|
538 | #/vis/scene/add/axes 0 0 0 10 m |
---|
539 | #/vis/scene/add/scale 10 m |
---|
540 | /vis/sceneHandler/attach |
---|
541 | /vis/viewer/refresh |
---|
542 | </PRE> |
---|
543 | The extent can be added on registration or on the command line or |
---|
544 | neither (if the extent of the scene is set by other components). Your |
---|
545 | <tt>Draw</tt> method will be called whenever needed to refresh the |
---|
546 | screen or rebuild a graphics database, for any chosen viewer. The |
---|
547 | scene can be attached to any scene handler and your drawing will be |
---|
548 | shown. |
---|
549 | |
---|
550 | <h4>8.5.11 Standalone Visualization</h4> |
---|
551 | |
---|
552 | The above raises the possibility of using Geant4 as a "standalone" |
---|
553 | graphics package without invoking the run manager. The following main |
---|
554 | program, together with a user visualization action and a macro file, |
---|
555 | will allow you to view your drawing interactively on any of the |
---|
556 | supported graphics systems. |
---|
557 | <PRE> |
---|
558 | #include "globals.hh" |
---|
559 | #include "G4VisExecutive.hh" |
---|
560 | #include "G4VisExtent.hh" |
---|
561 | #include "G4UImanager.hh" |
---|
562 | #include "G4UIterminal.hh" |
---|
563 | #include "G4UItcsh.hh" |
---|
564 | |
---|
565 | #include "StandaloneVisAction.hh" |
---|
566 | |
---|
567 | int main() { |
---|
568 | |
---|
569 | G4VisManager* visManager = new G4VisExecutive; |
---|
570 | visManager->Initialize (); |
---|
571 | |
---|
572 | visManager->SetUserAction |
---|
573 | (new StandaloneVisAction, |
---|
574 | G4VisExtent(-5*m,5*m,-5*m,5*m,-5*m,5*m)); // 2nd argument optional. |
---|
575 | |
---|
576 | G4UImanager* UI = G4UImanager::GetUIpointer (); |
---|
577 | UI->ApplyCommand ("/control/execute standalone.g4m"); |
---|
578 | |
---|
579 | G4UIsession* session = new G4UIterminal(new G4UItcsh); |
---|
580 | session->SessionStart(); |
---|
581 | |
---|
582 | delete session; |
---|
583 | delete visManager; |
---|
584 | } |
---|
585 | </PRE> |
---|
586 | |
---|
587 | <HR> |
---|
588 | <A HREF="attributes.html">Next section</A><BR> |
---|
589 | <A HREF="index.html">Back to contents</A> |
---|
590 | </BODY> |
---|
591 | </HTML> |
---|