Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/visualization/Qt3D/src/G4Qt3DSceneHandler.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /visualization/Qt3D/src/G4Qt3DSceneHandler.cc (Version 11.3.0) and /visualization/Qt3D/src/G4Qt3DSceneHandler.cc (Version 10.7.p1)


  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  17th June 2019                    26 // John Allison  17th June 2019
 27                                                    27 
                                                   >>  28 #if defined (G4VIS_BUILD_QT3D_DRIVER) || defined (G4VIS_USE_QT3D)
                                                   >>  29 
 28 #include "G4Qt3DSceneHandler.hh"                   30 #include "G4Qt3DSceneHandler.hh"
 29                                                    31 
 30 #include "G4PhysicalVolumeModel.hh"                32 #include "G4PhysicalVolumeModel.hh"
 31 #include "G4LogicalVolumeModel.hh"                 33 #include "G4LogicalVolumeModel.hh"
 32 #include "G4VPhysicalVolume.hh"                    34 #include "G4VPhysicalVolume.hh"
 33 #include "G4LogicalVolume.hh"                      35 #include "G4LogicalVolume.hh"
 34 #include "G4TransportationManager.hh"              36 #include "G4TransportationManager.hh"
 35 #include "G4Box.hh"                                37 #include "G4Box.hh"
 36 #include "G4Polyline.hh"                           38 #include "G4Polyline.hh"
 37 #include "G4Polymarker.hh"                         39 #include "G4Polymarker.hh"
 38 #include "G4Text.hh"                               40 #include "G4Text.hh"
 39 #include "G4Circle.hh"                             41 #include "G4Circle.hh"
 40 #include "G4Square.hh"                             42 #include "G4Square.hh"
 41 #include "G4Polyhedron.hh"                         43 #include "G4Polyhedron.hh"
 42 #include "G4Scene.hh"                              44 #include "G4Scene.hh"
 43 #include "G4Threading.hh"                          45 #include "G4Threading.hh"
 44 #include "G4Mesh.hh"                           << 
 45 #include "G4PseudoScene.hh"                    << 
 46 #include "G4VisManager.hh"                     << 
 47                                                    46 
 48 #include "G4Qt3DViewer.hh"                         47 #include "G4Qt3DViewer.hh"
 49 #include "G4Qt3DUtils.hh"                          48 #include "G4Qt3DUtils.hh"
 50 #include "G4Qt3DQEntity.hh"                        49 #include "G4Qt3DQEntity.hh"
 51                                                    50 
 52 #include <Qt3DCore>                                51 #include <Qt3DCore>
 53 #include <Qt3DExtras>                              52 #include <Qt3DExtras>
 54 #include <Qt3DRender>                              53 #include <Qt3DRender>
 55                                                    54 
 56 #include <utility>                                 55 #include <utility>
 57                                                    56 
 58 #define G4warn G4cout                          << 
 59                                                << 
 60 // Qt3D seems to offer a choice of type - floa     57 // Qt3D seems to offer a choice of type - float or double. It would be nice
 61 // to use double since it offers the prospect      58 // to use double since it offers the prospect of higher precision, hopefully
 62 // avoiding some issues that we see at high zo     59 // avoiding some issues that we see at high zoom. But it currently gives the
 63 // following warning:                          <<  60 // following warning: "findBoundingVolumeComputeData: Position attribute not
 64 // Qt5: "findBoundingVolumeComputeData: Positi <<  61 // suited for bounding volume computation", so for now we use float.
 65 // suited for bounding volume computation",    << 
 66 // Qt6: "Failed to build graphics pipeline: Ge << 
 67 // An attribute type is not supported "vertexP << 
 68 // so for now we use float.                    << 
 69 #define PRECISION float                            62 #define PRECISION float
 70 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))   << 
 71 #define BASETYPE Qt3DRender::QAttribute::Float     63 #define BASETYPE Qt3DRender::QAttribute::Float
 72 #else                                          << 
 73 #define BASETYPE Qt3DCore::QAttribute::Float   << 
 74 #endif                                         << 
 75                                                << 
 76 // Qt3D types move between namespaces between  << 
 77 namespace G4Qt3DCompat                         << 
 78 {                                              << 
 79 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))   << 
 80   using Qt3DRender::QAttribute;                << 
 81   using Qt3DRender::QBuffer;                   << 
 82   using Qt3DRender::QGeometry;                 << 
 83 #else                                          << 
 84   using Qt3DCore::QAttribute;                  << 
 85   using Qt3DCore::QBuffer;                     << 
 86   using Qt3DCore::QGeometry;                   << 
 87 #endif                                         << 
 88 }                                              << 
 89                                                    64 
 90 G4int G4Qt3DSceneHandler::fSceneIdCount = 0;       65 G4int G4Qt3DSceneHandler::fSceneIdCount = 0;
 91                                                    66 
 92 G4Qt3DSceneHandler::G4Qt3DSceneHandler             67 G4Qt3DSceneHandler::G4Qt3DSceneHandler
 93  (G4VGraphicsSystem& system, const G4String& n     68  (G4VGraphicsSystem& system, const G4String& name)
 94 : G4VSceneHandler(system, fSceneIdCount++, nam     69 : G4VSceneHandler(system, fSceneIdCount++, name)
 95 ,fpQt3DScene(nullptr)                          << 
 96 ,fpTransientObjects(nullptr)                   << 
 97 ,fpPersistentObjects(nullptr)                  << 
 98 {                                                  70 {
 99 #ifdef G4QT3DDEBUG                                 71 #ifdef G4QT3DDEBUG
100   G4cout << "G4Qt3DSceneHandler::G4Qt3DSceneHa     72   G4cout << "G4Qt3DSceneHandler::G4Qt3DSceneHandler called" << G4endl;
101 #endif                                             73 #endif
102   fpQt3DScene = new Qt3DCore::QEntity;             74   fpQt3DScene = new Qt3DCore::QEntity;
103   fpQt3DScene->setObjectName("G4Qt3DSceneRoot"     75   fpQt3DScene->setObjectName("G4Qt3DSceneRoot");
104   EstablishG4Qt3DQEntities();                      76   EstablishG4Qt3DQEntities();
105 }                                                  77 }
106                                                    78 
107 G4Qt3DSceneHandler::~G4Qt3DSceneHandler()          79 G4Qt3DSceneHandler::~G4Qt3DSceneHandler()
108 {                                                  80 {
109   if (fpQt3DScene) {                           <<  81   // Doesn't like this - it gives BAD_ACCESS in delete_entity_recursively.
110     G4Qt3DUtils::delete_components_and_childre <<  82   // Curiously the delete traceback shows three calls to this recursively:
111     delete fpQt3DScene;                        <<  83   /*#1  0x0000000100411906 in (anonymous namespace)::delete_entity_recursively(Qt3DCore::QNode*) at /Users/johna/Geant4/geant4-dev/source/visualization/Qt3D/src/G4Qt3DSceneHandler.cc:60
112   }                                            <<  84   #2  0x0000000100411840 in G4Qt3DSceneHandler::~G4Qt3DSceneHandler() at /Users/johna/Geant4/geant4-dev/source/visualization/Qt3D/src/G4Qt3DSceneHandler.cc:169
                                                   >>  85   #3  0x0000000100411fc5 in G4Qt3DSceneHandler::~G4Qt3DSceneHandler() at /Users/johna/Geant4/geant4-dev/source/visualization/Qt3D/src/G4Qt3DSceneHandler.cc:168
                                                   >>  86   #4  0x0000000100411fe9 in G4Qt3DSceneHandler::~G4Qt3DSceneHandler() at /Users/johna/Geant4/geant4-dev/source/visualization/Qt3D/src/G4Qt3DSceneHandler.cc:168
                                                   >>  87   #5  0x0000000101032510 in G4VisManager::~G4VisManager() at /Users/johna/Geant4/geant4-dev/source/visualization/management/src/G4VisManager.cc:214
                                                   >>  88   #6  0x0000000100013885 in G4VisExecutive::~G4VisExecutive() at /Users/johna/Geant4/geant4-dev/source/visualization/management/include/G4VisExecutive.hh:119
                                                   >>  89   #7  0x00000001000119a5 in G4VisExecutive::~G4VisExecutive() at /Users/johna/Geant4/geant4-dev/source/visualization/management/include/G4VisExecutive.hh:119
                                                   >>  90   #8  0x00000001000119c9 in G4VisExecutive::~G4VisExecutive() at /Users/johna/Geant4/geant4-dev/source/visualization/management/include/G4VisExecutive.hh:119
                                                   >>  91   #9  0x00000001000117dd in main at /Users/johna/Geant4/geant4-dev/examples/basic/B1/exampleB1.cc:108
                                                   >>  92   */
                                                   >>  93   //if (fpQt3DScene) delete_entity_recursively(fpQt3DScene);
113 }                                                  94 }
114                                                    95 
115 void G4Qt3DSceneHandler::EstablishG4Qt3DQEntit     96 void G4Qt3DSceneHandler::EstablishG4Qt3DQEntities()
116 {                                                  97 {
117   fpTransientObjects  = new G4Qt3DQEntity(fpQt     98   fpTransientObjects  = new G4Qt3DQEntity(fpQt3DScene);  // Hangs from root
118   fpTransientObjects  ->setObjectName("G4Qt3DT     99   fpTransientObjects  ->setObjectName("G4Qt3DTORoot");
119   fpPersistentObjects = new G4Qt3DQEntity(fpQt    100   fpPersistentObjects = new G4Qt3DQEntity(fpQt3DScene);  // Hangs from root
120   fpPersistentObjects ->setObjectName("G4Qt3DP    101   fpPersistentObjects ->setObjectName("G4Qt3DPORoot");
121                                                   102 
122   // Physical volume objects hang from POs     << 103   // Physical volume objects for each world hang from POs
123   fpPhysicalVolumeObjects.clear();             << 104   G4TransportationManager* transportationManager
124   if (fpScene) {                               << 105   = G4TransportationManager::GetTransportationManager ();
125     const auto& sceneModels = fpScene->GetRunD << 106   size_t nWorlds = transportationManager->GetNoWorlds();
126     for (const auto& sceneModel : sceneModels) << 107   std::vector<G4VPhysicalVolume*>::iterator iterWorld
127       const auto& pvModel = dynamic_cast<G4Phy << 108   = transportationManager->GetWorldsIterator();
128       if (pvModel) {                           << 109   fpPhysicalVolumeObjects.resize(nWorlds);
129         auto entity = new G4Qt3DQEntity(fpPers << 110   for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
130         const auto& pv = pvModel->GetTopPhysic << 111     G4VPhysicalVolume* world = (*iterWorld);
131         entity->setObjectName("G4Qt3DPORoot_"+ << 112     auto entity = new G4Qt3DQEntity(fpPersistentObjects);
132         entity->SetPVNodeID(G4PhysicalVolumeMo << 113     entity->setObjectName("G4Qt3DPORoot_"+QString(world->GetName()));
133         fpPhysicalVolumeObjects.push_back(enti << 114     entity->SetPVNodeID(G4PhysicalVolumeModel::G4PhysicalVolumeNodeID(world));
134       }                                        << 115     fpPhysicalVolumeObjects[i] = entity;
135     }                                          << 
136   }                                               116   }
137 }                                                 117 }
138                                                   118 
139 G4Qt3DQEntity* G4Qt3DSceneHandler::CreateNewNo    119 G4Qt3DQEntity* G4Qt3DSceneHandler::CreateNewNode()
140 {                                              << 120 { // Create a G4Qt3DQEntity node suitable for next solid or primitive
141   // Create a G4Qt3DQEntity node suitable for  << 121 
                                                   >> 122   // Avoid Qt errors in MT mode - see G4Qt3DViewer::SwitchToMasterThread
                                                   >> 123 #ifdef G4MULTITHREADED
                                                   >> 124   if (!G4Threading::IsMasterThread()) return nullptr;
                                                   >> 125 #endif
142                                                   126 
143   G4Qt3DQEntity* newNode = nullptr;               127   G4Qt3DQEntity* newNode = nullptr;
144                                                   128 
145   if (fReadyForTransients) {  // All transient    129   if (fReadyForTransients) {  // All transients hang from this node
146     newNode = new G4Qt3DQEntity(fpTransientObj    130     newNode = new G4Qt3DQEntity(fpTransientObjects);
147     G4String name = fpModel? fpModel->GetGloba << 131     newNode->setObjectName(fpModel->GetGlobalTag().c_str());
148     newNode->setObjectName(name.c_str());      << 
149     return newNode;                               132     return newNode;
150   }                                               133   }
151                                                   134 
152   G4PhysicalVolumeModel* pPVModel =               135   G4PhysicalVolumeModel* pPVModel =
153     dynamic_cast<G4PhysicalVolumeModel*>(fpMod    136     dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
154                                                   137 
155   if (!pPVModel) {  // Persistent objects (e.g    138   if (!pPVModel) {  // Persistent objects (e.g., axes)
156     newNode = new G4Qt3DQEntity(fpPersistentOb    139     newNode = new G4Qt3DQEntity(fpPersistentObjects);
157     newNode->setObjectName(fpModel->GetGlobalT    140     newNode->setObjectName(fpModel->GetGlobalTag().c_str());
158     return newNode;                               141     return newNode;
159   }                                               142   }
160                                                   143 
161   // So this is a G4PhysicalVolumeModel           144   // So this is a G4PhysicalVolumeModel
162                                                   145   
163   typedef G4PhysicalVolumeModel::G4PhysicalVol    146   typedef G4PhysicalVolumeModel::G4PhysicalVolumeNodeID PVNodeID;
164   typedef std::vector<PVNodeID> PVPath;           147   typedef std::vector<PVNodeID> PVPath;
165 //  const PVPath& drawnPVPath = pPVModel->GetD    148 //  const PVPath& drawnPVPath = pPVModel->GetDrawnPVPath();
166   const PVPath& fullPVPath  = pPVModel->GetFul    149   const PVPath& fullPVPath  = pPVModel->GetFullPVPath();
167   //G4int currentDepth = pPVModel->GetCurrentD    150   //G4int currentDepth = pPVModel->GetCurrentDepth();
168   //G4VPhysicalVolume* pCurrentPV = pPVModel->    151   //G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV();
169   //G4LogicalVolume* pCurrentLV = pPVModel->Ge    152   //G4LogicalVolume* pCurrentLV = pPVModel->GetCurrentLV();
170   //G4Material* pCurrentMaterial = pPVModel->G    153   //G4Material* pCurrentMaterial = pPVModel->GetCurrentMaterial();
171   // Note: pCurrentMaterial may be zero (paral    154   // Note: pCurrentMaterial may be zero (parallel world).
172                                                   155 
173 #ifdef G4QTDEBUG                                  156 #ifdef G4QTDEBUG
174   G4cout << "A: " << fullPVPath << G4endl;  //    157   G4cout << "A: " << fullPVPath << G4endl;  // DEBUG
175 #endif                                            158 #endif
176                                                   159 
177   // Find appropriate root                        160   // Find appropriate root
178   const std::size_t nWorlds = fpPhysicalVolume << 161   const size_t nWorlds = fpPhysicalVolumeObjects.size();
179   std::size_t iWorld = 0;                      << 162   size_t iWorld = 0;
180   for (; iWorld < nWorlds; ++iWorld) {            163   for (; iWorld < nWorlds; ++iWorld) {
181     if (fullPVPath[0].GetPhysicalVolume() ==      164     if (fullPVPath[0].GetPhysicalVolume() ==
182         fpPhysicalVolumeObjects[iWorld]->GetPV    165         fpPhysicalVolumeObjects[iWorld]->GetPVNodeID().GetPhysicalVolume()) break;
183   }                                               166   }
184   if (iWorld == nWorlds) {                        167   if (iWorld == nWorlds) {
185     G4Exception("G4Qt3DSceneHandler::CreateNew    168     G4Exception("G4Qt3DSceneHandler::CreateNewNode", "qt3D-0000", FatalException,
186                 "World mis-match - not possibl    169                 "World mis-match - not possible(!?)");
187   }                                               170   }
188                                                   171 
189   // (Re-)establish pv path of root entity        172   // (Re-)establish pv path of root entity
190   G4Qt3DQEntity* wrld = fpPhysicalVolumeObject << 173   G4Qt3DQEntity* world = fpPhysicalVolumeObjects[iWorld];
191   wrld->SetPVNodeID(fullPVPath[0]);            << 174   world->SetPVNodeID(fullPVPath[0]);
192                                                   175 
193   // Create nodes as required                     176   // Create nodes as required
194   G4Qt3DQEntity* node = wrld;                  << 177   G4Qt3DQEntity* node = world;
195   newNode = node;                                 178   newNode = node;
196   const std::size_t depth = fullPVPath.size(); << 179   const size_t depth = fullPVPath.size();
197   std::size_t iDepth = 1;                      << 180   size_t iDepth = 1;
198   while (iDepth < depth) {                        181   while (iDepth < depth) {
199     const auto& children = node->children();      182     const auto& children = node->children();
200     const G4int nChildren = (G4int)children.si << 183     const G4int nChildren = children.size();  // int size() (Qt covention?)
201     G4int iChild = 0;                             184     G4int iChild = 0;
202     G4Qt3DQEntity* child = nullptr;               185     G4Qt3DQEntity* child = nullptr;
203     for (; iChild < nChildren; ++iChild) {        186     for (; iChild < nChildren; ++iChild) {
204       child = static_cast<G4Qt3DQEntity*>(chil    187       child = static_cast<G4Qt3DQEntity*>(children[iChild]);
205       if (child->GetPVNodeID() == fullPVPath[i    188       if (child->GetPVNodeID() == fullPVPath[iDepth]) break;
206     }                                             189     }
207     if (iChild != nChildren) {  // Existing no    190     if (iChild != nChildren) {  // Existing node found
208       node = child;  // Must be the ancestor o    191       node = child;  // Must be the ancestor of new node (subsequent iteration)
209     } else {                                      192     } else {
210       // Add a new node as child of node          193       // Add a new node as child of node
211       newNode = new G4Qt3DQEntity(node);          194       newNode = new G4Qt3DQEntity(node);
212       newNode->SetPVNodeID(fullPVPath[iDepth])    195       newNode->SetPVNodeID(fullPVPath[iDepth]);
213       std::ostringstream oss;                     196       std::ostringstream oss;
214       oss << newNode->GetPVNodeID().GetPhysica    197       oss << newNode->GetPVNodeID().GetPhysicalVolume()->GetName()
215       << ':' << newNode->GetPVNodeID().GetCopy    198       << ':' << newNode->GetPVNodeID().GetCopyNo();
216       newNode->setObjectName(oss.str().c_str()    199       newNode->setObjectName(oss.str().c_str());
217       node = newNode;                             200       node = newNode;
218     }                                             201     }
219     ++iDepth;                                     202     ++iDepth;
220   }                                               203   }
221                                                   204 
222   return node;                                    205   return node;
223 }                                                 206 }
224                                                   207 
225 void G4Qt3DSceneHandler::PreAddSolid              208 void G4Qt3DSceneHandler::PreAddSolid
226  (const G4Transform3D& objectTransformation,      209  (const G4Transform3D& objectTransformation,
227   const G4VisAttributes& visAttribs)              210   const G4VisAttributes& visAttribs)
228 {                                                 211 {  
229   G4VSceneHandler::PreAddSolid(objectTransform    212   G4VSceneHandler::PreAddSolid(objectTransformation, visAttribs);
230 }                                                 213 }
231                                                   214 
232 void G4Qt3DSceneHandler::PostAddSolid()           215 void G4Qt3DSceneHandler::PostAddSolid()
233 {                                                 216 {
234   G4VSceneHandler::PostAddSolid();                217   G4VSceneHandler::PostAddSolid();
235 }                                                 218 }
236                                                   219 
237 void G4Qt3DSceneHandler::BeginPrimitives2D(con    220 void G4Qt3DSceneHandler::BeginPrimitives2D(const G4Transform3D& objectTransformation)
238 {                                                 221 {
239 // The x,y coordinates of the primitives passe    222 // The x,y coordinates of the primitives passed to AddPrimitive are
240 // intrepreted as screen coordinates, -1 < x,y    223 // intrepreted as screen coordinates, -1 < x,y < 1.  The
241 // z-coordinate is ignored.                       224 // z-coordinate is ignored.
242 // IMPORTANT: invoke this from your polymorphi    225 // IMPORTANT: invoke this from your polymorphic versions, e.g.:
243 // void MyXXXSceneHandler::BeginPrimitives2D      226 // void MyXXXSceneHandler::BeginPrimitives2D
244 // (const G4Transform3D& objectTransformation)    227 // (const G4Transform3D& objectTransformation) {
245   static G4bool first = true;                     228   static G4bool first = true;
246   if (first) {                                    229   if (first) {
247     first = false;                                230     first = false;
248     G4Exception("G4Qt3DSceneHandler::BeginPrim    231     G4Exception("G4Qt3DSceneHandler::BeginPrimitives2D", "qt3D-0001",
249                 JustWarning,                      232                 JustWarning,
250                 "2D drawing not yet implemente    233                 "2D drawing not yet implemented");
251   }                                               234   }
252    G4VSceneHandler::BeginPrimitives2D (objectT    235    G4VSceneHandler::BeginPrimitives2D (objectTransformation);
253 //   ...                                          236 //   ...
254 }                                                 237 }
255                                                   238 
256 void G4Qt3DSceneHandler::EndPrimitives2D ()       239 void G4Qt3DSceneHandler::EndPrimitives2D ()
257 {                                                 240 {
258 // IMPORTANT: invoke this from your polymorphi    241 // IMPORTANT: invoke this from your polymorphic versions, e.g.:
259 // void MyXXXSceneHandler::EndPrimitives2D ()     242 // void MyXXXSceneHandler::EndPrimitives2D () {
260 //   ...                                          243 //   ...
261   G4VSceneHandler::EndPrimitives2D ();            244   G4VSceneHandler::EndPrimitives2D ();
262 }                                                 245 }
263                                                   246 
264 void G4Qt3DSceneHandler::BeginPrimitives          247 void G4Qt3DSceneHandler::BeginPrimitives
265  (const G4Transform3D& objectTransformation)      248  (const G4Transform3D& objectTransformation)
266 {                                                 249 {
267   G4VSceneHandler::BeginPrimitives(objectTrans    250   G4VSceneHandler::BeginPrimitives(objectTransformation);
268 }                                                 251 }
269                                                   252 
270 void G4Qt3DSceneHandler::EndPrimitives ()         253 void G4Qt3DSceneHandler::EndPrimitives ()
271 {                                                 254 {
272   G4VSceneHandler::EndPrimitives ();              255   G4VSceneHandler::EndPrimitives ();
273 }                                                 256 }
274                                                   257 
275 void G4Qt3DSceneHandler::AddPrimitive(const G4    258 void G4Qt3DSceneHandler::AddPrimitive(const G4Polyline& polyline)
276 {                                                 259 {
277 #ifdef G4QT3DDEBUG                                260 #ifdef G4QT3DDEBUG
278   G4cout <<                                       261   G4cout <<
279   "G4Qt3DSceneHandler::AddPrimitive(const G4Po    262   "G4Qt3DSceneHandler::AddPrimitive(const G4Polyline& polyline) called.\n"
280   << polyline                                     263   << polyline
281   << G4endl;                                      264   << G4endl;
282 #endif                                            265 #endif
283                                                   266   
284   if (polyline.size() == 0) return;            << 
285                                                << 
286   auto currentNode = CreateNewNode();             267   auto currentNode = CreateNewNode();
287   if (!currentNode) {                          << 268   if (!currentNode) return;  // Node not available
288     static G4bool first = true;                << 269 
289     if (first) {                               << 270   if (polyline.size() == 0) return;
290       first = false;                           << 
291       G4Exception("G4Qt3DSceneHandler::AddPrim << 
292       "qt3d-0003", JustWarning,                << 
293       "No available node!");                   << 
294     }                                          << 
295     return;                                    << 
296   }                                            << 
297                                                   271 
298   fpVisAttribs = fpViewer->GetApplicableVisAtt    272   fpVisAttribs = fpViewer->GetApplicableVisAttributes(polyline.GetVisAttributes());
299                                                   273 
300   auto transform = G4Qt3DUtils::CreateQTransfo    274   auto transform = G4Qt3DUtils::CreateQTransformFrom(fObjectTransformation);
301   transform->setObjectName("transform");          275   transform->setObjectName("transform");
302                                                   276 
303   auto polylineEntity = new Qt3DCore::QEntity(    277   auto polylineEntity = new Qt3DCore::QEntity(currentNode);
304   polylineEntity->addComponent(transform);        278   polylineEntity->addComponent(transform);
305                                                   279 
306   const auto vertexByteSize  = 3*sizeof(PRECIS    280   const auto vertexByteSize  = 3*sizeof(PRECISION);
307                                                   281 
308   const std::size_t nLines = polyline.size() - << 282   const size_t nLines = polyline.size() - 1;
309   QByteArray polylineByteArray;                   283   QByteArray polylineByteArray;
310   const auto polylineBufferByteSize = 2*nLines    284   const auto polylineBufferByteSize = 2*nLines*vertexByteSize;
311   polylineByteArray.resize((G4int)polylineBuff << 285   polylineByteArray.resize(polylineBufferByteSize);
312   auto polylineBufferArray = reinterpret_cast<    286   auto polylineBufferArray = reinterpret_cast<PRECISION*>(polylineByteArray.data());
313   G4int iLine = 0;                                287   G4int iLine = 0;
314   for (std::size_t i = 0; i < nLines; ++i) {   << 288   for (size_t i = 0; i < nLines; ++i) {
315     polylineBufferArray[iLine++] = polyline[i]    289     polylineBufferArray[iLine++] = polyline[i].x();
316     polylineBufferArray[iLine++] = polyline[i]    290     polylineBufferArray[iLine++] = polyline[i].y();
317     polylineBufferArray[iLine++] = polyline[i]    291     polylineBufferArray[iLine++] = polyline[i].z();
318     polylineBufferArray[iLine++] = polyline[i+    292     polylineBufferArray[iLine++] = polyline[i+1].x();
319     polylineBufferArray[iLine++] = polyline[i+    293     polylineBufferArray[iLine++] = polyline[i+1].y();
320     polylineBufferArray[iLine++] = polyline[i+    294     polylineBufferArray[iLine++] = polyline[i+1].z();
321   }                                               295   }
322   auto polylineGeometry = new G4Qt3DCompat::QG << 296   auto polylineGeometry = new Qt3DRender::QGeometry();
323   polylineGeometry->setObjectName("polylineGeo    297   polylineGeometry->setObjectName("polylineGeometry");
324                                                << 298   auto polylineBuffer = new Qt3DRender::QBuffer(polylineGeometry);
325   auto polylineBuffer = new G4Qt3DCompat::QBuf << 
326   polylineBuffer->setObjectName("Polyline buff    299   polylineBuffer->setObjectName("Polyline buffer");
327   polylineBuffer->setData(polylineByteArray);     300   polylineBuffer->setData(polylineByteArray);
328                                                   301 
329   auto polylineAtt = new G4Qt3DCompat::QAttrib << 302   auto polylineAtt = new Qt3DRender::QAttribute;
330   polylineAtt->setObjectName("Position attribu    303   polylineAtt->setObjectName("Position attribute");
331   polylineAtt->setName(G4Qt3DCompat::QAttribut << 304   polylineAtt->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
332   polylineAtt->setBuffer(polylineBuffer);         305   polylineAtt->setBuffer(polylineBuffer);
333   polylineAtt->setAttributeType(G4Qt3DCompat:: << 306   polylineAtt->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
334   polylineAtt->setVertexBaseType(BASETYPE);       307   polylineAtt->setVertexBaseType(BASETYPE);
335   polylineAtt->setVertexSize(3);                  308   polylineAtt->setVertexSize(3);
336   polylineAtt->setCount((G4int)nLines);        << 309   polylineAtt->setCount(nLines);
337   polylineAtt->setByteOffset(0);                  310   polylineAtt->setByteOffset(0);
338   polylineAtt->setByteStride(vertexByteSize);     311   polylineAtt->setByteStride(vertexByteSize);
339   // Normal attribute (a dummy with count==0)  << 
340   auto dummyNormalLineAtt = new G4Qt3DCompat:: << 
341   dummyNormalLineAtt->setObjectName("Normal at << 
342   dummyNormalLineAtt->setName(G4Qt3DCompat::QA << 
343   dummyNormalLineAtt->setBuffer(polylineBuffer << 
344   dummyNormalLineAtt->setAttributeType(G4Qt3DC << 
345   dummyNormalLineAtt->setVertexBaseType(BASETY << 
346   dummyNormalLineAtt->setVertexSize(3);        << 
347   dummyNormalLineAtt->setCount(0);             << 
348   dummyNormalLineAtt->setByteOffset(0);        << 
349   dummyNormalLineAtt->setByteStride(vertexByte << 
350                                                   312 
351   const auto& colour = fpVisAttribs->GetColour    313   const auto& colour = fpVisAttribs->GetColour();
352                                                   314 
353   polylineGeometry->addAttribute(polylineAtt);    315   polylineGeometry->addAttribute(polylineAtt);
354   polylineGeometry->addAttribute(dummyNormalLi << 
355                                                   316 
356   auto material = new Qt3DExtras::QDiffuseSpec    317   auto material = new Qt3DExtras::QDiffuseSpecularMaterial();
357   material->setObjectName("materialForPolyline    318   material->setObjectName("materialForPolyline");
358   material->setAmbient(G4Qt3DUtils::ConvertToQ    319   material->setAmbient(G4Qt3DUtils::ConvertToQColor(colour));
359   material->setShininess(0.);                     320   material->setShininess(0.);
360   material->setSpecular(0.);                      321   material->setSpecular(0.);
361   polylineEntity->addComponent(material);         322   polylineEntity->addComponent(material);
362                                                   323 
363   auto renderer = new Qt3DRender::QGeometryRen    324   auto renderer = new Qt3DRender::QGeometryRenderer;
364   renderer->setObjectName("polylineRenderer"); << 325   renderer->setObjectName("polyhedronWireframeRenderer");
365   renderer->setGeometry(polylineGeometry);        326   renderer->setGeometry(polylineGeometry);
366   renderer->setVertexCount(2*(G4int)nLines);   << 327   renderer->setVertexCount(2*nLines);
367   renderer->setPrimitiveType(Qt3DRender::QGeom    328   renderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines);
368   polylineEntity->addComponent(renderer);         329   polylineEntity->addComponent(renderer);
369 }                                                 330 }
370                                                   331 
371 void G4Qt3DSceneHandler::AddPrimitive (const G    332 void G4Qt3DSceneHandler::AddPrimitive (const G4Polymarker& polymarker)
372 {                                                 333 {
373   if (polymarker.size() == 0) return;          << 
374                                                << 
375   auto currentNode = CreateNewNode();             334   auto currentNode = CreateNewNode();
376   if (!currentNode) {                          << 335   if (!currentNode) return;  // Node not available
377     static G4bool first = true;                << 
378     if (first) {                               << 
379       first = false;                           << 
380       G4Exception("G4Qt3DSceneHandler::AddPrim << 
381       "qt3d-0003", JustWarning,                << 
382       "No available node!");                   << 
383     }                                          << 
384     return;                                    << 
385   }                                            << 
386                                                   336 
387   fpVisAttribs = fpViewer->GetApplicableVisAtt << 337   if (polymarker.size() == 0) return;
388                                                   338 
389   MarkerSizeType markerSizeType;               << 339   fpVisAttribs = fpViewer->GetApplicableVisAttributes(polymarker.GetVisAttributes());
390   G4double markerSize = GetMarkerSize(polymark << 
391                                                   340 
392   switch (polymarker.GetMarkerType()) {           341   switch (polymarker.GetMarkerType()) {
393     default:                                      342     default:
394     case G4Polymarker::dots:                      343     case G4Polymarker::dots:
395     {                                             344     {
396       const std::size_t nDots = polymarker.siz << 345       const size_t nDots = polymarker.size();
397                                                   346 
398       auto transform = G4Qt3DUtils::CreateQTra    347       auto transform = G4Qt3DUtils::CreateQTransformFrom(fObjectTransformation);
399       transform->setObjectName("transform");      348       transform->setObjectName("transform");
400                                                   349 
401       auto polymarkerEntity = new Qt3DCore::QE    350       auto polymarkerEntity = new Qt3DCore::QEntity(currentNode);
402       polymarkerEntity->addComponent(transform    351       polymarkerEntity->addComponent(transform);
403                                                   352 
404       const auto vertexByteSize  = 3*sizeof(PR    353       const auto vertexByteSize  = 3*sizeof(PRECISION);
405                                                   354 
406       QByteArray polymarkerByteArray;             355       QByteArray polymarkerByteArray;
407       const auto polymarkerBufferByteSize = nD    356       const auto polymarkerBufferByteSize = nDots*vertexByteSize;
408       polymarkerByteArray.resize((G4int)polyma << 357       polymarkerByteArray.resize(polymarkerBufferByteSize);
409       auto polymarkerBufferArray = reinterpret    358       auto polymarkerBufferArray = reinterpret_cast<PRECISION*>(polymarkerByteArray.data());
410       G4int iMarker = 0;                          359       G4int iMarker = 0;
411       for (std::size_t i = 0; i < polymarker.s << 360       for (size_t i = 0; i < polymarker.size(); ++i) {
412         polymarkerBufferArray[iMarker++] = pol    361         polymarkerBufferArray[iMarker++] = polymarker[i].x();
413         polymarkerBufferArray[iMarker++] = pol    362         polymarkerBufferArray[iMarker++] = polymarker[i].y();
414         polymarkerBufferArray[iMarker++] = pol    363         polymarkerBufferArray[iMarker++] = polymarker[i].z();
415       }                                           364       }
416       auto polymarkerGeometry = new G4Qt3DComp << 365       auto polymarkerGeometry = new Qt3DRender::QGeometry();
417       polymarkerGeometry->setObjectName("polym    366       polymarkerGeometry->setObjectName("polymarkerGeometry");
418       auto polymarkerBuffer = new G4Qt3DCompat << 367       auto polymarkerBuffer = new Qt3DRender::QBuffer(polymarkerGeometry);
419       polymarkerBuffer->setObjectName("Polymar    368       polymarkerBuffer->setObjectName("Polymarker buffer");
420       polymarkerBuffer->setData(polymarkerByte    369       polymarkerBuffer->setData(polymarkerByteArray);
421                                                   370 
422       auto polymarkerAtt = new G4Qt3DCompat::Q << 371       auto polymarkerAtt = new Qt3DRender::QAttribute;
423       polymarkerAtt->setObjectName("Position a    372       polymarkerAtt->setObjectName("Position attribute");
424       polymarkerAtt->setName(G4Qt3DCompat::QAt << 373       polymarkerAtt->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
425       polymarkerAtt->setBuffer(polymarkerBuffe    374       polymarkerAtt->setBuffer(polymarkerBuffer);
426       polymarkerAtt->setAttributeType(G4Qt3DCo << 375       polymarkerAtt->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
427       polymarkerAtt->setVertexBaseType(BASETYP    376       polymarkerAtt->setVertexBaseType(BASETYPE);
428       polymarkerAtt->setVertexSize(3);            377       polymarkerAtt->setVertexSize(3);
429       polymarkerAtt->setCount((G4int)nDots);   << 378       polymarkerAtt->setCount(nDots);
430       polymarkerAtt->setByteOffset(0);            379       polymarkerAtt->setByteOffset(0);
431       polymarkerAtt->setByteStride(vertexByteS    380       polymarkerAtt->setByteStride(vertexByteSize);
432                                                   381 
433       const auto& colour = fpVisAttribs->GetCo    382       const auto& colour = fpVisAttribs->GetColour();
434                                                   383 
435       polymarkerGeometry->addAttribute(polymar    384       polymarkerGeometry->addAttribute(polymarkerAtt);
436                                                   385 
437       auto material = new Qt3DExtras::QDiffuse    386       auto material = new Qt3DExtras::QDiffuseSpecularMaterial();
438       material->setObjectName("materialForPoly    387       material->setObjectName("materialForPolymarker");
439       material->setAmbient(G4Qt3DUtils::Conver    388       material->setAmbient(G4Qt3DUtils::ConvertToQColor(colour));
440       material->setShininess(0.);                 389       material->setShininess(0.);
441       material->setSpecular(0.);                  390       material->setSpecular(0.);
442       polymarkerEntity->addComponent(material)    391       polymarkerEntity->addComponent(material);
443                                                   392 
444       auto renderer = new Qt3DRender::QGeometr    393       auto renderer = new Qt3DRender::QGeometryRenderer;
445       renderer->setObjectName("polymarkerWiref    394       renderer->setObjectName("polymarkerWireframeRenderer");
446       renderer->setGeometry(polymarkerGeometry    395       renderer->setGeometry(polymarkerGeometry);
447       renderer->setVertexCount((G4int)nDots);  << 396       renderer->setVertexCount(nDots);
448       renderer->setPrimitiveType(Qt3DRender::Q    397       renderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Points);
449       polymarkerEntity->addComponent(renderer)    398       polymarkerEntity->addComponent(renderer);
450     }                                             399     }
451       break;                                      400       break;
452     case G4Polymarker::circles:                   401     case G4Polymarker::circles:
453     {                                             402     {
454       G4Circle circle (polymarker);  // Defaul    403       G4Circle circle (polymarker);  // Default circle
455                                                   404 
456       const auto& colour = fpVisAttribs->GetCo    405       const auto& colour = fpVisAttribs->GetColour();
457       auto material = new Qt3DExtras::QDiffuse    406       auto material = new Qt3DExtras::QDiffuseSpecularMaterial();
458       material->setObjectName("materialForCirc    407       material->setObjectName("materialForCircle");
459       material->setAmbient(G4Qt3DUtils::Conver    408       material->setAmbient(G4Qt3DUtils::ConvertToQColor(colour));
460       if (colour.GetAlpha() < 1.) material->se    409       if (colour.GetAlpha() < 1.) material->setAlphaBlendingEnabled(true);
461                                                   410 
462       auto sphereMesh = new Qt3DExtras::QSpher    411       auto sphereMesh = new Qt3DExtras::QSphereMesh;
463       sphereMesh->setObjectName("sphereMesh");    412       sphereMesh->setObjectName("sphereMesh");
464       G4double radius = markerSize/2.;         << 413       G4double radius;
465       if (markerSizeType == G4VSceneHandler::s << 414       if (circle.GetSizeType() == G4VMarker::world ) {
                                                   >> 415         radius =circle.GetWorldRadius();
                                                   >> 416       } else {  // Screen-size or none
466         // Not figured out how to do screen-si    417         // Not figured out how to do screen-size, so use scene extent
467         const G4double scale = 200.;  // Rough << 418         const G4double scale = 200.;  // Roughly pixles per scene
468         radius *= fpScene->GetExtent().GetExte << 419         radius = circle.GetScreenRadius()*fpScene->GetExtent().GetExtentRadius()/scale;
469       }                                           420       }
470       sphereMesh->setRadius(radius);              421       sphereMesh->setRadius(radius);
471 //      sphereMesh->setInstanceCount(polymarke << 
472                                                   422 
473 //      auto currentEntity = new Qt3DCore::QEn << 423       for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
474       for (std::size_t iPoint = 0; iPoint < po << 
475         auto position = fObjectTransformation*    424         auto position = fObjectTransformation*G4Translate3D(polymarker[iPoint]);
476         auto transform = G4Qt3DUtils::CreateQT    425         auto transform = G4Qt3DUtils::CreateQTransformFrom(position);
477   auto currentEntity = new Qt3DCore::QEntity(c << 426         auto currentEntity = new Qt3DCore::QEntity(currentNode);
478         currentEntity->addComponent(material);    427         currentEntity->addComponent(material);
479         currentEntity->addComponent(transform)    428         currentEntity->addComponent(transform);
480         currentEntity->addComponent(sphereMesh    429         currentEntity->addComponent(sphereMesh);
481       }                                           430       }
482     }                                             431     }
483       break;                                      432       break;
484     case G4Polymarker::squares:                   433     case G4Polymarker::squares:
485     {                                             434     {
486       G4Square square (polymarker);  // Defaul    435       G4Square square (polymarker);  // Default square
487                                                   436 
488       const auto& colour = fpVisAttribs->GetCo    437       const auto& colour = fpVisAttribs->GetColour();
489       auto material = new Qt3DExtras::QDiffuse    438       auto material = new Qt3DExtras::QDiffuseSpecularMaterial();
490       material->setObjectName("materialForSqua    439       material->setObjectName("materialForSquare");
491       material->setAmbient(G4Qt3DUtils::Conver    440       material->setAmbient(G4Qt3DUtils::ConvertToQColor(colour));
492       if (colour.GetAlpha() < 1.) material->se    441       if (colour.GetAlpha() < 1.) material->setAlphaBlendingEnabled(true);
493                                                   442 
494       auto boxMesh = new Qt3DExtras::QCuboidMe    443       auto boxMesh = new Qt3DExtras::QCuboidMesh();
495       boxMesh->setObjectName("boxMesh");          444       boxMesh->setObjectName("boxMesh");
496       G4double side = markerSize;              << 445       G4double side;
497       if (markerSizeType == G4VSceneHandler::s << 446       if (square.GetSizeType() == G4VMarker::world ) {
                                                   >> 447         side = square.GetWorldDiameter();
                                                   >> 448       } else {  // Screen-size or none
498         // Not figured out how to do screen-si    449         // Not figured out how to do screen-size, so use scene extent
499         const G4double scale = 200.;  // Rough    450         const G4double scale = 200.;  // Roughly pixles per scene
500         side *= fpScene->GetExtent().GetExtent << 451         side = square.GetScreenDiameter()*fpScene->GetExtent().GetExtentRadius()/scale;
501       }                                           452       }
502       boxMesh->setXExtent(side);                  453       boxMesh->setXExtent(side);
503       boxMesh->setYExtent(side);                  454       boxMesh->setYExtent(side);
504       boxMesh->setZExtent(side);                  455       boxMesh->setZExtent(side);
505                                                   456 
506       for (std::size_t iPoint = 0; iPoint < po << 457       for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
507         auto position = fObjectTransformation*    458         auto position = fObjectTransformation*G4Translate3D(polymarker[iPoint]);
508         auto transform = G4Qt3DUtils::CreateQT    459         auto transform = G4Qt3DUtils::CreateQTransformFrom(position);
509         auto currentEntity = new Qt3DCore::QEn    460         auto currentEntity = new Qt3DCore::QEntity(currentNode);
510         currentEntity->addComponent(material);    461         currentEntity->addComponent(material);
511         currentEntity->addComponent(transform)    462         currentEntity->addComponent(transform);
512         currentEntity->addComponent(boxMesh);     463         currentEntity->addComponent(boxMesh);
513       }                                           464       }
514     }                                             465     }
515       break;                                      466       break;
516   }                                               467   }
517 }                                                 468 }
518                                                   469 
519 #ifdef G4QT3DDEBUG                             << 
520 void G4Qt3DSceneHandler::AddPrimitive(const G4    470 void G4Qt3DSceneHandler::AddPrimitive(const G4Text& text) {
                                                   >> 471 #ifdef G4QT3DDEBUG
521   G4cout <<                                       472   G4cout <<
522   "G4Qt3DSceneHandler::AddPrimitive(const G4Te    473   "G4Qt3DSceneHandler::AddPrimitive(const G4Text& text) called.\n"
523   << text                                         474   << text
524   << G4endl;                                      475   << G4endl;
525 #else                                          << 
526 void G4Qt3DSceneHandler::AddPrimitive(const G4 << 
527 #endif                                            476 #endif
528                                                   477 
529   static G4bool first = true;                     478   static G4bool first = true;
530   if (first) {                                    479   if (first) {
531     first = false;                                480     first = false;
532     G4Exception("G4Qt3DSceneHandler::AddPrimit << 481     G4Exception("G4Qt3DSceneHandler::AddPrimitive(const G4Text& text)",
533                 "qt3D-0002", JustWarning,         482                 "qt3D-0002", JustWarning,
534                 "Text drawing doesn't work yet    483                 "Text drawing doesn't work yet");
535   }  // OK. Not working, but let it execute, w    484   }  // OK. Not working, but let it execute, which it does without error.
536                                                   485 
537   /* But it crashes after /vis/viewer/rebuild! << 
538   auto currentNode = CreateNewNode();             486   auto currentNode = CreateNewNode();
539    if (!currentNode) {                         << 487   if (!currentNode) return;  // Node not available
540    static G4bool first = true;                 << 
541    if (first) {                                << 
542    first = false;                              << 
543    G4Exception("G4Qt3DSceneHandler::AddPrimiti << 
544    "qt3d-0003", JustWarning,                   << 
545    "No available node!");                      << 
546    }                                           << 
547    return;                                     << 
548    }                                           << 
549                                                   488 
550   fpVisAttribs = fpViewer->GetApplicableVisAtt    489   fpVisAttribs = fpViewer->GetApplicableVisAttributes(text.GetVisAttributes());
551                                                   490 
552   auto position = fObjectTransformation*G4Tran    491   auto position = fObjectTransformation*G4Translate3D(text.GetPosition());
553   auto transform = G4Qt3DUtils::CreateQTransfo    492   auto transform = G4Qt3DUtils::CreateQTransformFrom(position);
554 //  transform->setScale(10);                   << 493   transform->setScale(10);
555   transform->setScale(0.1);                    << 
556                                                   494 
557 //  auto currentEntity = new Qt3DCore::QEntity    495 //  auto currentEntity = new Qt3DCore::QEntity(currentNode);
558                                                   496 
559   // This simply does not work                    497   // This simply does not work
560   auto qtext = new Qt3DExtras::QText2DEntity()    498   auto qtext = new Qt3DExtras::QText2DEntity();
561   qtext->setParent(currentNode);                  499   qtext->setParent(currentNode);
562 //  qtext->setParent(currentEntity);  // ??  D    500 //  qtext->setParent(currentEntity);  // ??  Doesn't help
563   qtext->setText(text.GetText().c_str());         501   qtext->setText(text.GetText().c_str());
564 //  qtext->setHeight(100);                     << 502   qtext->setHeight(100);
565 //  qtext->setWidth(1000);                     << 503   qtext->setWidth(1000);
566   qtext->setHeight(20);                        << 
567   qtext->setWidth(100);                        << 
568   qtext->setColor(Qt::green);                     504   qtext->setColor(Qt::green);
569   qtext->setFont(QFont("Courier New", 10));       505   qtext->setFont(QFont("Courier New", 10));
570   qtext->addComponent(transform);                 506   qtext->addComponent(transform);
571                                                   507 
572   // This produces text in 3D facing +z - not     508   // This produces text in 3D facing +z - not what we want
573 //  const auto& colour = GetTextColour(text);     509 //  const auto& colour = GetTextColour(text);
574 //  auto material = new Qt3DExtras::QDiffuseSp    510 //  auto material = new Qt3DExtras::QDiffuseSpecularMaterial();
575 //  material->setObjectName("materialForText")    511 //  material->setObjectName("materialForText");
576 //  material->setAmbient(G4Qt3DUtils::ConvertT    512 //  material->setAmbient(G4Qt3DUtils::ConvertToQColor(colour));
577 //  if (colour.GetAlpha() < 1.) material->setA    513 //  if (colour.GetAlpha() < 1.) material->setAlphaBlendingEnabled(true);
578 //                                                514 //
579 //  auto textMesh = new Qt3DExtras::QExtrudedT    515 //  auto textMesh = new Qt3DExtras::QExtrudedTextMesh();
580 //  textMesh->setText(text.GetText().c_str());    516 //  textMesh->setText(text.GetText().c_str());
581 //  textMesh->setFont(QFont("Courier New", 10)    517 //  textMesh->setFont(QFont("Courier New", 10));
582 //  textMesh->setDepth(.01f);                     518 //  textMesh->setDepth(.01f);
583 //                                                519 //
584 //  currentNode->addComponent(material);          520 //  currentNode->addComponent(material);
585 //  currentNode->addComponent(transform);         521 //  currentNode->addComponent(transform);
586 //  currentNode->addComponent(textMesh);          522 //  currentNode->addComponent(textMesh);
587    */                                          << 
588 }                                                 523 }
589                                                   524 
590 void G4Qt3DSceneHandler::AddPrimitive(const G4    525 void G4Qt3DSceneHandler::AddPrimitive(const G4Circle& circle)
591 {                                                 526 {
592 #ifdef G4QT3DDEBUG                                527 #ifdef G4QT3DDEBUG
593   G4cout <<                                       528   G4cout <<
594   "G4Qt3DSceneHandler::AddPrimitive(const G4Ci    529   "G4Qt3DSceneHandler::AddPrimitive(const G4Circle& circle) called.\n"
595   << circle                                       530   << circle
596   << G4endl;                                      531   << G4endl;
597 #endif                                            532 #endif
598                                                   533 
599 #ifdef G4QT3DDEBUG                                534 #ifdef G4QT3DDEBUG
600   MarkerSizeType sizeType;                        535   MarkerSizeType sizeType;
601   G4double size = GetMarkerSize (circle, sizeT    536   G4double size = GetMarkerSize (circle, sizeType);
602   switch (sizeType) {                             537   switch (sizeType) {
603     default:                                      538     default:
604     case screen:                                  539     case screen:
605       // Draw in screen coordinates.              540       // Draw in screen coordinates.
606       G4cout << "screen";                         541       G4cout << "screen";
607       break;                                      542       break;
608     case world:                                   543     case world:
609       // Draw in world coordinates.               544       // Draw in world coordinates.
610       G4cout << "world";                          545       G4cout << "world";
611       break;                                      546       break;
612   }                                               547   }
613   G4cout << " size: " << size << G4endl;          548   G4cout << " size: " << size << G4endl;
614 #endif                                            549 #endif
615                                                   550 
616   auto currentNode = CreateNewNode();             551   auto currentNode = CreateNewNode();
617   if (!currentNode) {                          << 552   if (!currentNode) return;  // Node not available
618     static G4bool first = true;                << 
619     if (first) {                               << 
620       first = false;                           << 
621       G4Exception("G4Qt3DSceneHandler::AddPrim << 
622       "qt3d-0003", JustWarning,                << 
623       "No available node!");                   << 
624     }                                          << 
625     return;                                    << 
626   }                                            << 
627                                                   553 
628   fpVisAttribs = fpViewer->GetApplicableVisAtt    554   fpVisAttribs = fpViewer->GetApplicableVisAttributes(circle.GetVisAttributes());
629                                                   555 
630   auto position = fObjectTransformation*G4Tran    556   auto position = fObjectTransformation*G4Translate3D(circle.GetPosition());
631   auto transform = G4Qt3DUtils::CreateQTransfo    557   auto transform = G4Qt3DUtils::CreateQTransformFrom(position);
632                                                   558 
633   const auto& colour = fpVisAttribs->GetColour    559   const auto& colour = fpVisAttribs->GetColour();
634   auto material = new Qt3DExtras::QDiffuseSpec    560   auto material = new Qt3DExtras::QDiffuseSpecularMaterial();
635   material->setObjectName("materialForCircle")    561   material->setObjectName("materialForCircle");
636   material->setAmbient(G4Qt3DUtils::ConvertToQ    562   material->setAmbient(G4Qt3DUtils::ConvertToQColor(colour));
637   if (colour.GetAlpha() < 1.) material->setAlp    563   if (colour.GetAlpha() < 1.) material->setAlphaBlendingEnabled(true);
638                                                   564 
639   auto sphereMesh = new Qt3DExtras::QSphereMes    565   auto sphereMesh = new Qt3DExtras::QSphereMesh;
640   sphereMesh->setObjectName("sphereMesh");        566   sphereMesh->setObjectName("sphereMesh");
641   G4double radius;                                567   G4double radius;
642   if (circle.GetSizeType() == G4VMarker::world    568   if (circle.GetSizeType() == G4VMarker::world ) {
643     radius =circle.GetWorldRadius();              569     radius =circle.GetWorldRadius();
644   } else {  // Screen-size or none                570   } else {  // Screen-size or none
645     // Not figured out how to do screen-size,     571     // Not figured out how to do screen-size, so use scene extent
646     const G4double scale = 200.;  // Roughly p    572     const G4double scale = 200.;  // Roughly pixles per scene
647     radius = circle.GetScreenRadius()*fpScene-    573     radius = circle.GetScreenRadius()*fpScene->GetExtent().GetExtentRadius()/scale;
648   }                                               574   }
649   sphereMesh->setRadius(radius);                  575   sphereMesh->setRadius(radius);
650                                                   576 
651   auto currentEntity = new Qt3DCore::QEntity(c    577   auto currentEntity = new Qt3DCore::QEntity(currentNode);
652   currentEntity->addComponent(material);          578   currentEntity->addComponent(material);
653   currentEntity->addComponent(transform);         579   currentEntity->addComponent(transform);
654   currentEntity->addComponent(sphereMesh);        580   currentEntity->addComponent(sphereMesh);
655 }                                                 581 }
656                                                   582 
657 void G4Qt3DSceneHandler::AddPrimitive(const G4    583 void G4Qt3DSceneHandler::AddPrimitive(const G4Square& square)
658 {                                                 584 {
659 #ifdef G4QT3DDEBUG                                585 #ifdef G4QT3DDEBUG
660   G4cout <<                                       586   G4cout <<
661   "G4Qt3DSceneHandler::AddPrimitive(const G4Sq    587   "G4Qt3DSceneHandler::AddPrimitive(const G4Square& square) called.\n"
662   << square                                       588   << square
663   << G4endl;                                      589   << G4endl;
664 #endif                                            590 #endif
665                                                   591 
666 #ifdef G4QT3DDEBUG                                592 #ifdef G4QT3DDEBUG
667   MarkerSizeType sizeType;                        593   MarkerSizeType sizeType;
668   G4double size = GetMarkerSize (square, sizeT    594   G4double size = GetMarkerSize (square, sizeType);
669   switch (sizeType) {                             595   switch (sizeType) {
670     default:                                      596     default:
671     case screen:                                  597     case screen:
672       // Draw in screen coordinates.              598       // Draw in screen coordinates.
673       G4cout << "screen";                         599       G4cout << "screen";
674       break;                                      600       break;
675     case world:                                   601     case world:
676       // Draw in world coordinates.               602       // Draw in world coordinates.
677       G4cout << "world";                          603       G4cout << "world";
678       break;                                      604       break;
679   }                                               605   }
680   G4cout << " size: " << size << G4endl;          606   G4cout << " size: " << size << G4endl;
681 #endif                                            607 #endif
682                                                   608 
683   auto currentNode = CreateNewNode();             609   auto currentNode = CreateNewNode();
684   if (!currentNode) {                          << 610   if (!currentNode) return;  // Node not available
685     static G4bool first = true;                << 
686     if (first) {                               << 
687       first = false;                           << 
688       G4Exception("G4Qt3DSceneHandler::AddPrim << 
689       "qt3d-0003", JustWarning,                << 
690       "No available node!");                   << 
691     }                                          << 
692     return;                                    << 
693   }                                            << 
694                                                   611 
695   fpVisAttribs = fpViewer->GetApplicableVisAtt    612   fpVisAttribs = fpViewer->GetApplicableVisAttributes(square.GetVisAttributes());
696                                                   613 
697   auto position = fObjectTransformation*G4Tran    614   auto position = fObjectTransformation*G4Translate3D(square.GetPosition());
698   auto transform = G4Qt3DUtils::CreateQTransfo    615   auto transform = G4Qt3DUtils::CreateQTransformFrom(position);
699                                                   616 
700   const auto& colour = fpVisAttribs->GetColour    617   const auto& colour = fpVisAttribs->GetColour();
701   auto material = new Qt3DExtras::QDiffuseSpec    618   auto material = new Qt3DExtras::QDiffuseSpecularMaterial();
702   material->setObjectName("materialForSquare")    619   material->setObjectName("materialForSquare");
703   material->setAmbient(G4Qt3DUtils::ConvertToQ    620   material->setAmbient(G4Qt3DUtils::ConvertToQColor(colour));
704   if (colour.GetAlpha() < 1.) material->setAlp    621   if (colour.GetAlpha() < 1.) material->setAlphaBlendingEnabled(true);
705                                                   622 
706   auto boxMesh = new Qt3DExtras::QCuboidMesh()    623   auto boxMesh = new Qt3DExtras::QCuboidMesh();
707   boxMesh->setObjectName("boxMesh");              624   boxMesh->setObjectName("boxMesh");
708   G4double side;                                  625   G4double side;
709   if (square.GetSizeType() == G4VMarker::world    626   if (square.GetSizeType() == G4VMarker::world ) {
710     side = square.GetWorldDiameter();             627     side = square.GetWorldDiameter();
711   } else {  // Screen-size or none                628   } else {  // Screen-size or none
712     // Not figured out how to do screen-size,     629     // Not figured out how to do screen-size, so use scene extent
713     const G4double scale = 200.;  // Roughly p    630     const G4double scale = 200.;  // Roughly pixles per scene
714     side = square.GetScreenDiameter()*fpScene-    631     side = square.GetScreenDiameter()*fpScene->GetExtent().GetExtentRadius()/scale;
715   }                                               632   }
716   boxMesh->setXExtent(side);                      633   boxMesh->setXExtent(side);
717   boxMesh->setYExtent(side);                      634   boxMesh->setYExtent(side);
718   boxMesh->setZExtent(side);                      635   boxMesh->setZExtent(side);
719                                                   636 
720   auto currentEntity = new Qt3DCore::QEntity(c    637   auto currentEntity = new Qt3DCore::QEntity(currentNode);
721   currentEntity->addComponent(material);          638   currentEntity->addComponent(material);
722   currentEntity->addComponent(transform);         639   currentEntity->addComponent(transform);
723   currentEntity->addComponent(boxMesh);           640   currentEntity->addComponent(boxMesh);
724 }                                                 641 }
725                                                   642 
726 void G4Qt3DSceneHandler::AddPrimitive(const G4    643 void G4Qt3DSceneHandler::AddPrimitive(const G4Polyhedron& polyhedron)
727 {                                                 644 {
728   auto currentNode = CreateNewNode();             645   auto currentNode = CreateNewNode();
729   if (!currentNode) {                          << 646   if (!currentNode) return;  // Node not available
730     static G4bool first = true;                << 
731     if (first) {                               << 
732       first = false;                           << 
733       G4Exception("G4Qt3DSceneHandler::AddPrim << 
734       "qt3d-0003", JustWarning,                << 
735       "No available node!");                   << 
736     }                                          << 
737     return;                                    << 
738   }                                            << 
739                                                   647 
740   if (polyhedron.GetNoFacets() == 0) return;      648   if (polyhedron.GetNoFacets() == 0) return;
741                                                   649 
742   fpVisAttribs = fpViewer->GetApplicableVisAtt    650   fpVisAttribs = fpViewer->GetApplicableVisAttributes(polyhedron.GetVisAttributes());
743                                                   651 
744   // Roll out vertices and normals for the fac    652   // Roll out vertices and normals for the faces. Note that this means vertices
745   // are duplicated. For example a box has 8 v    653   // are duplicated. For example a box has 8 vertices, but to define 6 faces
746   // you need 12 triangles and 36 vertices. If    654   // you need 12 triangles and 36 vertices. If it was just a matter of vertices
747   // we could restrict the number to 8 and use    655   // we could restrict the number to 8 and use the indices to define the
748   // triangles, but we also have to consider t    656   // triangles, but we also have to consider the normals. A vertex can be have
749   // more than one normal, depending on which     657   // more than one normal, depending on which face it is being used to define.
750   // So we roll out all the vertices and norma    658   // So we roll out all the vertices and normals for each triangle.
751   std::vector<G4Point3D> vertices;                659   std::vector<G4Point3D> vertices;
752   std::vector<G4Normal3D> normals;                660   std::vector<G4Normal3D> normals;
753                                                   661 
754   // Also roll out edges (as lines) for wirefr    662   // Also roll out edges (as lines) for wireframe. Avoid duplicate lines,
755   // including those that differ only in the o    663   // including those that differ only in the order of vertices.
756   typedef std::pair<G4Point3D,G4Point3D> Line;    664   typedef std::pair<G4Point3D,G4Point3D> Line;
757   std::vector<Line> lines;                        665   std::vector<Line> lines;
758   auto insertIfNew = [&lines](const Line& newL    666   auto insertIfNew = [&lines](const Line& newLine) {
759     // For a large polyhedron, eliminating lin << 667     for (const auto& line: lines) {
760     // expensive. Comment out for now, and may << 668       if ((newLine.first==line.first && newLine.second==line.second) ||
761     // Allow the graphics-reps utilities to op << 669           (newLine.first==line.second && newLine.second==line.first))
762 //    for (const auto& line: lines) {          << 670       return;
763 //      if ((newLine.first==line.first && newL << 671     }
764 //          (newLine.first==line.second && new << 
765 //      return;                                << 
766 //    }                                        << 
767     lines.push_back(newLine);                     672     lines.push_back(newLine);
768   };                                              673   };
769                                                   674 
770   G4bool isAuxilaryEdgeVisible = fpViewer->Get    675   G4bool isAuxilaryEdgeVisible = fpViewer->GetViewParameters().IsAuxEdgeVisible();
771   G4bool notLastFace;                             676   G4bool notLastFace;
772   do {                                            677   do {
773     G4int      nEdges;                            678     G4int      nEdges;
774     G4Point3D  vertex  [4];                       679     G4Point3D  vertex  [4];
775     G4int      edgeFlag[4];                       680     G4int      edgeFlag[4];
776     G4Normal3D normal  [4];                       681     G4Normal3D normal  [4];
777     notLastFace = polyhedron.GetNextFacet(nEdg    682     notLastFace = polyhedron.GetNextFacet(nEdges, vertex, edgeFlag, normal);
778     vertices.push_back(vertex[0]);                683     vertices.push_back(vertex[0]);
779     vertices.push_back(vertex[1]);                684     vertices.push_back(vertex[1]);
780     vertices.push_back(vertex[2]);                685     vertices.push_back(vertex[2]);
781     normals.push_back(normal[0]);                 686     normals.push_back(normal[0]);
782     normals.push_back(normal[1]);                 687     normals.push_back(normal[1]);
783     normals.push_back(normal[2]);                 688     normals.push_back(normal[2]);
784     if(isAuxilaryEdgeVisible||edgeFlag[0]>0)in    689     if(isAuxilaryEdgeVisible||edgeFlag[0]>0)insertIfNew(Line(vertex[0],vertex[1]));
785     if(isAuxilaryEdgeVisible||edgeFlag[1]>0)in    690     if(isAuxilaryEdgeVisible||edgeFlag[1]>0)insertIfNew(Line(vertex[1],vertex[2]));
786     if (nEdges == 3) {                            691     if (nEdges == 3) {
787       // Face is a triangle                       692       // Face is a triangle
788       // One more line for wireframe, triangle    693       // One more line for wireframe, triangles for surfaces are complete
789       if(isAuxilaryEdgeVisible||edgeFlag[2]>0)    694       if(isAuxilaryEdgeVisible||edgeFlag[2]>0)insertIfNew(Line(vertex[2],vertex[0]));
790     } else if (nEdges == 4) {                     695     } else if (nEdges == 4) {
791       // Face is a quadrilateral                  696       // Face is a quadrilateral
792       // Create another triangle for surfaces,    697       // Create another triangle for surfaces, add two more lines for wireframe
793       vertices.push_back(vertex[2]);              698       vertices.push_back(vertex[2]);
794       vertices.push_back(vertex[3]);              699       vertices.push_back(vertex[3]);
795       vertices.push_back(vertex[0]);              700       vertices.push_back(vertex[0]);
796       normals.push_back(normal[2]);               701       normals.push_back(normal[2]);
797       normals.push_back(normal[3]);               702       normals.push_back(normal[3]);
798       normals.push_back(normal[0]);               703       normals.push_back(normal[0]);
799       if(isAuxilaryEdgeVisible||edgeFlag[2]>0)    704       if(isAuxilaryEdgeVisible||edgeFlag[2]>0)insertIfNew(Line(vertex[2],vertex[3]));
800       if(isAuxilaryEdgeVisible||edgeFlag[3]>0)    705       if(isAuxilaryEdgeVisible||edgeFlag[3]>0)insertIfNew(Line(vertex[3],vertex[0]));
801     } else {                                      706     } else {
802       G4warn                                   << 707       G4cerr << "ERROR: polyhedron face with more than 4 edges" << G4endl;
803       << "ERROR: polyhedron face with unexpect << 
804       << "\n  Tag: " << fpModel->GetCurrentTag << 
805       << G4endl;                               << 
806       return;                                     708       return;
807     }                                             709     }
808   } while (notLastFace);                          710   } while (notLastFace);
809   const auto nVerts = vertices.size();            711   const auto nVerts = vertices.size();
810   const auto nLines = lines.size();               712   const auto nLines = lines.size();
811                                                   713 
812   // Now put stuff into Qt objects                714   // Now put stuff into Qt objects
813                                                   715 
814   auto transform = G4Qt3DUtils::CreateQTransfo    716   auto transform = G4Qt3DUtils::CreateQTransformFrom(fObjectTransformation);
815   transform->setObjectName("transform");          717   transform->setObjectName("transform");
816                                                   718 
817   Qt3DCore::QEntity* wireframeEntity = nullptr    719   Qt3DCore::QEntity* wireframeEntity = nullptr;
818   Qt3DCore::QEntity* surfaceEntity   = nullptr    720   Qt3DCore::QEntity* surfaceEntity   = nullptr;
819   static G4int errorCount = 0;                    721   static G4int errorCount = 0;
820   G4ViewParameters::DrawingStyle drawing_style    722   G4ViewParameters::DrawingStyle drawing_style = GetDrawingStyle (fpVisAttribs);
821   switch (drawing_style) {                        723   switch (drawing_style) {
822     case G4ViewParameters::wireframe:             724     case G4ViewParameters::wireframe:
823       wireframeEntity = new Qt3DCore::QEntity(    725       wireframeEntity = new Qt3DCore::QEntity(currentNode);
824       wireframeEntity->addComponent(transform)    726       wireframeEntity->addComponent(transform);
825       break;                                      727       break;
826     case G4ViewParameters::hlr:                   728     case G4ViewParameters::hlr:
827       wireframeEntity = new Qt3DCore::QEntity(    729       wireframeEntity = new Qt3DCore::QEntity(currentNode);
828       wireframeEntity->addComponent(transform)    730       wireframeEntity->addComponent(transform);
829       surfaceEntity = new Qt3DCore::QEntity(cu    731       surfaceEntity = new Qt3DCore::QEntity(currentNode);
830       surfaceEntity->addComponent(transform);     732       surfaceEntity->addComponent(transform);
831       break;                                      733       break;
832     case G4ViewParameters::hsr:                   734     case G4ViewParameters::hsr:
833       surfaceEntity = new Qt3DCore::QEntity(cu    735       surfaceEntity = new Qt3DCore::QEntity(currentNode);
834       surfaceEntity->addComponent(transform);     736       surfaceEntity->addComponent(transform);
835       break;                                      737       break;
836     case G4ViewParameters::hlhsr:                 738     case G4ViewParameters::hlhsr:
837       wireframeEntity = new Qt3DCore::QEntity(    739       wireframeEntity = new Qt3DCore::QEntity(currentNode);
838       wireframeEntity->addComponent(transform)    740       wireframeEntity->addComponent(transform);
839       surfaceEntity = new Qt3DCore::QEntity(cu    741       surfaceEntity = new Qt3DCore::QEntity(currentNode);
840       surfaceEntity->addComponent(transform);     742       surfaceEntity->addComponent(transform);
841       break;                                      743       break;
842     case G4ViewParameters::cloud:                 744     case G4ViewParameters::cloud:
843       // Shouldn't happen in this function (it    745       // Shouldn't happen in this function (it's a polyhedron!)
844       if (errorCount == 0) {                      746       if (errorCount == 0) {
845         ++errorCount;                             747         ++errorCount;
846         G4warn << "WARNING: Qt3D: cloud drawin << 748         G4cerr << "WARNING: Qt3D: cloud drawing not implemented" << G4endl;
847       }                                           749       }
848       return;                                     750       return;
849       break;                                      751       break;
850   }                                               752   }
851                                                   753 
852   const auto vertexByteSize  = 3*sizeof(PRECIS    754   const auto vertexByteSize  = 3*sizeof(PRECISION);
853                                                   755 
854   G4Qt3DCompat::QGeometry* vertexGeometry = nu << 756   Qt3DRender::QGeometry* vertexGeometry = nullptr;
855   G4Qt3DCompat::QGeometry* lineGeometry   = nu << 757   Qt3DRender::QGeometry* lineGeometry   = nullptr;
856                                                   758 
857   G4Qt3DCompat::QAttribute* positionAtt = null << 759   Qt3DRender::QAttribute* positionAtt = nullptr;
858   G4Qt3DCompat::QAttribute* normalAtt   = null << 760   Qt3DRender::QAttribute* normalAtt   = nullptr;
859   G4Qt3DCompat::QAttribute* lineAtt     = null << 761   Qt3DRender::QAttribute* lineAtt     = nullptr;
860   G4Qt3DCompat::QAttribute* dummyNormalLineAtt << 
861                                                   762 
862   G4Qt3DCompat::QBuffer* vertexBuffer = nullpt << 763   Qt3DRender::QBuffer* vertexBuffer = nullptr;
863   if (drawing_style == G4ViewParameters::hlr |    764   if (drawing_style == G4ViewParameters::hlr ||
864       drawing_style == G4ViewParameters::hsr |    765       drawing_style == G4ViewParameters::hsr ||
865       drawing_style == G4ViewParameters::hlhsr    766       drawing_style == G4ViewParameters::hlhsr) {
866                                                   767 
867     // Put vertices, normals into  QByteArray     768     // Put vertices, normals into  QByteArray
868     // Accomodates both vertices and normals -    769     // Accomodates both vertices and normals - hence 2*
869     QByteArray vertexByteArray;                   770     QByteArray vertexByteArray;
870     const auto vertexBufferByteSize = 2*nVerts    771     const auto vertexBufferByteSize = 2*nVerts*vertexByteSize;
871     vertexByteArray.resize((G4int)vertexBuffer << 772     vertexByteArray.resize(vertexBufferByteSize);
872     auto vertexBufferArray = reinterpret_cast<    773     auto vertexBufferArray = reinterpret_cast<PRECISION*>(vertexByteArray.data());
873     G4int i1 = 0;                                 774     G4int i1 = 0;
874     for (std::size_t i = 0; i < nVerts; ++i) { << 775     for (size_t i = 0; i < nVerts; i++) {
875       vertexBufferArray[i1++] = vertices[i].x(    776       vertexBufferArray[i1++] = vertices[i].x();
876       vertexBufferArray[i1++] = vertices[i].y(    777       vertexBufferArray[i1++] = vertices[i].y();
877       vertexBufferArray[i1++] = vertices[i].z(    778       vertexBufferArray[i1++] = vertices[i].z();
878       vertexBufferArray[i1++] = normals[i].x()    779       vertexBufferArray[i1++] = normals[i].x();
879       vertexBufferArray[i1++] = normals[i].y()    780       vertexBufferArray[i1++] = normals[i].y();
880       vertexBufferArray[i1++] = normals[i].z()    781       vertexBufferArray[i1++] = normals[i].z();
881     }                                             782     }
882     // Vertex buffer (vertices and normals)       783     // Vertex buffer (vertices and normals)
883     vertexGeometry = new G4Qt3DCompat::QGeomet << 784     vertexGeometry = new Qt3DRender::QGeometry();
884     vertexGeometry->setObjectName("vertexGeome    785     vertexGeometry->setObjectName("vertexGeometry");
885     vertexBuffer = new G4Qt3DCompat::QBuffer(v << 786     vertexBuffer = new Qt3DRender::QBuffer(vertexGeometry);
886     vertexBuffer->setObjectName("Vertex buffer    787     vertexBuffer->setObjectName("Vertex buffer");
887     vertexBuffer->setData(vertexByteArray);       788     vertexBuffer->setData(vertexByteArray);
888                                                   789 
889     // Position attribute                         790     // Position attribute
890     positionAtt = new G4Qt3DCompat::QAttribute << 791     positionAtt = new Qt3DRender::QAttribute;
891     positionAtt->setObjectName("Position attri    792     positionAtt->setObjectName("Position attribute");
892     positionAtt->setName(G4Qt3DCompat::QAttrib << 793     positionAtt->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
893     positionAtt->setBuffer(vertexBuffer);         794     positionAtt->setBuffer(vertexBuffer);
894     positionAtt->setAttributeType(G4Qt3DCompat << 795     positionAtt->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
895     positionAtt->setVertexBaseType(BASETYPE);     796     positionAtt->setVertexBaseType(BASETYPE);
896     positionAtt->setVertexSize(3);                797     positionAtt->setVertexSize(3);
897     positionAtt->setCount((G4int)nVerts);      << 798     positionAtt->setCount(nVerts);
898     positionAtt->setByteOffset(0);                799     positionAtt->setByteOffset(0);
899     positionAtt->setByteStride(2*vertexByteSiz    800     positionAtt->setByteStride(2*vertexByteSize);
900                                                   801 
901     // Normal attribute                           802     // Normal attribute
902     normalAtt = new G4Qt3DCompat::QAttribute;  << 803     normalAtt = new Qt3DRender::QAttribute;
903     normalAtt->setObjectName("Normal attribute    804     normalAtt->setObjectName("Normal attribute");
904     normalAtt->setName(G4Qt3DCompat::QAttribut << 805     normalAtt->setName(Qt3DRender::QAttribute::defaultNormalAttributeName());
905     normalAtt->setBuffer(vertexBuffer);           806     normalAtt->setBuffer(vertexBuffer);
906     normalAtt->setAttributeType(G4Qt3DCompat:: << 807     normalAtt->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
907     normalAtt->setVertexBaseType(BASETYPE);       808     normalAtt->setVertexBaseType(BASETYPE);
908     normalAtt->setVertexSize(3);                  809     normalAtt->setVertexSize(3);
909     normalAtt->setCount((G4int)nVerts);        << 810     normalAtt->setCount(nVerts);
910     normalAtt->setByteOffset(vertexByteSize);     811     normalAtt->setByteOffset(vertexByteSize);
911     normalAtt->setByteStride(2*vertexByteSize)    812     normalAtt->setByteStride(2*vertexByteSize);
912   }                                               813   }
913                                                   814 
914   G4Qt3DCompat::QBuffer* lineBuffer = nullptr; << 815   Qt3DRender::QBuffer* lineBuffer = nullptr;
915   if (drawing_style == G4ViewParameters::wiref    816   if (drawing_style == G4ViewParameters::wireframe ||
916       drawing_style == G4ViewParameters::hlr |    817       drawing_style == G4ViewParameters::hlr ||
917       drawing_style == G4ViewParameters::hlhsr    818       drawing_style == G4ViewParameters::hlhsr) {
918                                                   819 
919     // Put lines into a QByteArray                820     // Put lines into a QByteArray
920     QByteArray lineByteArray;                     821     QByteArray lineByteArray;
921     const auto lineBufferByteSize = 2*nLines*v    822     const auto lineBufferByteSize = 2*nLines*vertexByteSize;
922     lineByteArray.resize((G4int)lineBufferByte << 823     lineByteArray.resize(lineBufferByteSize);
923     auto lineBufferArray = reinterpret_cast<PR    824     auto lineBufferArray = reinterpret_cast<PRECISION*>(lineByteArray.data());
924     G4int i2 = 0;                                 825     G4int i2 = 0;
925     for (const auto& line: lines) {               826     for (const auto& line: lines) {
926       lineBufferArray[i2++] = line.first.x();     827       lineBufferArray[i2++] = line.first.x();
927       lineBufferArray[i2++] = line.first.y();     828       lineBufferArray[i2++] = line.first.y();
928       lineBufferArray[i2++] = line.first.z();     829       lineBufferArray[i2++] = line.first.z();
929       lineBufferArray[i2++] = line.second.x();    830       lineBufferArray[i2++] = line.second.x();
930       lineBufferArray[i2++] = line.second.y();    831       lineBufferArray[i2++] = line.second.y();
931       lineBufferArray[i2++] = line.second.z();    832       lineBufferArray[i2++] = line.second.z();
932     }                                             833     }
933     // Line loop buffer                           834     // Line loop buffer
934     lineGeometry = new G4Qt3DCompat::QGeometry << 835     lineGeometry = new Qt3DRender::QGeometry();
935     lineGeometry->setObjectName("lineGeometry"    836     lineGeometry->setObjectName("lineGeometry");
936     lineBuffer = new G4Qt3DCompat::QBuffer(lin << 837     lineBuffer = new Qt3DRender::QBuffer(lineGeometry);
937     lineBuffer->setObjectName("Line buffer");     838     lineBuffer->setObjectName("Line buffer");
938     lineBuffer->setData(lineByteArray);           839     lineBuffer->setData(lineByteArray);
939                                                   840 
940     // Line attribute                             841     // Line attribute
941     lineAtt = new G4Qt3DCompat::QAttribute;    << 842     lineAtt = new Qt3DRender::QAttribute;
942     lineAtt->setObjectName("Position attribute    843     lineAtt->setObjectName("Position attribute");
943     lineAtt->setName(G4Qt3DCompat::QAttribute: << 844     lineAtt->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
944     lineAtt->setBuffer(lineBuffer);               845     lineAtt->setBuffer(lineBuffer);
945     lineAtt->setAttributeType(G4Qt3DCompat::QA << 846     lineAtt->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
946     lineAtt->setVertexBaseType(BASETYPE);         847     lineAtt->setVertexBaseType(BASETYPE);
947     lineAtt->setVertexSize(3);                    848     lineAtt->setVertexSize(3);
948     lineAtt->setCount((G4int)nLines);          << 849     lineAtt->setCount(nLines);
949     lineAtt->setByteOffset(0);                    850     lineAtt->setByteOffset(0);
950     lineAtt->setByteStride(vertexByteSize);       851     lineAtt->setByteStride(vertexByteSize);
951     // Normal attribute (a dummy with count==0 << 
952     dummyNormalLineAtt = new G4Qt3DCompat::QAt << 
953     dummyNormalLineAtt->setObjectName("Normal  << 
954     dummyNormalLineAtt->setName(G4Qt3DCompat:: << 
955     dummyNormalLineAtt->setBuffer(lineBuffer); << 
956     dummyNormalLineAtt->setAttributeType(G4Qt3 << 
957     dummyNormalLineAtt->setVertexBaseType(BASE << 
958     dummyNormalLineAtt->setVertexSize(3);      << 
959     dummyNormalLineAtt->setCount(0);           << 
960     dummyNormalLineAtt->setByteOffset(0);      << 
961     dummyNormalLineAtt->setByteStride(vertexBy << 
962   }                                               852   }
963                                                   853 
964   // Create material and renderer(s)...           854   // Create material and renderer(s)...
965                                                   855 
966   const auto& colour = fpVisAttribs->GetColour    856   const auto& colour = fpVisAttribs->GetColour();
967   Qt3DExtras::QDiffuseSpecularMaterial* materi    857   Qt3DExtras::QDiffuseSpecularMaterial* material;
968   Qt3DRender::QGeometryRenderer* renderer;        858   Qt3DRender::QGeometryRenderer* renderer;
969   switch (drawing_style) {                        859   switch (drawing_style) {
970                                                   860       
971     case G4ViewParameters::wireframe:             861     case G4ViewParameters::wireframe:
972                                                   862 
973       lineGeometry->addAttribute(lineAtt);        863       lineGeometry->addAttribute(lineAtt);
974       lineGeometry->addAttribute(dummyNormalLi << 
975                                                   864 
976       material = new Qt3DExtras::QDiffuseSpecu    865       material = new Qt3DExtras::QDiffuseSpecularMaterial();
977       material->setObjectName("materialForWire    866       material->setObjectName("materialForWireframe");
978       material->setAmbient(G4Qt3DUtils::Conver    867       material->setAmbient(G4Qt3DUtils::ConvertToQColor(colour));
979       material->setShininess(0.);                 868       material->setShininess(0.);
980       material->setSpecular(0.);                  869       material->setSpecular(0.);
981       wireframeEntity->addComponent(material);    870       wireframeEntity->addComponent(material);
982                                                   871 
983       renderer = new Qt3DRender::QGeometryRend    872       renderer = new Qt3DRender::QGeometryRenderer;
984       renderer->setObjectName("polyhedronWiref    873       renderer->setObjectName("polyhedronWireframeRenderer");
985       renderer->setGeometry(lineGeometry);        874       renderer->setGeometry(lineGeometry);
986       renderer->setVertexCount(2*(G4int)nLines << 875       renderer->setVertexCount(2*nLines);
987       renderer->setPrimitiveType(Qt3DRender::Q    876       renderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines);
988       wireframeEntity->addComponent(renderer);    877       wireframeEntity->addComponent(renderer);
989                                                   878 
990       break;                                      879       break;
991                                                   880 
992     case G4ViewParameters::hlr:                   881     case G4ViewParameters::hlr:
993                                                   882 
994       // Surfaces with background colour to hi    883       // Surfaces with background colour to hide the edges
995                                                   884 
996       vertexGeometry->addAttribute(positionAtt    885       vertexGeometry->addAttribute(positionAtt);
997       vertexGeometry->addAttribute(normalAtt);    886       vertexGeometry->addAttribute(normalAtt);
998                                                   887 
999       material = new Qt3DExtras::QDiffuseSpecu    888       material = new Qt3DExtras::QDiffuseSpecularMaterial();
1000       material->setObjectName("materialForHid    889       material->setObjectName("materialForHiddenLines");
1001       material->setAmbient(Qt::white);  // Wh    890       material->setAmbient(Qt::white);  // White for now (should be from fVP)
1002       material->setShininess(0.);                891       material->setShininess(0.);
1003       material->setSpecular(0.);                 892       material->setSpecular(0.);
1004       surfaceEntity->addComponent(material);     893       surfaceEntity->addComponent(material);
1005                                                  894 
1006       renderer = new Qt3DRender::QGeometryRen    895       renderer = new Qt3DRender::QGeometryRenderer;
1007       renderer->setObjectName("polyhedronSurf    896       renderer->setObjectName("polyhedronSurfaceRenderer");
1008       renderer->setGeometry(vertexGeometry);     897       renderer->setGeometry(vertexGeometry);
1009       renderer->setVertexCount((G4int)nVerts) << 898       renderer->setVertexCount(nVerts);
1010       renderer->setPrimitiveType(Qt3DRender::    899       renderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles);
1011       surfaceEntity->addComponent(renderer);     900       surfaceEntity->addComponent(renderer);
1012                                                  901 
1013       // Edges                                   902       // Edges
1014                                                  903 
1015       lineGeometry->addAttribute(lineAtt);       904       lineGeometry->addAttribute(lineAtt);
1016       lineGeometry->addAttribute(dummyNormalL << 
1017                                                  905 
1018       material = new Qt3DExtras::QDiffuseSpec    906       material = new Qt3DExtras::QDiffuseSpecularMaterial();
1019       material->setObjectName("materialForWir    907       material->setObjectName("materialForWireFrame");
1020       material->setAmbient(G4Qt3DUtils::Conve    908       material->setAmbient(G4Qt3DUtils::ConvertToQColor(colour));
1021       material->setShininess(0.);                909       material->setShininess(0.);
1022       material->setSpecular(0.);                 910       material->setSpecular(0.);
1023       wireframeEntity->addComponent(material)    911       wireframeEntity->addComponent(material);
1024                                                  912 
1025       renderer = new Qt3DRender::QGeometryRen    913       renderer = new Qt3DRender::QGeometryRenderer;
1026       renderer->setObjectName("polyhedronWire    914       renderer->setObjectName("polyhedronWireframeRenderer");
1027       renderer->setGeometry(lineGeometry);       915       renderer->setGeometry(lineGeometry);
1028       renderer->setVertexCount(2*(G4int)nLine << 916       renderer->setVertexCount(2*nLines);
1029       renderer->setPrimitiveType(Qt3DRender::    917       renderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines);
1030       wireframeEntity->addComponent(renderer)    918       wireframeEntity->addComponent(renderer);
1031                                                  919 
1032       break;                                     920       break;
1033                                                  921 
1034     case G4ViewParameters::hsr:                  922     case G4ViewParameters::hsr:
1035                                                  923 
1036       vertexGeometry->addAttribute(positionAt    924       vertexGeometry->addAttribute(positionAtt);
1037       vertexGeometry->addAttribute(normalAtt)    925       vertexGeometry->addAttribute(normalAtt);
1038                                                  926 
1039       material = new Qt3DExtras::QDiffuseSpec    927       material = new Qt3DExtras::QDiffuseSpecularMaterial();
1040       material->setObjectName("materialForSur    928       material->setObjectName("materialForSurface");
1041       material->setAmbient(G4Qt3DUtils::Conve    929       material->setAmbient(G4Qt3DUtils::ConvertToQColor(colour));
1042       if (colour.GetAlpha() < 1.) material->s    930       if (colour.GetAlpha() < 1.) material->setAlphaBlendingEnabled(true);
1043       surfaceEntity->addComponent(material);     931       surfaceEntity->addComponent(material);
1044                                                  932 
1045       renderer = new Qt3DRender::QGeometryRen    933       renderer = new Qt3DRender::QGeometryRenderer;
1046       renderer->setObjectName("polyhedronSurf    934       renderer->setObjectName("polyhedronSurfaceRenderer");
1047       renderer->setGeometry(vertexGeometry);     935       renderer->setGeometry(vertexGeometry);
1048       renderer->setVertexCount((G4int)nVerts) << 936       renderer->setVertexCount(nVerts);
1049       renderer->setPrimitiveType(Qt3DRender::    937       renderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles);
1050       surfaceEntity->addComponent(renderer);     938       surfaceEntity->addComponent(renderer);
1051                                                  939 
1052       break;                                     940       break;
1053                                                  941 
1054     case G4ViewParameters::hlhsr:                942     case G4ViewParameters::hlhsr:
1055                                                  943 
1056       // Surfaces                                944       // Surfaces
1057                                                  945 
1058       vertexGeometry->addAttribute(positionAt    946       vertexGeometry->addAttribute(positionAtt);
1059       vertexGeometry->addAttribute(normalAtt)    947       vertexGeometry->addAttribute(normalAtt);
1060                                                  948 
1061       material = new Qt3DExtras::QDiffuseSpec    949       material = new Qt3DExtras::QDiffuseSpecularMaterial();
1062       material->setObjectName("materialForSur    950       material->setObjectName("materialForSurface");
1063       material->setAmbient(G4Qt3DUtils::Conve    951       material->setAmbient(G4Qt3DUtils::ConvertToQColor(colour));
1064       if (colour.GetAlpha() < 1.) material->s    952       if (colour.GetAlpha() < 1.) material->setAlphaBlendingEnabled(true);
1065       surfaceEntity->addComponent(material);     953       surfaceEntity->addComponent(material);
1066                                                  954 
1067       renderer = new Qt3DRender::QGeometryRen    955       renderer = new Qt3DRender::QGeometryRenderer;
1068       renderer->setObjectName("polyhedronSurf    956       renderer->setObjectName("polyhedronSurfaceRenderer");
1069       renderer->setGeometry(vertexGeometry);     957       renderer->setGeometry(vertexGeometry);
1070       renderer->setVertexCount((G4int)nVerts) << 958       renderer->setVertexCount(nVerts);
1071       renderer->setPrimitiveType(Qt3DRender::    959       renderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles);
1072       surfaceEntity->addComponent(renderer);     960       surfaceEntity->addComponent(renderer);
1073                                                  961 
1074       // Edges                                   962       // Edges
1075                                                  963 
1076       lineGeometry->addAttribute(lineAtt);       964       lineGeometry->addAttribute(lineAtt);
1077       lineGeometry->addAttribute(dummyNormalL << 
1078                                                  965 
1079       material = new Qt3DExtras::QDiffuseSpec    966       material = new Qt3DExtras::QDiffuseSpecularMaterial();
1080       material->setObjectName("materialForWir    967       material->setObjectName("materialForWireframe");
1081       material->setAmbient(G4Qt3DUtils::Conve    968       material->setAmbient(G4Qt3DUtils::ConvertToQColor(colour));
1082       material->setShininess(0.);                969       material->setShininess(0.);
1083       material->setSpecular(0.);                 970       material->setSpecular(0.);
1084       wireframeEntity->addComponent(material)    971       wireframeEntity->addComponent(material);
1085                                                  972 
1086       renderer = new Qt3DRender::QGeometryRen    973       renderer = new Qt3DRender::QGeometryRenderer;
1087       renderer->setObjectName("polyhedronSurf    974       renderer->setObjectName("polyhedronSurfaceRenderer");
1088       renderer->setGeometry(lineGeometry);       975       renderer->setGeometry(lineGeometry);
1089       renderer->setVertexCount(2*(G4int)nLine << 976       renderer->setVertexCount(2*nLines);
1090       renderer->setPrimitiveType(Qt3DRender::    977       renderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines);
1091       wireframeEntity->addComponent(renderer)    978       wireframeEntity->addComponent(renderer);
1092                                                  979 
1093       break;                                     980       break;
1094                                                  981 
1095     case G4ViewParameters::cloud:                982     case G4ViewParameters::cloud:
1096       // Case trapped at start of function, s    983       // Case trapped at start of function, so no need to implement
1097       break;                                     984       break;
1098   }                                              985   }
1099 }                                                986 }
1100                                                  987 
1101 void G4Qt3DSceneHandler::AddCompound(const G4 << 
1102 {                                             << 
1103   StandardSpecialMeshRendering(mesh);         << 
1104 }                                             << 
1105                                               << 
1106 void G4Qt3DSceneHandler::ClearStore ()           988 void G4Qt3DSceneHandler::ClearStore ()
1107 {                                                989 {
1108   G4Qt3DUtils::delete_components_and_children    990   G4Qt3DUtils::delete_components_and_children_of_entity_recursively(fpQt3DScene);
1109   EstablishG4Qt3DQEntities();                    991   EstablishG4Qt3DQEntities();
1110 }                                                992 }
1111                                                  993 
1112 void G4Qt3DSceneHandler::ClearTransientStore     994 void G4Qt3DSceneHandler::ClearTransientStore ()
1113 {                                                995 {
1114   G4Qt3DUtils::delete_components_and_children    996   G4Qt3DUtils::delete_components_and_children_of_entity_recursively(fpTransientObjects);
1115 }                                                997 }
                                                   >> 998 
                                                   >> 999 #endif  // #if defined (G4VIS_BUILD_QT3D_DRIVER) || defined (G4VIS_USE_QT3D)
1116                                                  1000