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)


  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 not yet implemented");
535   }  // OK. Not working, but let it execute, w << 484   }
                                                   >> 485   return;
536                                                   486 
537   /* But it crashes after /vis/viewer/rebuild! << 
538   auto currentNode = CreateNewNode();             487   auto currentNode = CreateNewNode();
539    if (!currentNode) {                         << 488   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                                                   489 
550   fpVisAttribs = fpViewer->GetApplicableVisAtt    490   fpVisAttribs = fpViewer->GetApplicableVisAttributes(text.GetVisAttributes());
551                                                   491 
552   auto position = fObjectTransformation*G4Tran    492   auto position = fObjectTransformation*G4Translate3D(text.GetPosition());
553   auto transform = G4Qt3DUtils::CreateQTransfo    493   auto transform = G4Qt3DUtils::CreateQTransformFrom(position);
554 //  transform->setScale(10);                   << 494   transform->setScale(10);
555   transform->setScale(0.1);                    << 
556                                                << 
557 //  auto currentEntity = new Qt3DCore::QEntity << 
558                                                   495 
559   // This simply does not work                    496   // This simply does not work
560   auto qtext = new Qt3DExtras::QText2DEntity() << 497   //  auto qtext = new Qt3DExtras::QText2DEntity(currentNode);
561   qtext->setParent(currentNode);               << 498   //  qtext->setText(text.GetText().c_str());
562 //  qtext->setParent(currentEntity);  // ??  D << 499   //  qtext->setHeight(100);
563   qtext->setText(text.GetText().c_str());      << 500   //  qtext->setWidth(1000);
564 //  qtext->setHeight(100);                     << 501   //  qtext->setColor(Qt::green);
565 //  qtext->setWidth(1000);                     << 502   //  qtext->setFont(QFont("Courier New", 10));
566   qtext->setHeight(20);                        << 503   //
567   qtext->setWidth(100);                        << 504   //  qtext->addComponent(transform);
568   qtext->setColor(Qt::green);                  << 505   //  qtext->addComponent(material);
569   qtext->setFont(QFont("Courier New", 10));    << 
570   qtext->addComponent(transform);              << 
571                                                   506 
572   // This produces text in 3D facing +z - not     507   // This produces text in 3D facing +z - not what we want
573 //  const auto& colour = GetTextColour(text);  << 508   const auto& colour = GetTextColour(text);
574 //  auto material = new Qt3DExtras::QDiffuseSp << 509   auto material = new Qt3DExtras::QDiffuseSpecularMaterial();
575 //  material->setObjectName("materialForText") << 510   material->setObjectName("materialForText");
576 //  material->setAmbient(G4Qt3DUtils::ConvertT << 511   material->setAmbient(G4Qt3DUtils::ConvertToQColor(colour));
577 //  if (colour.GetAlpha() < 1.) material->setA << 512   if (colour.GetAlpha() < 1.) material->setAlphaBlendingEnabled(true);
578 //                                             << 513 
579 //  auto textMesh = new Qt3DExtras::QExtrudedT << 514   auto textMesh = new Qt3DExtras::QExtrudedTextMesh();
580 //  textMesh->setText(text.GetText().c_str()); << 515   textMesh->setText(text.GetText().c_str());
581 //  textMesh->setFont(QFont("Courier New", 10) << 516   textMesh->setFont(QFont("Courier New", 10));
582 //  textMesh->setDepth(.01f);                  << 517   textMesh->setDepth(.01f);
583 //                                             << 518 
584 //  currentNode->addComponent(material);       << 519   currentNode->addComponent(material);
585 //  currentNode->addComponent(transform);      << 520   currentNode->addComponent(transform);
586 //  currentNode->addComponent(textMesh);       << 521   currentNode->addComponent(textMesh);
587    */                                          << 
588 }                                                 522 }
589                                                   523 
590 void G4Qt3DSceneHandler::AddPrimitive(const G4    524 void G4Qt3DSceneHandler::AddPrimitive(const G4Circle& circle)
591 {                                                 525 {
592 #ifdef G4QT3DDEBUG                                526 #ifdef G4QT3DDEBUG
593   G4cout <<                                       527   G4cout <<
594   "G4Qt3DSceneHandler::AddPrimitive(const G4Ci    528   "G4Qt3DSceneHandler::AddPrimitive(const G4Circle& circle) called.\n"
595   << circle                                       529   << circle
596   << G4endl;                                      530   << G4endl;
597 #endif                                            531 #endif
598                                                   532 
599 #ifdef G4QT3DDEBUG                                533 #ifdef G4QT3DDEBUG
600   MarkerSizeType sizeType;                        534   MarkerSizeType sizeType;
601   G4double size = GetMarkerSize (circle, sizeT    535   G4double size = GetMarkerSize (circle, sizeType);
602   switch (sizeType) {                             536   switch (sizeType) {
603     default:                                      537     default:
604     case screen:                                  538     case screen:
605       // Draw in screen coordinates.              539       // Draw in screen coordinates.
606       G4cout << "screen";                         540       G4cout << "screen";
607       break;                                      541       break;
608     case world:                                   542     case world:
609       // Draw in world coordinates.               543       // Draw in world coordinates.
610       G4cout << "world";                          544       G4cout << "world";
611       break;                                      545       break;
612   }                                               546   }
613   G4cout << " size: " << size << G4endl;          547   G4cout << " size: " << size << G4endl;
614 #endif                                            548 #endif
615                                                   549 
616   auto currentNode = CreateNewNode();             550   auto currentNode = CreateNewNode();
617   if (!currentNode) {                          << 551   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                                                   552 
628   fpVisAttribs = fpViewer->GetApplicableVisAtt    553   fpVisAttribs = fpViewer->GetApplicableVisAttributes(circle.GetVisAttributes());
629                                                   554 
630   auto position = fObjectTransformation*G4Tran    555   auto position = fObjectTransformation*G4Translate3D(circle.GetPosition());
631   auto transform = G4Qt3DUtils::CreateQTransfo    556   auto transform = G4Qt3DUtils::CreateQTransformFrom(position);
632                                                   557 
633   const auto& colour = fpVisAttribs->GetColour    558   const auto& colour = fpVisAttribs->GetColour();
634   auto material = new Qt3DExtras::QDiffuseSpec    559   auto material = new Qt3DExtras::QDiffuseSpecularMaterial();
635   material->setObjectName("materialForCircle")    560   material->setObjectName("materialForCircle");
636   material->setAmbient(G4Qt3DUtils::ConvertToQ    561   material->setAmbient(G4Qt3DUtils::ConvertToQColor(colour));
637   if (colour.GetAlpha() < 1.) material->setAlp    562   if (colour.GetAlpha() < 1.) material->setAlphaBlendingEnabled(true);
638                                                   563 
639   auto sphereMesh = new Qt3DExtras::QSphereMes    564   auto sphereMesh = new Qt3DExtras::QSphereMesh;
640   sphereMesh->setObjectName("sphereMesh");        565   sphereMesh->setObjectName("sphereMesh");
641   G4double radius;                                566   G4double radius;
642   if (circle.GetSizeType() == G4VMarker::world    567   if (circle.GetSizeType() == G4VMarker::world ) {
643     radius =circle.GetWorldRadius();              568     radius =circle.GetWorldRadius();
644   } else {  // Screen-size or none                569   } else {  // Screen-size or none
645     // Not figured out how to do screen-size,     570     // Not figured out how to do screen-size, so use scene extent
646     const G4double scale = 200.;  // Roughly p    571     const G4double scale = 200.;  // Roughly pixles per scene
647     radius = circle.GetScreenRadius()*fpScene-    572     radius = circle.GetScreenRadius()*fpScene->GetExtent().GetExtentRadius()/scale;
648   }                                               573   }
649   sphereMesh->setRadius(radius);                  574   sphereMesh->setRadius(radius);
650                                                   575 
651   auto currentEntity = new Qt3DCore::QEntity(c    576   auto currentEntity = new Qt3DCore::QEntity(currentNode);
652   currentEntity->addComponent(material);          577   currentEntity->addComponent(material);
653   currentEntity->addComponent(transform);         578   currentEntity->addComponent(transform);
654   currentEntity->addComponent(sphereMesh);        579   currentEntity->addComponent(sphereMesh);
655 }                                                 580 }
656                                                   581 
657 void G4Qt3DSceneHandler::AddPrimitive(const G4    582 void G4Qt3DSceneHandler::AddPrimitive(const G4Square& square)
658 {                                                 583 {
659 #ifdef G4QT3DDEBUG                                584 #ifdef G4QT3DDEBUG
660   G4cout <<                                       585   G4cout <<
661   "G4Qt3DSceneHandler::AddPrimitive(const G4Sq    586   "G4Qt3DSceneHandler::AddPrimitive(const G4Square& square) called.\n"
662   << square                                       587   << square
663   << G4endl;                                      588   << G4endl;
664 #endif                                            589 #endif
665                                                   590 
666 #ifdef G4QT3DDEBUG                                591 #ifdef G4QT3DDEBUG
667   MarkerSizeType sizeType;                        592   MarkerSizeType sizeType;
668   G4double size = GetMarkerSize (square, sizeT    593   G4double size = GetMarkerSize (square, sizeType);
669   switch (sizeType) {                             594   switch (sizeType) {
670     default:                                      595     default:
671     case screen:                                  596     case screen:
672       // Draw in screen coordinates.              597       // Draw in screen coordinates.
673       G4cout << "screen";                         598       G4cout << "screen";
674       break;                                      599       break;
675     case world:                                   600     case world:
676       // Draw in world coordinates.               601       // Draw in world coordinates.
677       G4cout << "world";                          602       G4cout << "world";
678       break;                                      603       break;
679   }                                               604   }
680   G4cout << " size: " << size << G4endl;          605   G4cout << " size: " << size << G4endl;
681 #endif                                            606 #endif
682                                                   607 
683   auto currentNode = CreateNewNode();             608   auto currentNode = CreateNewNode();
684   if (!currentNode) {                          << 609   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                                                   610 
695   fpVisAttribs = fpViewer->GetApplicableVisAtt    611   fpVisAttribs = fpViewer->GetApplicableVisAttributes(square.GetVisAttributes());
696                                                   612 
697   auto position = fObjectTransformation*G4Tran    613   auto position = fObjectTransformation*G4Translate3D(square.GetPosition());
698   auto transform = G4Qt3DUtils::CreateQTransfo    614   auto transform = G4Qt3DUtils::CreateQTransformFrom(position);
699                                                   615 
700   const auto& colour = fpVisAttribs->GetColour    616   const auto& colour = fpVisAttribs->GetColour();
701   auto material = new Qt3DExtras::QDiffuseSpec    617   auto material = new Qt3DExtras::QDiffuseSpecularMaterial();
702   material->setObjectName("materialForSquare")    618   material->setObjectName("materialForSquare");
703   material->setAmbient(G4Qt3DUtils::ConvertToQ    619   material->setAmbient(G4Qt3DUtils::ConvertToQColor(colour));
704   if (colour.GetAlpha() < 1.) material->setAlp    620   if (colour.GetAlpha() < 1.) material->setAlphaBlendingEnabled(true);
705                                                   621 
706   auto boxMesh = new Qt3DExtras::QCuboidMesh()    622   auto boxMesh = new Qt3DExtras::QCuboidMesh();
707   boxMesh->setObjectName("boxMesh");              623   boxMesh->setObjectName("boxMesh");
708   G4double side;                                  624   G4double side;
709   if (square.GetSizeType() == G4VMarker::world    625   if (square.GetSizeType() == G4VMarker::world ) {
710     side = square.GetWorldDiameter();             626     side = square.GetWorldDiameter();
711   } else {  // Screen-size or none                627   } else {  // Screen-size or none
712     // Not figured out how to do screen-size,     628     // Not figured out how to do screen-size, so use scene extent
713     const G4double scale = 200.;  // Roughly p    629     const G4double scale = 200.;  // Roughly pixles per scene
714     side = square.GetScreenDiameter()*fpScene-    630     side = square.GetScreenDiameter()*fpScene->GetExtent().GetExtentRadius()/scale;
715   }                                               631   }
716   boxMesh->setXExtent(side);                      632   boxMesh->setXExtent(side);
717   boxMesh->setYExtent(side);                      633   boxMesh->setYExtent(side);
718   boxMesh->setZExtent(side);                      634   boxMesh->setZExtent(side);
719                                                   635 
720   auto currentEntity = new Qt3DCore::QEntity(c    636   auto currentEntity = new Qt3DCore::QEntity(currentNode);
721   currentEntity->addComponent(material);          637   currentEntity->addComponent(material);
722   currentEntity->addComponent(transform);         638   currentEntity->addComponent(transform);
723   currentEntity->addComponent(boxMesh);           639   currentEntity->addComponent(boxMesh);
724 }                                                 640 }
725                                                   641 
726 void G4Qt3DSceneHandler::AddPrimitive(const G4    642 void G4Qt3DSceneHandler::AddPrimitive(const G4Polyhedron& polyhedron)
727 {                                                 643 {
728   auto currentNode = CreateNewNode();             644   auto currentNode = CreateNewNode();
729   if (!currentNode) {                          << 645   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                                                   646 
740   if (polyhedron.GetNoFacets() == 0) return;      647   if (polyhedron.GetNoFacets() == 0) return;
741                                                   648 
742   fpVisAttribs = fpViewer->GetApplicableVisAtt    649   fpVisAttribs = fpViewer->GetApplicableVisAttributes(polyhedron.GetVisAttributes());
743                                                   650 
744   // Roll out vertices and normals for the fac    651   // Roll out vertices and normals for the faces. Note that this means vertices
745   // are duplicated. For example a box has 8 v    652   // are duplicated. For example a box has 8 vertices, but to define 6 faces
746   // you need 12 triangles and 36 vertices. If    653   // 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    654   // we could restrict the number to 8 and use the indices to define the
748   // triangles, but we also have to consider t    655   // triangles, but we also have to consider the normals. A vertex can be have
749   // more than one normal, depending on which     656   // more than one normal, depending on which face it is being used to define.
750   // So we roll out all the vertices and norma    657   // So we roll out all the vertices and normals for each triangle.
751   std::vector<G4Point3D> vertices;                658   std::vector<G4Point3D> vertices;
752   std::vector<G4Normal3D> normals;                659   std::vector<G4Normal3D> normals;
753                                                   660 
754   // Also roll out edges (as lines) for wirefr    661   // Also roll out edges (as lines) for wireframe. Avoid duplicate lines,
755   // including those that differ only in the o    662   // including those that differ only in the order of vertices.
756   typedef std::pair<G4Point3D,G4Point3D> Line;    663   typedef std::pair<G4Point3D,G4Point3D> Line;
757   std::vector<Line> lines;                        664   std::vector<Line> lines;
758   auto insertIfNew = [&lines](const Line& newL    665   auto insertIfNew = [&lines](const Line& newLine) {
759     // For a large polyhedron, eliminating lin << 666     for (const auto& line: lines) {
760     // expensive. Comment out for now, and may << 667       if ((newLine.first==line.first && newLine.second==line.second) ||
761     // Allow the graphics-reps utilities to op << 668           (newLine.first==line.second && newLine.second==line.first))
762 //    for (const auto& line: lines) {          << 669       return;
763 //      if ((newLine.first==line.first && newL << 670     }
764 //          (newLine.first==line.second && new << 
765 //      return;                                << 
766 //    }                                        << 
767     lines.push_back(newLine);                     671     lines.push_back(newLine);
768   };                                              672   };
769                                                   673 
770   G4bool isAuxilaryEdgeVisible = fpViewer->Get << 
771   G4bool notLastFace;                             674   G4bool notLastFace;
772   do {                                            675   do {
773     G4int      nEdges;                            676     G4int      nEdges;
774     G4Point3D  vertex  [4];                       677     G4Point3D  vertex  [4];
775     G4int      edgeFlag[4];                       678     G4int      edgeFlag[4];
776     G4Normal3D normal  [4];                       679     G4Normal3D normal  [4];
777     notLastFace = polyhedron.GetNextFacet(nEdg    680     notLastFace = polyhedron.GetNextFacet(nEdges, vertex, edgeFlag, normal);
778     vertices.push_back(vertex[0]);                681     vertices.push_back(vertex[0]);
779     vertices.push_back(vertex[1]);                682     vertices.push_back(vertex[1]);
780     vertices.push_back(vertex[2]);                683     vertices.push_back(vertex[2]);
781     normals.push_back(normal[0]);                 684     normals.push_back(normal[0]);
782     normals.push_back(normal[1]);                 685     normals.push_back(normal[1]);
783     normals.push_back(normal[2]);                 686     normals.push_back(normal[2]);
784     if(isAuxilaryEdgeVisible||edgeFlag[0]>0)in << 687     insertIfNew(Line(vertex[0],vertex[1]));
785     if(isAuxilaryEdgeVisible||edgeFlag[1]>0)in << 688     insertIfNew(Line(vertex[1],vertex[2]));
786     if (nEdges == 3) {                            689     if (nEdges == 3) {
787       // Face is a triangle                       690       // Face is a triangle
788       // One more line for wireframe, triangle    691       // One more line for wireframe, triangles for surfaces are complete
789       if(isAuxilaryEdgeVisible||edgeFlag[2]>0) << 692       insertIfNew(Line(vertex[2],vertex[0]));
790     } else if (nEdges == 4) {                     693     } else if (nEdges == 4) {
791       // Face is a quadrilateral                  694       // Face is a quadrilateral
792       // Create another triangle for surfaces,    695       // Create another triangle for surfaces, add two more lines for wireframe
793       vertices.push_back(vertex[2]);              696       vertices.push_back(vertex[2]);
794       vertices.push_back(vertex[3]);              697       vertices.push_back(vertex[3]);
795       vertices.push_back(vertex[0]);              698       vertices.push_back(vertex[0]);
796       normals.push_back(normal[2]);               699       normals.push_back(normal[2]);
797       normals.push_back(normal[3]);               700       normals.push_back(normal[3]);
798       normals.push_back(normal[0]);               701       normals.push_back(normal[0]);
799       if(isAuxilaryEdgeVisible||edgeFlag[2]>0) << 702       insertIfNew(Line(vertex[2],vertex[3]));
800       if(isAuxilaryEdgeVisible||edgeFlag[3]>0) << 703       insertIfNew(Line(vertex[3],vertex[0]));
801     } else {                                      704     } else {
802       G4warn                                   << 705       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;                                     706       return;
807     }                                             707     }
808   } while (notLastFace);                          708   } while (notLastFace);
809   const auto nVerts = vertices.size();            709   const auto nVerts = vertices.size();
810   const auto nLines = lines.size();               710   const auto nLines = lines.size();
811                                                   711 
812   // Now put stuff into Qt objects                712   // Now put stuff into Qt objects
813                                                   713 
814   auto transform = G4Qt3DUtils::CreateQTransfo    714   auto transform = G4Qt3DUtils::CreateQTransformFrom(fObjectTransformation);
815   transform->setObjectName("transform");          715   transform->setObjectName("transform");
816                                                   716 
817   Qt3DCore::QEntity* wireframeEntity = nullptr    717   Qt3DCore::QEntity* wireframeEntity = nullptr;
818   Qt3DCore::QEntity* surfaceEntity   = nullptr    718   Qt3DCore::QEntity* surfaceEntity   = nullptr;
819   static G4int errorCount = 0;                    719   static G4int errorCount = 0;
820   G4ViewParameters::DrawingStyle drawing_style    720   G4ViewParameters::DrawingStyle drawing_style = GetDrawingStyle (fpVisAttribs);
821   switch (drawing_style) {                        721   switch (drawing_style) {
822     case G4ViewParameters::wireframe:             722     case G4ViewParameters::wireframe:
823       wireframeEntity = new Qt3DCore::QEntity(    723       wireframeEntity = new Qt3DCore::QEntity(currentNode);
824       wireframeEntity->addComponent(transform)    724       wireframeEntity->addComponent(transform);
825       break;                                      725       break;
826     case G4ViewParameters::hlr:                   726     case G4ViewParameters::hlr:
827       wireframeEntity = new Qt3DCore::QEntity(    727       wireframeEntity = new Qt3DCore::QEntity(currentNode);
828       wireframeEntity->addComponent(transform)    728       wireframeEntity->addComponent(transform);
829       surfaceEntity = new Qt3DCore::QEntity(cu    729       surfaceEntity = new Qt3DCore::QEntity(currentNode);
830       surfaceEntity->addComponent(transform);     730       surfaceEntity->addComponent(transform);
831       break;                                      731       break;
832     case G4ViewParameters::hsr:                   732     case G4ViewParameters::hsr:
833       surfaceEntity = new Qt3DCore::QEntity(cu    733       surfaceEntity = new Qt3DCore::QEntity(currentNode);
834       surfaceEntity->addComponent(transform);     734       surfaceEntity->addComponent(transform);
835       break;                                      735       break;
836     case G4ViewParameters::hlhsr:                 736     case G4ViewParameters::hlhsr:
837       wireframeEntity = new Qt3DCore::QEntity(    737       wireframeEntity = new Qt3DCore::QEntity(currentNode);
838       wireframeEntity->addComponent(transform)    738       wireframeEntity->addComponent(transform);
839       surfaceEntity = new Qt3DCore::QEntity(cu    739       surfaceEntity = new Qt3DCore::QEntity(currentNode);
840       surfaceEntity->addComponent(transform);     740       surfaceEntity->addComponent(transform);
841       break;                                      741       break;
842     case G4ViewParameters::cloud:                 742     case G4ViewParameters::cloud:
843       // Shouldn't happen in this function (it    743       // Shouldn't happen in this function (it's a polyhedron!)
844       if (errorCount == 0) {                      744       if (errorCount == 0) {
845         ++errorCount;                             745         ++errorCount;
846         G4warn << "WARNING: Qt3D: cloud drawin << 746         G4cerr << "WARNING: Qt3D: cloud drawing not implemented" << G4endl;
847       }                                           747       }
848       return;                                     748       return;
849       break;                                      749       break;
850   }                                               750   }
851                                                   751 
852   const auto vertexByteSize  = 3*sizeof(PRECIS    752   const auto vertexByteSize  = 3*sizeof(PRECISION);
853                                                   753 
854   G4Qt3DCompat::QGeometry* vertexGeometry = nu << 754   Qt3DRender::QGeometry* vertexGeometry = nullptr;
855   G4Qt3DCompat::QGeometry* lineGeometry   = nu << 755   Qt3DRender::QGeometry* lineGeometry   = nullptr;
856                                                   756 
857   G4Qt3DCompat::QAttribute* positionAtt = null << 757   Qt3DRender::QAttribute* positionAtt = nullptr;
858   G4Qt3DCompat::QAttribute* normalAtt   = null << 758   Qt3DRender::QAttribute* normalAtt   = nullptr;
859   G4Qt3DCompat::QAttribute* lineAtt     = null << 759   Qt3DRender::QAttribute* lineAtt     = nullptr;
860   G4Qt3DCompat::QAttribute* dummyNormalLineAtt << 
861                                                   760 
862   G4Qt3DCompat::QBuffer* vertexBuffer = nullpt << 761   Qt3DRender::QBuffer* vertexBuffer = nullptr;
863   if (drawing_style == G4ViewParameters::hlr |    762   if (drawing_style == G4ViewParameters::hlr ||
864       drawing_style == G4ViewParameters::hsr |    763       drawing_style == G4ViewParameters::hsr ||
865       drawing_style == G4ViewParameters::hlhsr    764       drawing_style == G4ViewParameters::hlhsr) {
866                                                   765 
867     // Put vertices, normals into  QByteArray     766     // Put vertices, normals into  QByteArray
868     // Accomodates both vertices and normals -    767     // Accomodates both vertices and normals - hence 2*
869     QByteArray vertexByteArray;                   768     QByteArray vertexByteArray;
870     const auto vertexBufferByteSize = 2*nVerts    769     const auto vertexBufferByteSize = 2*nVerts*vertexByteSize;
871     vertexByteArray.resize((G4int)vertexBuffer << 770     vertexByteArray.resize(vertexBufferByteSize);
872     auto vertexBufferArray = reinterpret_cast<    771     auto vertexBufferArray = reinterpret_cast<PRECISION*>(vertexByteArray.data());
873     G4int i1 = 0;                                 772     G4int i1 = 0;
874     for (std::size_t i = 0; i < nVerts; ++i) { << 773     for (size_t i = 0; i < nVerts; i++) {
875       vertexBufferArray[i1++] = vertices[i].x(    774       vertexBufferArray[i1++] = vertices[i].x();
876       vertexBufferArray[i1++] = vertices[i].y(    775       vertexBufferArray[i1++] = vertices[i].y();
877       vertexBufferArray[i1++] = vertices[i].z(    776       vertexBufferArray[i1++] = vertices[i].z();
878       vertexBufferArray[i1++] = normals[i].x()    777       vertexBufferArray[i1++] = normals[i].x();
879       vertexBufferArray[i1++] = normals[i].y()    778       vertexBufferArray[i1++] = normals[i].y();
880       vertexBufferArray[i1++] = normals[i].z()    779       vertexBufferArray[i1++] = normals[i].z();
881     }                                             780     }
882     // Vertex buffer (vertices and normals)       781     // Vertex buffer (vertices and normals)
883     vertexGeometry = new G4Qt3DCompat::QGeomet << 782     vertexGeometry = new Qt3DRender::QGeometry();
884     vertexGeometry->setObjectName("vertexGeome    783     vertexGeometry->setObjectName("vertexGeometry");
885     vertexBuffer = new G4Qt3DCompat::QBuffer(v << 784     vertexBuffer = new Qt3DRender::QBuffer(vertexGeometry);
886     vertexBuffer->setObjectName("Vertex buffer    785     vertexBuffer->setObjectName("Vertex buffer");
887     vertexBuffer->setData(vertexByteArray);       786     vertexBuffer->setData(vertexByteArray);
888                                                   787 
889     // Position attribute                         788     // Position attribute
890     positionAtt = new G4Qt3DCompat::QAttribute << 789     positionAtt = new Qt3DRender::QAttribute;
891     positionAtt->setObjectName("Position attri    790     positionAtt->setObjectName("Position attribute");
892     positionAtt->setName(G4Qt3DCompat::QAttrib << 791     positionAtt->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
893     positionAtt->setBuffer(vertexBuffer);         792     positionAtt->setBuffer(vertexBuffer);
894     positionAtt->setAttributeType(G4Qt3DCompat << 793     positionAtt->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
895     positionAtt->setVertexBaseType(BASETYPE);     794     positionAtt->setVertexBaseType(BASETYPE);
896     positionAtt->setVertexSize(3);                795     positionAtt->setVertexSize(3);
897     positionAtt->setCount((G4int)nVerts);      << 796     positionAtt->setCount(nVerts);
898     positionAtt->setByteOffset(0);                797     positionAtt->setByteOffset(0);
899     positionAtt->setByteStride(2*vertexByteSiz    798     positionAtt->setByteStride(2*vertexByteSize);
900                                                   799 
901     // Normal attribute                           800     // Normal attribute
902     normalAtt = new G4Qt3DCompat::QAttribute;  << 801     normalAtt = new Qt3DRender::QAttribute;
903     normalAtt->setObjectName("Normal attribute    802     normalAtt->setObjectName("Normal attribute");
904     normalAtt->setName(G4Qt3DCompat::QAttribut << 803     normalAtt->setName(Qt3DRender::QAttribute::defaultNormalAttributeName());
905     normalAtt->setBuffer(vertexBuffer);           804     normalAtt->setBuffer(vertexBuffer);
906     normalAtt->setAttributeType(G4Qt3DCompat:: << 805     normalAtt->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
907     normalAtt->setVertexBaseType(BASETYPE);       806     normalAtt->setVertexBaseType(BASETYPE);
908     normalAtt->setVertexSize(3);                  807     normalAtt->setVertexSize(3);
909     normalAtt->setCount((G4int)nVerts);        << 808     normalAtt->setCount(nVerts);
910     normalAtt->setByteOffset(vertexByteSize);     809     normalAtt->setByteOffset(vertexByteSize);
911     normalAtt->setByteStride(2*vertexByteSize)    810     normalAtt->setByteStride(2*vertexByteSize);
912   }                                               811   }
913                                                   812 
914   G4Qt3DCompat::QBuffer* lineBuffer = nullptr; << 813   Qt3DRender::QBuffer* lineBuffer = nullptr;
915   if (drawing_style == G4ViewParameters::wiref    814   if (drawing_style == G4ViewParameters::wireframe ||
916       drawing_style == G4ViewParameters::hlr |    815       drawing_style == G4ViewParameters::hlr ||
917       drawing_style == G4ViewParameters::hlhsr    816       drawing_style == G4ViewParameters::hlhsr) {
918                                                   817 
919     // Put lines into a QByteArray                818     // Put lines into a QByteArray
920     QByteArray lineByteArray;                     819     QByteArray lineByteArray;
921     const auto lineBufferByteSize = 2*nLines*v    820     const auto lineBufferByteSize = 2*nLines*vertexByteSize;
922     lineByteArray.resize((G4int)lineBufferByte << 821     lineByteArray.resize(lineBufferByteSize);
923     auto lineBufferArray = reinterpret_cast<PR    822     auto lineBufferArray = reinterpret_cast<PRECISION*>(lineByteArray.data());
924     G4int i2 = 0;                                 823     G4int i2 = 0;
925     for (const auto& line: lines) {               824     for (const auto& line: lines) {
926       lineBufferArray[i2++] = line.first.x();     825       lineBufferArray[i2++] = line.first.x();
927       lineBufferArray[i2++] = line.first.y();     826       lineBufferArray[i2++] = line.first.y();
928       lineBufferArray[i2++] = line.first.z();     827       lineBufferArray[i2++] = line.first.z();
929       lineBufferArray[i2++] = line.second.x();    828       lineBufferArray[i2++] = line.second.x();
930       lineBufferArray[i2++] = line.second.y();    829       lineBufferArray[i2++] = line.second.y();
931       lineBufferArray[i2++] = line.second.z();    830       lineBufferArray[i2++] = line.second.z();
932     }                                             831     }
933     // Line loop buffer                           832     // Line loop buffer
934     lineGeometry = new G4Qt3DCompat::QGeometry << 833     lineGeometry = new Qt3DRender::QGeometry();
935     lineGeometry->setObjectName("lineGeometry"    834     lineGeometry->setObjectName("lineGeometry");
936     lineBuffer = new G4Qt3DCompat::QBuffer(lin << 835     lineBuffer = new Qt3DRender::QBuffer(lineGeometry);
937     lineBuffer->setObjectName("Line buffer");     836     lineBuffer->setObjectName("Line buffer");
938     lineBuffer->setData(lineByteArray);           837     lineBuffer->setData(lineByteArray);
939                                                   838 
940     // Line attribute                             839     // Line attribute
941     lineAtt = new G4Qt3DCompat::QAttribute;    << 840     lineAtt = new Qt3DRender::QAttribute;
942     lineAtt->setObjectName("Position attribute    841     lineAtt->setObjectName("Position attribute");
943     lineAtt->setName(G4Qt3DCompat::QAttribute: << 842     lineAtt->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
944     lineAtt->setBuffer(lineBuffer);               843     lineAtt->setBuffer(lineBuffer);
945     lineAtt->setAttributeType(G4Qt3DCompat::QA << 844     lineAtt->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
946     lineAtt->setVertexBaseType(BASETYPE);         845     lineAtt->setVertexBaseType(BASETYPE);
947     lineAtt->setVertexSize(3);                    846     lineAtt->setVertexSize(3);
948     lineAtt->setCount((G4int)nLines);          << 847     lineAtt->setCount(nLines);
949     lineAtt->setByteOffset(0);                    848     lineAtt->setByteOffset(0);
950     lineAtt->setByteStride(vertexByteSize);       849     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   }                                               850   }
963                                                   851 
964   // Create material and renderer(s)...           852   // Create material and renderer(s)...
965                                                   853 
966   const auto& colour = fpVisAttribs->GetColour    854   const auto& colour = fpVisAttribs->GetColour();
967   Qt3DExtras::QDiffuseSpecularMaterial* materi    855   Qt3DExtras::QDiffuseSpecularMaterial* material;
968   Qt3DRender::QGeometryRenderer* renderer;        856   Qt3DRender::QGeometryRenderer* renderer;
969   switch (drawing_style) {                        857   switch (drawing_style) {
970                                                   858       
971     case G4ViewParameters::wireframe:             859     case G4ViewParameters::wireframe:
972                                                   860 
973       lineGeometry->addAttribute(lineAtt);        861       lineGeometry->addAttribute(lineAtt);
974       lineGeometry->addAttribute(dummyNormalLi << 
975                                                   862 
976       material = new Qt3DExtras::QDiffuseSpecu    863       material = new Qt3DExtras::QDiffuseSpecularMaterial();
977       material->setObjectName("materialForWire    864       material->setObjectName("materialForWireframe");
978       material->setAmbient(G4Qt3DUtils::Conver    865       material->setAmbient(G4Qt3DUtils::ConvertToQColor(colour));
979       material->setShininess(0.);                 866       material->setShininess(0.);
980       material->setSpecular(0.);                  867       material->setSpecular(0.);
981       wireframeEntity->addComponent(material);    868       wireframeEntity->addComponent(material);
982                                                   869 
983       renderer = new Qt3DRender::QGeometryRend    870       renderer = new Qt3DRender::QGeometryRenderer;
984       renderer->setObjectName("polyhedronWiref    871       renderer->setObjectName("polyhedronWireframeRenderer");
985       renderer->setGeometry(lineGeometry);        872       renderer->setGeometry(lineGeometry);
986       renderer->setVertexCount(2*(G4int)nLines << 873       renderer->setVertexCount(2*nLines);
987       renderer->setPrimitiveType(Qt3DRender::Q    874       renderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines);
988       wireframeEntity->addComponent(renderer);    875       wireframeEntity->addComponent(renderer);
989                                                   876 
990       break;                                      877       break;
991                                                   878 
992     case G4ViewParameters::hlr:                   879     case G4ViewParameters::hlr:
993                                                   880 
994       // Surfaces with background colour to hi    881       // Surfaces with background colour to hide the edges
995                                                   882 
996       vertexGeometry->addAttribute(positionAtt    883       vertexGeometry->addAttribute(positionAtt);
997       vertexGeometry->addAttribute(normalAtt);    884       vertexGeometry->addAttribute(normalAtt);
998                                                   885 
999       material = new Qt3DExtras::QDiffuseSpecu    886       material = new Qt3DExtras::QDiffuseSpecularMaterial();
1000       material->setObjectName("materialForHid    887       material->setObjectName("materialForHiddenLines");
1001       material->setAmbient(Qt::white);  // Wh    888       material->setAmbient(Qt::white);  // White for now (should be from fVP)
1002       material->setShininess(0.);                889       material->setShininess(0.);
1003       material->setSpecular(0.);                 890       material->setSpecular(0.);
1004       surfaceEntity->addComponent(material);     891       surfaceEntity->addComponent(material);
1005                                                  892 
1006       renderer = new Qt3DRender::QGeometryRen    893       renderer = new Qt3DRender::QGeometryRenderer;
1007       renderer->setObjectName("polyhedronSurf    894       renderer->setObjectName("polyhedronSurfaceRenderer");
1008       renderer->setGeometry(vertexGeometry);     895       renderer->setGeometry(vertexGeometry);
1009       renderer->setVertexCount((G4int)nVerts) << 896       renderer->setVertexCount(nVerts);
1010       renderer->setPrimitiveType(Qt3DRender::    897       renderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles);
1011       surfaceEntity->addComponent(renderer);     898       surfaceEntity->addComponent(renderer);
1012                                                  899 
1013       // Edges                                   900       // Edges
1014                                                  901 
1015       lineGeometry->addAttribute(lineAtt);       902       lineGeometry->addAttribute(lineAtt);
1016       lineGeometry->addAttribute(dummyNormalL << 
1017                                                  903 
1018       material = new Qt3DExtras::QDiffuseSpec    904       material = new Qt3DExtras::QDiffuseSpecularMaterial();
1019       material->setObjectName("materialForWir    905       material->setObjectName("materialForWireFrame");
1020       material->setAmbient(G4Qt3DUtils::Conve    906       material->setAmbient(G4Qt3DUtils::ConvertToQColor(colour));
1021       material->setShininess(0.);                907       material->setShininess(0.);
1022       material->setSpecular(0.);                 908       material->setSpecular(0.);
1023       wireframeEntity->addComponent(material)    909       wireframeEntity->addComponent(material);
1024                                                  910 
1025       renderer = new Qt3DRender::QGeometryRen    911       renderer = new Qt3DRender::QGeometryRenderer;
1026       renderer->setObjectName("polyhedronWire    912       renderer->setObjectName("polyhedronWireframeRenderer");
1027       renderer->setGeometry(lineGeometry);       913       renderer->setGeometry(lineGeometry);
1028       renderer->setVertexCount(2*(G4int)nLine << 914       renderer->setVertexCount(2*nLines);
1029       renderer->setPrimitiveType(Qt3DRender::    915       renderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines);
1030       wireframeEntity->addComponent(renderer)    916       wireframeEntity->addComponent(renderer);
1031                                                  917 
1032       break;                                     918       break;
1033                                                  919 
1034     case G4ViewParameters::hsr:                  920     case G4ViewParameters::hsr:
1035                                                  921 
1036       vertexGeometry->addAttribute(positionAt    922       vertexGeometry->addAttribute(positionAtt);
1037       vertexGeometry->addAttribute(normalAtt)    923       vertexGeometry->addAttribute(normalAtt);
1038                                                  924 
1039       material = new Qt3DExtras::QDiffuseSpec    925       material = new Qt3DExtras::QDiffuseSpecularMaterial();
1040       material->setObjectName("materialForSur    926       material->setObjectName("materialForSurface");
1041       material->setAmbient(G4Qt3DUtils::Conve    927       material->setAmbient(G4Qt3DUtils::ConvertToQColor(colour));
1042       if (colour.GetAlpha() < 1.) material->s    928       if (colour.GetAlpha() < 1.) material->setAlphaBlendingEnabled(true);
1043       surfaceEntity->addComponent(material);     929       surfaceEntity->addComponent(material);
1044                                                  930 
1045       renderer = new Qt3DRender::QGeometryRen    931       renderer = new Qt3DRender::QGeometryRenderer;
1046       renderer->setObjectName("polyhedronSurf    932       renderer->setObjectName("polyhedronSurfaceRenderer");
1047       renderer->setGeometry(vertexGeometry);     933       renderer->setGeometry(vertexGeometry);
1048       renderer->setVertexCount((G4int)nVerts) << 934       renderer->setVertexCount(nVerts);
1049       renderer->setPrimitiveType(Qt3DRender::    935       renderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles);
1050       surfaceEntity->addComponent(renderer);     936       surfaceEntity->addComponent(renderer);
1051                                                  937 
1052       break;                                     938       break;
1053                                                  939 
1054     case G4ViewParameters::hlhsr:                940     case G4ViewParameters::hlhsr:
1055                                                  941 
1056       // Surfaces                                942       // Surfaces
1057                                                  943 
1058       vertexGeometry->addAttribute(positionAt    944       vertexGeometry->addAttribute(positionAtt);
1059       vertexGeometry->addAttribute(normalAtt)    945       vertexGeometry->addAttribute(normalAtt);
1060                                                  946 
1061       material = new Qt3DExtras::QDiffuseSpec    947       material = new Qt3DExtras::QDiffuseSpecularMaterial();
1062       material->setObjectName("materialForSur    948       material->setObjectName("materialForSurface");
1063       material->setAmbient(G4Qt3DUtils::Conve    949       material->setAmbient(G4Qt3DUtils::ConvertToQColor(colour));
1064       if (colour.GetAlpha() < 1.) material->s    950       if (colour.GetAlpha() < 1.) material->setAlphaBlendingEnabled(true);
1065       surfaceEntity->addComponent(material);     951       surfaceEntity->addComponent(material);
1066                                                  952 
1067       renderer = new Qt3DRender::QGeometryRen    953       renderer = new Qt3DRender::QGeometryRenderer;
1068       renderer->setObjectName("polyhedronSurf    954       renderer->setObjectName("polyhedronSurfaceRenderer");
1069       renderer->setGeometry(vertexGeometry);     955       renderer->setGeometry(vertexGeometry);
1070       renderer->setVertexCount((G4int)nVerts) << 956       renderer->setVertexCount(nVerts);
1071       renderer->setPrimitiveType(Qt3DRender::    957       renderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles);
1072       surfaceEntity->addComponent(renderer);     958       surfaceEntity->addComponent(renderer);
1073                                                  959 
1074       // Edges                                   960       // Edges
1075                                                  961 
1076       lineGeometry->addAttribute(lineAtt);       962       lineGeometry->addAttribute(lineAtt);
1077       lineGeometry->addAttribute(dummyNormalL << 
1078                                                  963 
1079       material = new Qt3DExtras::QDiffuseSpec    964       material = new Qt3DExtras::QDiffuseSpecularMaterial();
1080       material->setObjectName("materialForWir    965       material->setObjectName("materialForWireframe");
1081       material->setAmbient(G4Qt3DUtils::Conve    966       material->setAmbient(G4Qt3DUtils::ConvertToQColor(colour));
1082       material->setShininess(0.);                967       material->setShininess(0.);
1083       material->setSpecular(0.);                 968       material->setSpecular(0.);
1084       wireframeEntity->addComponent(material)    969       wireframeEntity->addComponent(material);
1085                                                  970 
1086       renderer = new Qt3DRender::QGeometryRen    971       renderer = new Qt3DRender::QGeometryRenderer;
1087       renderer->setObjectName("polyhedronSurf    972       renderer->setObjectName("polyhedronSurfaceRenderer");
1088       renderer->setGeometry(lineGeometry);       973       renderer->setGeometry(lineGeometry);
1089       renderer->setVertexCount(2*(G4int)nLine << 974       renderer->setVertexCount(2*nLines);
1090       renderer->setPrimitiveType(Qt3DRender::    975       renderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines);
1091       wireframeEntity->addComponent(renderer)    976       wireframeEntity->addComponent(renderer);
1092                                                  977 
1093       break;                                     978       break;
1094                                                  979 
1095     case G4ViewParameters::cloud:                980     case G4ViewParameters::cloud:
1096       // Case trapped at start of function, s    981       // Case trapped at start of function, so no need to implement
1097       break;                                     982       break;
1098   }                                              983   }
1099 }                                                984 }
1100                                                  985 
1101 void G4Qt3DSceneHandler::AddCompound(const G4 << 
1102 {                                             << 
1103   StandardSpecialMeshRendering(mesh);         << 
1104 }                                             << 
1105                                               << 
1106 void G4Qt3DSceneHandler::ClearStore ()           986 void G4Qt3DSceneHandler::ClearStore ()
1107 {                                                987 {
1108   G4Qt3DUtils::delete_components_and_children    988   G4Qt3DUtils::delete_components_and_children_of_entity_recursively(fpQt3DScene);
1109   EstablishG4Qt3DQEntities();                    989   EstablishG4Qt3DQEntities();
1110 }                                                990 }
1111                                                  991 
1112 void G4Qt3DSceneHandler::ClearTransientStore     992 void G4Qt3DSceneHandler::ClearTransientStore ()
1113 {                                                993 {
1114   G4Qt3DUtils::delete_components_and_children    994   G4Qt3DUtils::delete_components_and_children_of_entity_recursively(fpTransientObjects);
1115 }                                                995 }
                                                   >> 996 
                                                   >> 997 #endif  // #if defined (G4VIS_BUILD_QT3D_DRIVER) || defined (G4VIS_USE_QT3D)
1116                                                  998