Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // John Allison 6th October 2019 26 // John Allison 6th October 2019 27 27 28 #ifndef G4TOOLSSGVIEWER_HH 28 #ifndef G4TOOLSSGVIEWER_HH 29 #define G4TOOLSSGVIEWER_HH 29 #define G4TOOLSSGVIEWER_HH 30 30 31 #include "G4VViewer.hh" 31 #include "G4VViewer.hh" 32 32 33 #include "G4ToolsSGSceneHandler.hh" 33 #include "G4ToolsSGSceneHandler.hh" 34 #include "G4Scene.hh" 34 #include "G4Scene.hh" 35 #include "G4VVisCommand.hh" 35 #include "G4VVisCommand.hh" 36 36 37 #include <tools/fpng> 37 #include <tools/fpng> 38 #include <tools/toojpeg> 38 #include <tools/toojpeg> 39 39 40 #include <tools/sg/device_interactor> 40 #include <tools/sg/device_interactor> 41 #include <tools/sg/separator> 41 #include <tools/sg/separator> 42 #include <tools/sg/ortho> 42 #include <tools/sg/ortho> 43 #include <tools/sg/perspective> 43 #include <tools/sg/perspective> 44 #include <tools/sg/torche> 44 #include <tools/sg/torche> 45 #include <tools/sg/blend> 45 #include <tools/sg/blend> 46 #include <tools/sg/noderef> 46 #include <tools/sg/noderef> 47 #include <tools/sg/keys> 47 #include <tools/sg/keys> 48 48 49 #include <tools/tokenize> 49 #include <tools/tokenize> 50 #include <tools/sg/write_paper> 50 #include <tools/sg/write_paper> 51 51 52 template <class SG_SESSION,class SG_VIEWER> 52 template <class SG_SESSION,class SG_VIEWER> 53 class G4ToolsSGViewer : public G4VViewer, tool 53 class G4ToolsSGViewer : public G4VViewer, tools::sg::device_interactor { 54 typedef G4VViewer parent; 54 typedef G4VViewer parent; 55 typedef tools::sg::device_interactor parent_ 55 typedef tools::sg::device_interactor parent_interactor; 56 public: //tools::sg::device_interactor interfa 56 public: //tools::sg::device_interactor interface. 57 virtual void key_press(const tools::sg::key_ 57 virtual void key_press(const tools::sg::key_down_event& a_event) { 58 fKeyPressed = true; 58 fKeyPressed = true; 59 fKeyShift = a_event.key() == tools::sg::ke 59 fKeyShift = a_event.key() == tools::sg::key_shift()?true:false; 60 } 60 } 61 virtual void key_release(const tools::sg::ke 61 virtual void key_release(const tools::sg::key_up_event&) {fKeyPressed = false;} 62 virtual void mouse_press(const tools::sg::mo 62 virtual void mouse_press(const tools::sg::mouse_down_event& a_event) { 63 fMousePressed = true; 63 fMousePressed = true; 64 fMousePressedX = a_event.x(); 64 fMousePressedX = a_event.x(); 65 fMousePressedY = a_event.y(); 65 fMousePressedY = a_event.y(); 66 } 66 } 67 virtual void mouse_release(const tools::sg:: 67 virtual void mouse_release(const tools::sg::mouse_up_event&) {fMousePressed = false;} 68 virtual void mouse_move(const tools::sg::mou 68 virtual void mouse_move(const tools::sg::mouse_move_event& a_event) { 69 G4double x = a_event.x(); 69 G4double x = a_event.x(); 70 G4double y = a_event.y(); 70 G4double y = a_event.y(); 71 G4double dx = x-fMousePressedX; 71 G4double dx = x-fMousePressedX; 72 G4double dy = y-fMousePressedY; 72 G4double dy = y-fMousePressedY; 73 fMousePressedX = x; 73 fMousePressedX = x; 74 fMousePressedY = y; 74 fMousePressedY = y; 75 75 76 if (fMousePressed) { 76 if (fMousePressed) { 77 77 78 if (fKeyPressed && fKeyShift) { // Tran 78 if (fKeyPressed && fKeyShift) { // Translation (pan) 79 79 80 const G4double sceneRadius = fSGSceneH 80 const G4double sceneRadius = fSGSceneHandler.GetScene()->GetExtent().GetExtentRadius(); 81 const G4double scale = 300; // Roughl 81 const G4double scale = 300; // Roughly pixels per window, empirically chosen 82 const G4double dxScene = dx*sceneRadiu 82 const G4double dxScene = dx*sceneRadius/scale; 83 const G4double dyScene = dy*sceneRadiu 83 const G4double dyScene = dy*sceneRadius/scale; 84 fVP.IncrementPan(-dxScene,dyScene); 84 fVP.IncrementPan(-dxScene,dyScene); 85 85 86 } else { // Rotation 86 } else { // Rotation 87 87 88 // Simple ad-hoc algorithms 88 // Simple ad-hoc algorithms 89 const G4Vector3D& x_prime = fVP.GetVie 89 const G4Vector3D& x_prime = fVP.GetViewpointDirection().cross(fVP.GetUpVector()); 90 const G4Vector3D& y_prime = x_prime.cr 90 const G4Vector3D& y_prime = x_prime.cross(fVP.GetViewpointDirection()); 91 const G4double scale = 200; // Roughl 91 const G4double scale = 200; // Roughly pixels per window, empirically chosen 92 G4Vector3D newViewpointDirection = fVP 92 G4Vector3D newViewpointDirection = fVP.GetViewpointDirection(); 93 newViewpointDirection += dx*x_prime/sc 93 newViewpointDirection += dx*x_prime/scale; 94 newViewpointDirection += dy*y_prime/sc 94 newViewpointDirection += dy*y_prime/scale; 95 fVP.SetViewpointDirection(newViewpoint 95 fVP.SetViewpointDirection(newViewpointDirection.unit()); 96 96 97 if (fVP.GetRotationStyle() == G4ViewPa 97 if (fVP.GetRotationStyle() == G4ViewParameters::freeRotation) { 98 G4Vector3D newUpVector = fVP.GetUpVe 98 G4Vector3D newUpVector = fVP.GetUpVector(); 99 newUpVector += dx*x_prime/scale; 99 newUpVector += dx*x_prime/scale; 100 newUpVector += dy*y_prime/scale; 100 newUpVector += dy*y_prime/scale; 101 fVP.SetUpVector(newUpVector.unit()); 101 fVP.SetUpVector(newUpVector.unit()); 102 } 102 } 103 } 103 } 104 } 104 } 105 105 106 SetView(); 106 SetView(); 107 DrawView(); 107 DrawView(); 108 } 108 } 109 virtual void wheel_rotate(const tools::sg::w 109 virtual void wheel_rotate(const tools::sg::wheel_rotate_event& a_event) { 110 const G4double angleY = a_event.angle(); 110 const G4double angleY = a_event.angle(); 111 if (fVP.GetFieldHalfAngle() == 0.) { // O 111 if (fVP.GetFieldHalfAngle() == 0.) { // Orthographic projection 112 const G4double scale = 500; // Empirica 112 const G4double scale = 500; // Empirically chosen 113 fVP.MultiplyZoomFactor(1.+angleY/scale); 113 fVP.MultiplyZoomFactor(1.+angleY/scale); 114 } else { // P 114 } else { // Perspective projection 115 const G4double delta = fSceneHandler.Get 115 const G4double delta = fSceneHandler.GetExtent().GetExtentRadius()/200.; // Empirical 116 fVP.SetDolly(fVP.GetDolly()+angleY*delta 116 fVP.SetDolly(fVP.GetDolly()+angleY*delta); 117 } 117 } 118 SetView(); 118 SetView(); 119 DrawView(); 119 DrawView(); 120 } 120 } 121 public: 121 public: 122 G4ToolsSGViewer(SG_SESSION& a_session,G4Tool 122 G4ToolsSGViewer(SG_SESSION& a_session,G4ToolsSGSceneHandler& a_scene_handler, const G4String& a_name) 123 :parent(a_scene_handler,a_scene_handler.Incr 123 :parent(a_scene_handler,a_scene_handler.IncrementViewCount(),a_name) 124 ,fSGSession(a_session) 124 ,fSGSession(a_session) 125 ,fSGSceneHandler(a_scene_handler) 125 ,fSGSceneHandler(a_scene_handler) 126 ,fSGViewer(nullptr) 126 ,fSGViewer(nullptr) 127 ,fKeyPressed(false) 127 ,fKeyPressed(false) 128 ,fKeyShift(false) 128 ,fKeyShift(false) 129 ,fMousePressed(false) 129 ,fMousePressed(false) 130 ,fMousePressedX(0) 130 ,fMousePressedX(0) 131 ,fMousePressedY(0) 131 ,fMousePressedY(0) 132 { 132 { 133 //::printf("debug : G4ToolsSGViewer::G4Too 133 //::printf("debug : G4ToolsSGViewer::G4ToolsSGViewer: %lu, %s\n",this,a_name.c_str()); 134 Messenger::Create(); 134 Messenger::Create(); 135 } 135 } 136 136 137 virtual ~G4ToolsSGViewer() { 137 virtual ~G4ToolsSGViewer() { 138 //::printf("debug : G4ToolsSGViewer::~G4To 138 //::printf("debug : G4ToolsSGViewer::~G4ToolsSGViewer: %lu\n",this); 139 //WARNING : nodes may refer f_gl2ps_mgr, f 139 //WARNING : nodes may refer f_gl2ps_mgr, f_zb_mgr (to handle gstos (for GPU) or textures), then 140 // we have to delete them first. 140 // we have to delete them first. 141 fSGViewer->sg().clear(); 141 fSGViewer->sg().clear(); 142 delete fSGViewer; 142 delete fSGViewer; 143 } 143 } 144 protected: 144 protected: 145 G4ToolsSGViewer(const G4ToolsSGViewer& a_fro 145 G4ToolsSGViewer(const G4ToolsSGViewer& a_from) 146 :parent(a_from) 146 :parent(a_from) 147 ,parent_interactor(a_from) 147 ,parent_interactor(a_from) 148 ,fSGSession(a_from.fSGSession) 148 ,fSGSession(a_from.fSGSession) 149 ,fSGSceneHandler(a_from.fSGSceneHandler) 149 ,fSGSceneHandler(a_from.fSGSceneHandler) 150 ,fSGViewer(nullptr) 150 ,fSGViewer(nullptr) 151 ,fKeyPressed(false) 151 ,fKeyPressed(false) 152 ,fKeyShift(false) 152 ,fKeyShift(false) 153 ,fMousePressed(false) 153 ,fMousePressed(false) 154 ,fMousePressedX(0) 154 ,fMousePressedX(0) 155 ,fMousePressedY(0) 155 ,fMousePressedY(0) 156 {} 156 {} 157 G4ToolsSGViewer& operator=(const G4ToolsSGVi 157 G4ToolsSGViewer& operator=(const G4ToolsSGViewer&) {return *this;} 158 public: 158 public: 159 virtual void Initialise() { 159 virtual void Initialise() { 160 if(fSGViewer) return; //done. 160 if(fSGViewer) return; //done. 161 fVP.SetAutoRefresh(true); 161 fVP.SetAutoRefresh(true); 162 fDefaultVP.SetAutoRefresh(true); 162 fDefaultVP.SetAutoRefresh(true); 163 //::printf("debug : G4ToolsSGViewer::Initi 163 //::printf("debug : G4ToolsSGViewer::Initialise\n"); 164 ////////////////////////////////////////// 164 ////////////////////////////////////////////////////////// 165 /// create the viewer, set the scene graph 165 /// create the viewer, set the scene graph /////////////// 166 ////////////////////////////////////////// 166 ////////////////////////////////////////////////////////// 167 fSGViewer = new SG_VIEWER(fSGSession 167 fSGViewer = new SG_VIEWER(fSGSession 168 ,fVP.GetWindowAbsoluteLocationHintX(1440 168 ,fVP.GetWindowAbsoluteLocationHintX(1440) 169 ,fVP.GetWindowAbsoluteLocationHintY(900) 169 ,fVP.GetWindowAbsoluteLocationHintY(900) 170 ,fVP.GetWindowSizeHintX() 170 ,fVP.GetWindowSizeHintX() 171 ,fVP.GetWindowSizeHintY() 171 ,fVP.GetWindowSizeHintY() 172 ,fName); 172 ,fName); 173 if(!fSGViewer->has_window()) { 173 if(!fSGViewer->has_window()) { 174 fViewId = -1; // This flags an error. 174 fViewId = -1; // This flags an error. 175 G4cerr << "G4ToolsSGViewer::Initialise : 175 G4cerr << "G4ToolsSGViewer::Initialise : SG_VIEWER::has_window() failed." << G4endl; 176 return; 176 return; 177 } 177 } 178 fSGViewer->set_device_interactor(this); 178 fSGViewer->set_device_interactor(this); 179 } 179 } 180 180 181 virtual void SetView() { 181 virtual void SetView() { 182 //::printf("debug : G4ToolsSGViewer::SetVi 182 //::printf("debug : G4ToolsSGViewer::SetView\n"); 183 if(!fSceneHandler.GetScene()) { 183 if(!fSceneHandler.GetScene()) { 184 fSGViewer->set_clear_color(0.3,0.3,0.3,1 184 fSGViewer->set_clear_color(0.3,0.3,0.3,1); //some grey color to signal the user that something is wrong. 185 G4cerr << "G4ToolsSGViewer::SetView : no 185 G4cerr << "G4ToolsSGViewer::SetView : no G4Scene.." << G4endl; 186 return; 186 return; 187 } 187 } 188 188 189 ////////////////////////////////////////// 189 ////////////////////////////////////////////////////////// 190 ////////////////////////////////////////// 190 ////////////////////////////////////////////////////////// 191 ////////////////////////////////////////// 191 ////////////////////////////////////////////////////////// 192 // Get radius of scene, etc. 192 // Get radius of scene, etc. 193 // Note that this procedure properly takes 193 // Note that this procedure properly takes into account zoom, dolly and pan. 194 const G4Point3D targetPoint 194 const G4Point3D targetPoint 195 = fSceneHandler.GetScene()->GetStandardT 195 = fSceneHandler.GetScene()->GetStandardTargetPoint() + fVP.GetCurrentTargetPoint (); 196 G4double radius = fSceneHandler.GetScene() 196 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius(); 197 if(radius<=0.) radius = 1.; 197 if(radius<=0.) radius = 1.; 198 const G4double cameraDistance = fVP.GetCam 198 const G4double cameraDistance = fVP.GetCameraDistance (radius); 199 const G4Point3D cameraPosition = targetPoi 199 const G4Point3D cameraPosition = targetPoint + cameraDistance * fVP.GetViewpointDirection().unit(); 200 const G4Normal3D& up = fVP.GetUpVector (); 200 const G4Normal3D& up = fVP.GetUpVector (); 201 const G4double pnear = fVP.GetNearDistanc 201 const G4double pnear = fVP.GetNearDistance (cameraDistance, radius); 202 const G4double pfar = fVP.GetFarDistance 202 const G4double pfar = fVP.GetFarDistance (cameraDistance, pnear, radius); 203 //const G4double right = fVP.GetFrontHalfHe 203 //const G4double right = fVP.GetFrontHalfHeight (pnear, radius); 204 //const G4double left = -right; 204 //const G4double left = -right; 205 const G4double top = fVP.GetFrontHalfHe 205 const G4double top = fVP.GetFrontHalfHeight (pnear, radius); 206 const G4double bottom = -top; 206 const G4double bottom = -top; 207 // sanity check : 207 // sanity check : 208 tools::vec3f dir(float(targetPoint.x()-cam 208 tools::vec3f dir(float(targetPoint.x()-cameraPosition.x()), 209 float(targetPoint.y()-cam 209 float(targetPoint.y()-cameraPosition.y()), 210 float(targetPoint.z()-cam 210 float(targetPoint.z()-cameraPosition.z())); 211 if(!dir.length()) { 211 if(!dir.length()) { 212 fSGViewer->set_clear_color(0.3,0.3,0.3,1 212 fSGViewer->set_clear_color(0.3,0.3,0.3,1); 213 G4cerr << "G4ToolsSGViewer::SetView : nu 213 G4cerr << "G4ToolsSGViewer::SetView : null size viewer area." << G4endl; 214 return; 214 return; 215 } 215 } 216 216 217 ////////////////////////////////////////// 217 ////////////////////////////////////////////////////////// 218 ////////////////////////////////////////// 218 ////////////////////////////////////////////////////////// 219 ////////////////////////////////////////// 219 ////////////////////////////////////////////////////////// 220 /* 220 /* 221 G4cout << "debug : 0002 : radius " << radi 221 G4cout << "debug : 0002 : radius " << radius << std::endl; 222 G4cout << "debug : cameraDistance : " << c 222 G4cout << "debug : cameraDistance : " << cameraDistance << std::endl; 223 G4cout << "debug : fieldHalfAngle : " << f 223 G4cout << "debug : fieldHalfAngle : " << fVP.GetFieldHalfAngle() << std::endl; 224 G4cout << "debug : zoomFactor : " << fVP.G 224 G4cout << "debug : zoomFactor : " << fVP.GetZoomFactor() << std::endl; 225 G4cout << "debug : up : " << up.x() << " " 225 G4cout << "debug : up : " << up.x() << " " << up.y() << " " << up.z() << std::endl; 226 G4cout << "debug : targetPoint : " << targ 226 G4cout << "debug : targetPoint : " << targetPoint.x() << " " << targetPoint.y() << " " << targetPoint.z() << std::endl; 227 G4cout << "debug : cameraPosition : " << c 227 G4cout << "debug : cameraPosition : " << cameraPosition.x() << " " << cameraPosition.y() << " " << cameraPosition.z() << std::endl; 228 G4cout << "debug : camera : znear " << pne 228 G4cout << "debug : camera : znear " << pnear << ", zfar " << pfar << std::endl; 229 */ 229 */ 230 ////////////////////////////////////////// 230 ////////////////////////////////////////////////////////// 231 /// create scene graph /////////////////// 231 /// create scene graph /////////////////////////////////// 232 ////////////////////////////////////////// 232 ////////////////////////////////////////////////////////// 233 // Set projection, then create the tools:: 233 // Set projection, then create the tools::sg camera node : 234 tools::sg::base_camera* _camera = nullptr; 234 tools::sg::base_camera* _camera = nullptr; 235 if (fVP.GetFieldHalfAngle() <= 0.) { 235 if (fVP.GetFieldHalfAngle() <= 0.) { 236 //G4cout << "debug : camera : ortho : to 236 //G4cout << "debug : camera : ortho : top " << top << " bottom " << bottom << " top-bottom " << top-bottom << std::endl; 237 if((top-bottom)<=0) { 237 if((top-bottom)<=0) { 238 fSGViewer->set_clear_color(0.3,0.3,0.3 238 fSGViewer->set_clear_color(0.3,0.3,0.3,1); 239 G4cerr << "G4ToolsSGViewer::SetView : 239 G4cerr << "G4ToolsSGViewer::SetView : for ortho camera, (top-bottom)<=0." << G4endl; 240 return; 240 return; 241 } 241 } 242 tools::sg::ortho* ortho_camera = new too 242 tools::sg::ortho* ortho_camera = new tools::sg::ortho; 243 ortho_camera->height.value(float(top-bot 243 ortho_camera->height.value(float(top-bottom)); 244 _camera = ortho_camera; 244 _camera = ortho_camera; 245 } else { 245 } else { 246 //G4cout << "debug : camera : perspec : 246 //G4cout << "debug : camera : perspec : heightAngle " << float(2*fVP.GetFieldHalfAngle()) << std::endl; 247 tools::sg::perspective* perspective_came 247 tools::sg::perspective* perspective_camera = new tools::sg::perspective; 248 perspective_camera->height_angle.value(f 248 perspective_camera->height_angle.value(float(2*fVP.GetFieldHalfAngle())); 249 _camera = perspective_camera; 249 _camera = perspective_camera; 250 } 250 } 251 251 252 _camera->position.value 252 _camera->position.value 253 (tools::vec3f(float(cameraPosition.x()), 253 (tools::vec3f(float(cameraPosition.x()), 254 float(cameraPosition.y()), 254 float(cameraPosition.y()), 255 float(cameraPosition.z()))); 255 float(cameraPosition.z()))); 256 _camera->znear.value(float(pnear)); 256 _camera->znear.value(float(pnear)); 257 _camera->zfar.value(float(pfar)); 257 _camera->zfar.value(float(pfar)); 258 258 259 _camera->look_at(dir,tools::vec3f(up.x(),u 259 _camera->look_at(dir,tools::vec3f(up.x(),up.y(),up.z())); //same logic as in G4OpenInventorViewer. 260 260 261 /* 261 /* 262 const G4Vector3D& lightDirection = fVP.Get 262 const G4Vector3D& lightDirection = fVP.GetLightpointDirection(); 263 G4cout << "debug : lightDirection : " << l 263 G4cout << "debug : lightDirection : " << lightDirection.x() << " " << lightDirection.y() << " " << lightDirection.z() << std::endl; 264 const G4Vector3D& actualLightDirection = f 264 const G4Vector3D& actualLightDirection = fVP.GetActualLightpointDirection(); 265 G4cout << "debug : actualLightDirection : 265 G4cout << "debug : actualLightDirection : " << actualLightDirection.x() << " " << actualLightDirection.y() << " " << actualLightDirection.z() << std::endl; 266 */ 266 */ 267 267 268 CreateSG(_camera,fVP.GetActualLightpointDi 268 CreateSG(_camera,fVP.GetActualLightpointDirection()); 269 269 270 {G4Color background = fVP.GetBackgroundColo 270 {G4Color background = fVP.GetBackgroundColour (); 271 fSGViewer->set_clear_color(float(backgroun 271 fSGViewer->set_clear_color(float(background.GetRed()),float(background.GetGreen()),float(background.GetBlue()),1);} 272 } 272 } 273 273 274 virtual void ClearView() {} 274 virtual void ClearView() {} 275 275 276 virtual void DrawView() { 276 virtual void DrawView() { 277 if (!fNeedKernelVisit) KernelVisitDecision 277 if (!fNeedKernelVisit) KernelVisitDecision(); 278 G4bool kernelVisitWasNeeded = fNeedKernelV 278 G4bool kernelVisitWasNeeded = fNeedKernelVisit; // Keep (ProcessView resets). 279 fLastVP = fVP; 279 fLastVP = fVP; 280 ProcessView(); // Clears store and proces 280 ProcessView(); // Clears store and processes scene only if necessary. 281 if (kernelVisitWasNeeded) { 281 if (kernelVisitWasNeeded) { 282 // We might need to do something if the 282 // We might need to do something if the kernel was visited. 283 } else { 283 } else { 284 } 284 } 285 FinishView (); // Flush streams and/ 285 FinishView (); // Flush streams and/or swap buffers. 286 } 286 } 287 287 288 virtual void ShowView() {FinishView();} 288 virtual void ShowView() {FinishView();} 289 289 290 virtual void FinishView() { 290 virtual void FinishView() { 291 if(fSGViewer) { 291 if(fSGViewer) { 292 fSGSceneHandler.TouchPlotters(fSGViewer- 292 fSGSceneHandler.TouchPlotters(fSGViewer->sg()); 293 fSGViewer->show(); 293 fSGViewer->show(); 294 fSGViewer->win_render(); 294 fSGViewer->win_render(); 295 fSGSession.sync(); 295 fSGSession.sync(); 296 } 296 } 297 } 297 } 298 298 >> 299 #ifdef G4MULTITHREADED 299 virtual void SwitchToVisSubThread() {} 300 virtual void SwitchToVisSubThread() {} 300 301 301 virtual void SwitchToMasterThread() { 302 virtual void SwitchToMasterThread() { 302 if (G4Threading::IsMultithreadedApplicatio 303 if (G4Threading::IsMultithreadedApplication()) { 303 // I have not figured out how to draw du 304 // I have not figured out how to draw during a run. 304 // 305 // 305 // Setting fNeedKernelVisit=true causes 306 // Setting fNeedKernelVisit=true causes scene deletion and a complete rebuild, 306 // including trajectories, hits, etc. fr 307 // including trajectories, hits, etc. from kept events. 307 // 308 // 308 // Clearly this is a limitation because 309 // Clearly this is a limitation because even if you run 1000 events you only 309 // get those kept (default 100), and eve 310 // get those kept (default 100), and even worse, if end-if-event-action is 310 // "refresh", you only get one event (th 311 // "refresh", you only get one event (the last I think). 311 // 312 // 312 // Also, strictly, there is no need to r 313 // Also, strictly, there is no need to rebuid run-duration models (detector), 313 // but a complete rebuild is the easiest 314 // but a complete rebuild is the easiest way (already imeplemented). 314 // 315 // 315 // Only do this if there are end-of-even 316 // Only do this if there are end-of-event models (e.g., trajectories) that 316 // may require it. 317 // may require it. 317 if (fSceneHandler.GetScene() && fSceneHa 318 if (fSceneHandler.GetScene() && fSceneHandler.GetScene()->GetEndOfEventModelList().size()) { 318 fNeedKernelVisit = true; 319 fNeedKernelVisit = true; 319 DrawView(); // Draw trajectories, etc 320 DrawView(); // Draw trajectories, etc., from kept events 320 } 321 } 321 } 322 } 322 } 323 } >> 324 #endif 323 325 324 //SG_VIEWER* sg_viewer() {return fSGViewer;} 326 //SG_VIEWER* sg_viewer() {return fSGViewer;} 325 protected: 327 protected: 326 void KernelVisitDecision () { 328 void KernelVisitDecision () { 327 if (CompareForKernelVisit(fLastVP)) { 329 if (CompareForKernelVisit(fLastVP)) { 328 NeedKernelVisit (); // Sets fNeedKernel 330 NeedKernelVisit (); // Sets fNeedKernelVisit. 329 } 331 } 330 } 332 } 331 333 332 G4bool CompareForKernelVisit(G4ViewParameter 334 G4bool CompareForKernelVisit(G4ViewParameters& vp) { 333 // Typical comparison. Taken from OpenInv 335 // Typical comparison. Taken from OpenInventor. 334 if ( 336 if ( 335 (vp.GetDrawingStyle () != fVP.GetDra 337 (vp.GetDrawingStyle () != fVP.GetDrawingStyle ()) || 336 (vp.GetNumberOfCloudPoints() != fVP.Ge 338 (vp.GetNumberOfCloudPoints() != fVP.GetNumberOfCloudPoints()) || 337 (vp.IsAuxEdgeVisible () != fVP.IsAuxE 339 (vp.IsAuxEdgeVisible () != fVP.IsAuxEdgeVisible ()) || 338 (vp.IsCulling () != fVP.IsCull 340 (vp.IsCulling () != fVP.IsCulling ()) || 339 (vp.IsCullingInvisible () != fVP.IsCull 341 (vp.IsCullingInvisible () != fVP.IsCullingInvisible ()) || 340 (vp.IsDensityCulling () != fVP.IsDens 342 (vp.IsDensityCulling () != fVP.IsDensityCulling ()) || 341 (vp.IsCullingCovered () != fVP.IsCull 343 (vp.IsCullingCovered () != fVP.IsCullingCovered ()) || 342 (vp.GetCBDAlgorithmNumber() != 344 (vp.GetCBDAlgorithmNumber() != 343 fVP.GetCBDAlgorithmNumber()) 345 fVP.GetCBDAlgorithmNumber()) || 344 (vp.IsSection () != fVP.IsSect 346 (vp.IsSection () != fVP.IsSection ()) || 345 (vp.IsCutaway () != fVP.IsCuta 347 (vp.IsCutaway () != fVP.IsCutaway ()) || 346 // This assumes use of generic clipping 348 // This assumes use of generic clipping (sectioning, slicing, 347 // DCUT, cutaway). If a decision is ma 349 // DCUT, cutaway). If a decision is made to implement locally, 348 // this will need changing. See G4Open 350 // this will need changing. See G4OpenGLViewer::SetView, 349 // G4OpenGLStoredViewer.cc::CompareForK 351 // G4OpenGLStoredViewer.cc::CompareForKernelVisit and 350 // G4OpenGLStoredSceneHander::CreateSec 352 // G4OpenGLStoredSceneHander::CreateSection/CutawayPolyhedron. 351 (vp.IsExplode () != fVP.IsExpl 353 (vp.IsExplode () != fVP.IsExplode ()) || 352 (vp.GetNoOfSides () != fVP.GetNoO 354 (vp.GetNoOfSides () != fVP.GetNoOfSides ()) || 353 (vp.GetGlobalMarkerScale() != fVP.Ge 355 (vp.GetGlobalMarkerScale() != fVP.GetGlobalMarkerScale()) || 354 (vp.GetGlobalLineWidthScale() != fVP.Ge 356 (vp.GetGlobalLineWidthScale() != fVP.GetGlobalLineWidthScale()) || 355 (vp.IsMarkerNotHidden () != fVP.IsMark 357 (vp.IsMarkerNotHidden () != fVP.IsMarkerNotHidden ()) || 356 (vp.GetDefaultVisAttributes()->GetColou 358 (vp.GetDefaultVisAttributes()->GetColour() != 357 fVP.GetDefaultVisAttributes()->GetColo 359 fVP.GetDefaultVisAttributes()->GetColour()) || 358 (vp.GetDefaultTextVisAttributes()->GetC 360 (vp.GetDefaultTextVisAttributes()->GetColour() != 359 fVP.GetDefaultTextVisAttributes()->Get 361 fVP.GetDefaultTextVisAttributes()->GetColour()) || 360 (vp.GetBackgroundColour ()!= fVP.GetBac 362 (vp.GetBackgroundColour ()!= fVP.GetBackgroundColour ())|| 361 (vp.IsPicking () != fVP.IsPick 363 (vp.IsPicking () != fVP.IsPicking ()) || 362 // Scaling for Open Inventor is done by 364 // Scaling for Open Inventor is done by the scene handler so it 363 // needs a kernel visit. (In this resp 365 // needs a kernel visit. (In this respect, it differs from the 364 // OpenGL drivers, where it's done in S 366 // OpenGL drivers, where it's done in SetView.) 365 (vp.GetScaleFactor () != fVP.GetSca 367 (vp.GetScaleFactor () != fVP.GetScaleFactor ()) || 366 (vp.GetVisAttributesModifiers() != 368 (vp.GetVisAttributesModifiers() != 367 fVP.GetVisAttributesModifiers()) 369 fVP.GetVisAttributesModifiers()) || 368 (vp.IsSpecialMeshRendering() != 370 (vp.IsSpecialMeshRendering() != 369 fVP.IsSpecialMeshRendering()) 371 fVP.IsSpecialMeshRendering()) || 370 (vp.GetSpecialMeshRenderingOption() != 372 (vp.GetSpecialMeshRenderingOption() != 371 fVP.GetSpecialMeshRenderingOption()) 373 fVP.GetSpecialMeshRenderingOption()) 372 ) 374 ) 373 return true; 375 return true; 374 376 375 if (vp.IsDensityCulling () && 377 if (vp.IsDensityCulling () && 376 (vp.GetVisibleDensity () != fVP.GetVis 378 (vp.GetVisibleDensity () != fVP.GetVisibleDensity ())) 377 return true; 379 return true; 378 380 379 if (vp.GetCBDAlgorithmNumber() > 0) { 381 if (vp.GetCBDAlgorithmNumber() > 0) { 380 if (vp.GetCBDParameters().size() != fVP. 382 if (vp.GetCBDParameters().size() != fVP.GetCBDParameters().size()) return true; 381 else if (vp.GetCBDParameters() != fVP.Ge 383 else if (vp.GetCBDParameters() != fVP.GetCBDParameters()) return true; 382 } 384 } 383 385 384 if (vp.IsSection () && 386 if (vp.IsSection () && 385 (vp.GetSectionPlane () != fVP.GetSecti 387 (vp.GetSectionPlane () != fVP.GetSectionPlane ())) 386 return true; 388 return true; 387 389 388 if (vp.IsCutaway ()) { 390 if (vp.IsCutaway ()) { 389 if (vp.GetCutawayMode() != fVP.GetCutawa 391 if (vp.GetCutawayMode() != fVP.GetCutawayMode()) return true; 390 if (vp.GetCutawayPlanes ().size () != 392 if (vp.GetCutawayPlanes ().size () != 391 fVP.GetCutawayPlanes ().size ()) ret 393 fVP.GetCutawayPlanes ().size ()) return true; 392 for (size_t i = 0; i < vp.GetCutawayPlan 394 for (size_t i = 0; i < vp.GetCutawayPlanes().size(); ++i) 393 if (vp.GetCutawayPlanes()[i] != fVP.GetC 395 if (vp.GetCutawayPlanes()[i] != fVP.GetCutawayPlanes()[i]) 394 return true; 396 return true; 395 } 397 } 396 398 397 if (vp.IsExplode () && 399 if (vp.IsExplode () && 398 (vp.GetExplodeFactor () != fVP.GetExpl 400 (vp.GetExplodeFactor () != fVP.GetExplodeFactor ())) 399 return true; 401 return true; 400 402 401 if (vp.IsSpecialMeshRendering() && 403 if (vp.IsSpecialMeshRendering() && 402 (vp.GetSpecialMeshVolumes() != fVP.Get 404 (vp.GetSpecialMeshVolumes() != fVP.GetSpecialMeshVolumes())) 403 return true; 405 return true; 404 406 405 return false; 407 return false; 406 } 408 } 407 // void keyPressEvent (KeyEvent*); 409 // void keyPressEvent (KeyEvent*); 408 // void keyReleaseEvent (KeyEvent*); 410 // void keyReleaseEvent (KeyEvent*); 409 // void mouseDoubleClickEvent(MouseEvent*); 411 // void mouseDoubleClickEvent(MouseEvent*); 410 // void mouseMoveEvent (MouseEvent*); 412 // void mouseMoveEvent (MouseEvent*); 411 // void mousePressEvent (MouseEvent*); 413 // void mousePressEvent (MouseEvent*); 412 // void mouseReleaseEvent (MouseEvent*); 414 // void mouseReleaseEvent (MouseEvent*); 413 // void wheelEvent (WheelEvent*); 415 // void wheelEvent (WheelEvent*); 414 416 415 protected: 417 protected: 416 void CreateSG(tools::sg::base_camera* a_came 418 void CreateSG(tools::sg::base_camera* a_camera,const G4Vector3D& a_light_dir) { 417 tools::sg::group& _parent = fSGViewer->sg( 419 tools::sg::group& _parent = fSGViewer->sg(); 418 _parent.clear(); 420 _parent.clear(); 419 421 420 ////////////////////////////////////////// 422 /////////////////////////////////////////////////// 421 /// 2D scene graph: ////////////////////// 423 /// 2D scene graph: /////////////////////////////// 422 ////////////////////////////////////////// 424 /////////////////////////////////////////////////// 423 tools::sg::separator* scene_2D = new tools 425 tools::sg::separator* scene_2D = new tools::sg::separator; 424 _parent.add(scene_2D); 426 _parent.add(scene_2D); 425 scene_2D->add(new tools::sg::noderef(fSGSc 427 scene_2D->add(new tools::sg::noderef(fSGSceneHandler.GetTransient2DObjects())); 426 scene_2D->add(new tools::sg::noderef(fSGSc 428 scene_2D->add(new tools::sg::noderef(fSGSceneHandler.GetPersistent2DObjects())); 427 429 428 ////////////////////////////////////////// 430 /////////////////////////////////////////////////// 429 /// 3D scene graph: ////////////////////// 431 /// 3D scene graph: /////////////////////////////// 430 ////////////////////////////////////////// 432 /////////////////////////////////////////////////// 431 tools::sg::separator* scene_3D = new tools 433 tools::sg::separator* scene_3D = new tools::sg::separator; 432 _parent.add(scene_3D); 434 _parent.add(scene_3D); 433 435 434 scene_3D->add(a_camera); 436 scene_3D->add(a_camera); 435 437 436 {tools::sg::torche* light = new tools::sg:: 438 {tools::sg::torche* light = new tools::sg::torche; 437 light->on = true; 439 light->on = true; 438 light->direction = tools::vec3f(-a_light_d 440 light->direction = tools::vec3f(-a_light_dir.x(),-a_light_dir.y(),-a_light_dir.z()); 439 light->ambient = tools::colorf(0.2f,0.2f,0 441 light->ambient = tools::colorf(0.2f,0.2f,0.2f,1.0f); //same as in G4OpenGLViewer.cc glLight(GL_LIGHT0,GL_AMBIENT and GL_DIFFUSE). 440 light->color = tools::colorf(0.8f,0.8f,0.8 442 light->color = tools::colorf(0.8f,0.8f,0.8f,1.0f); //idem. 441 scene_3D->add(light);} 443 scene_3D->add(light);} 442 444 443 {tools::sg::blend* blend = new tools::sg::b 445 {tools::sg::blend* blend = new tools::sg::blend; 444 blend->on = true; //to handle transparency 446 blend->on = true; //to handle transparency. 445 scene_3D->add(blend);} 447 scene_3D->add(blend);} 446 448 447 scene_3D->add(new tools::sg::noderef(fSGSc 449 scene_3D->add(new tools::sg::noderef(fSGSceneHandler.GetTransient3DObjects())); 448 scene_3D->add(new tools::sg::noderef(fSGSc 450 scene_3D->add(new tools::sg::noderef(fSGSceneHandler.GetPersistent3DObjects())); 449 } 451 } 450 452 451 void Export(const G4String& a_format,const G 453 void Export(const G4String& a_format,const G4String& a_file,G4bool a_do_transparency) { 452 if(!fSGViewer) return; 454 if(!fSGViewer) return; 453 const G4Colour& back_color = fVP.GetBackgr 455 const G4Colour& back_color = fVP.GetBackgroundColour(); 454 bool top_to_bottom = false; //if using to 456 bool top_to_bottom = false; //if using tools::fpng, tools::toojpeg. 455 if(!tools::sg::write_paper(G4cout,f_gl2ps_ 457 if(!tools::sg::write_paper(G4cout,f_gl2ps_mgr,f_zb_mgr, 456 tools::fpng::write,tools:: 458 tools::fpng::write,tools::toojpeg::write, 457 float(back_color.GetRed()) 459 float(back_color.GetRed()),float(back_color.GetGreen()),float(back_color.GetBlue()),float(back_color.GetAlpha()), 458 fSGViewer->sg(),fSGViewer- 460 fSGViewer->sg(),fSGViewer->width(),fSGViewer->height(), 459 a_file,a_format,a_do_trans 461 a_file,a_format,a_do_transparency,top_to_bottom,std::string(),std::string())) { 460 G4cout << "G4ToolsSGViewer::Export: writ 462 G4cout << "G4ToolsSGViewer::Export: write_paper() failed." << G4endl; 461 return; 463 return; 462 } 464 } 463 } 465 } 464 466 465 protected: 467 protected: 466 class Messenger: public G4VVisCommand { 468 class Messenger: public G4VVisCommand { 467 public: 469 public: 468 static void Create() {static Messenger s_m 470 static void Create() {static Messenger s_messenger;} 469 private: 471 private: 470 Messenger() { 472 Messenger() { 471 G4UIparameter* parameter; 473 G4UIparameter* parameter; 472 //////////////////////////////////////// 474 ////////////////////////////////////////////////////////// 473 //////////////////////////////////////// 475 ////////////////////////////////////////////////////////// 474 write_scene = new G4UIcommand("/vis/tsg/ 476 write_scene = new G4UIcommand("/vis/tsg/export", this); 475 write_scene->SetGuidance("Write the cont 477 write_scene->SetGuidance("Write the content of the current viewer in a file at various formats."); 476 write_scene->SetGuidance("Default file i 478 write_scene->SetGuidance("Default file is out.eps and default format is gl2ps_eps."); 477 write_scene->SetGuidance("Available form 479 write_scene->SetGuidance("Available formats are:"); 478 write_scene->SetGuidance("- gl2ps_eps: g 480 write_scene->SetGuidance("- gl2ps_eps: gl2ps producing eps"); 479 write_scene->SetGuidance("- gl2ps_ps: g 481 write_scene->SetGuidance("- gl2ps_ps: gl2ps producing ps"); 480 write_scene->SetGuidance("- gl2ps_pdf: g 482 write_scene->SetGuidance("- gl2ps_pdf: gl2ps producing pdf"); 481 write_scene->SetGuidance("- gl2ps_svg: g 483 write_scene->SetGuidance("- gl2ps_svg: gl2ps producing svg"); 482 write_scene->SetGuidance("- gl2ps_tex: g 484 write_scene->SetGuidance("- gl2ps_tex: gl2ps producing tex"); 483 write_scene->SetGuidance("- gl2ps_pgf: g 485 write_scene->SetGuidance("- gl2ps_pgf: gl2ps producing pgf"); 484 write_scene->SetGuidance("- zb_ps: tools 486 write_scene->SetGuidance("- zb_ps: tools::sg offscreen zbuffer put in a PostScript file."); 485 write_scene->SetGuidance("- zb_png: tool 487 write_scene->SetGuidance("- zb_png: tools::sg offscreen zbuffer put in a png file."); 486 write_scene->SetGuidance("- zb_jpeg: too 488 write_scene->SetGuidance("- zb_jpeg: tools::sg offscreen zbuffer put in a jpeg file."); 487 489 488 parameter = new G4UIparameter("format",' 490 parameter = new G4UIparameter("format",'s',true); 489 parameter->SetDefaultValue("gl2ps_eps"); 491 parameter->SetDefaultValue("gl2ps_eps"); 490 write_scene->SetParameter (parameter); 492 write_scene->SetParameter (parameter); 491 493 492 parameter = new G4UIparameter("file",'s' 494 parameter = new G4UIparameter("file",'s',true); 493 parameter->SetDefaultValue("out.eps"); 495 parameter->SetDefaultValue("out.eps"); 494 write_scene->SetParameter (parameter); 496 write_scene->SetParameter (parameter); 495 497 496 parameter = new G4UIparameter ("do_tran 498 parameter = new G4UIparameter ("do_transparency", 'b', true); 497 parameter->SetDefaultValue ("true"); 499 parameter->SetDefaultValue ("true"); 498 write_scene->SetParameter (parameter); 500 write_scene->SetParameter (parameter); 499 501 500 } 502 } 501 virtual ~Messenger() { 503 virtual ~Messenger() { 502 delete write_scene; 504 delete write_scene; 503 } 505 } 504 public: 506 public: 505 virtual void SetNewValue(G4UIcommand* a_cm 507 virtual void SetNewValue(G4UIcommand* a_cmd,G4String a_value) { 506 G4VisManager::Verbosity verbosity = GetV 508 G4VisManager::Verbosity verbosity = GetVisManager()->GetVerbosity(); 507 G4VViewer* viewer = GetVisManager()->Get 509 G4VViewer* viewer = GetVisManager()->GetCurrentViewer(); 508 if (!viewer) { 510 if (!viewer) { 509 if (verbosity >= G4VisManager::errors) 511 if (verbosity >= G4VisManager::errors) G4cerr << "ERROR: No current viewer." << G4endl; 510 return; 512 return; 511 } 513 } 512 G4ToolsSGViewer* tsg_viewer = dynamic_ca 514 G4ToolsSGViewer* tsg_viewer = dynamic_cast<G4ToolsSGViewer*>(viewer); 513 if(!tsg_viewer) { 515 if(!tsg_viewer) { 514 G4cout << "G4ToolsSGViewer::SetNewValu 516 G4cout << "G4ToolsSGViewer::SetNewValue:" 515 << " current viewer is not a G4 517 << " current viewer is not a G4ToolsSGViewer." << G4endl; 516 return; 518 return; 517 } 519 } 518 std::vector<std::string> args; 520 std::vector<std::string> args; 519 tools::double_quotes_tokenize(a_value,ar 521 tools::double_quotes_tokenize(a_value,args); 520 if(args.size()!=a_cmd->GetParameterEntri 522 if(args.size()!=a_cmd->GetParameterEntries()) return; 521 if(a_cmd==write_scene) { 523 if(a_cmd==write_scene) { 522 G4bool do_transparency = G4UIcommand:: 524 G4bool do_transparency = G4UIcommand::ConvertToBool(args[2].c_str()); 523 tsg_viewer->Export(args[0],args[1],do_ 525 tsg_viewer->Export(args[0],args[1],do_transparency); 524 } 526 } 525 } 527 } 526 private: 528 private: 527 G4UIcommand* write_scene; 529 G4UIcommand* write_scene; 528 }; 530 }; 529 531 530 protected: 532 protected: 531 SG_SESSION& fSGSession; 533 SG_SESSION& fSGSession; 532 G4ToolsSGSceneHandler& fSGSceneHandler; 534 G4ToolsSGSceneHandler& fSGSceneHandler; 533 SG_VIEWER* fSGViewer; 535 SG_VIEWER* fSGViewer; 534 G4ViewParameters fLastVP; // Memory for mak 536 G4ViewParameters fLastVP; // Memory for making kernel visit decisions. 535 537 536 G4bool fKeyPressed; 538 G4bool fKeyPressed; 537 G4bool fKeyShift; 539 G4bool fKeyShift; 538 G4bool fMousePressed; 540 G4bool fMousePressed; 539 G4double fMousePressedX, fMousePressedY; 541 G4double fMousePressedX, fMousePressedY; 540 542 541 tools::sg::zb_manager f_zb_mgr; 543 tools::sg::zb_manager f_zb_mgr; 542 tools::sg::gl2ps_manager f_gl2ps_mgr; 544 tools::sg::gl2ps_manager f_gl2ps_mgr; 543 545 544 }; 546 }; 545 547 546 #endif 548 #endif 547 549