Import Geant4 11.3.0 source tree
This commit is contained in:
@@ -6,6 +6,25 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2024-10-17 John Allison (visVtk-V11-02-07)
|
||||
- G4VtkMessenger.cc:
|
||||
- Added x3d to /vis/vtk/export format parameter guidance.
|
||||
- Set parameter omitables to false.
|
||||
|
||||
## 2024-10-07 Stewart Boogert (visVtk-V11-02-06)
|
||||
- G4VtkViewer:
|
||||
- Added export for X3D file format
|
||||
|
||||
## 2024-08-13 John Allison (visVtk-V11-02-05)
|
||||
- G4VtkQtViewer:
|
||||
- Resolve the timing issues around switching to the vis sub-thread with the
|
||||
use of G4CONDITIONWAITLAMBDA.
|
||||
|
||||
## 2024-07-12 Guy Barrand (visVtk-V11-02-04)
|
||||
- G4VtkQtViewer: in DoneWithVisSubThread(), SwitchToMasterThread() protect against a
|
||||
possible null qGLW->context(). It permits to avoid a crash in case of doing /run/beamOn
|
||||
in vis.mac at startup.
|
||||
|
||||
## 2024-05-27 Guy Barrand (visVtk-V11-02-03)
|
||||
- G4VtxQtViewer: MT: have the variables mWaitForVisSubThreadQtOpenGLContextMoved,
|
||||
mWaitForVisSubThreadQtOpenGLContextInitialized,
|
||||
|
||||
@@ -59,7 +59,17 @@ class G4VtkQtViewer : public QVTKOpenGLNativeWidget, public G4VtkViewer
|
||||
void Initialise() override;
|
||||
virtual void CreateMainWindow(QVTKOpenGLNativeWidget*, const QString&);
|
||||
#ifdef G4MULTITHREADED
|
||||
// In MT mode these functions are called in the following order for each run:
|
||||
// For switching threads in MT mode
|
||||
// Note: the order of calling of MovingToVisSubThread and SwitchToVisSubThread
|
||||
// is undefined, so we have to use mutexes to ensure required information,
|
||||
// namely the vis sub-thread address, is available before moving objects.
|
||||
// To summarise, the order of calling is
|
||||
// DoneWithMasterThread
|
||||
// MovingToVisSubThread ) or ( SwitchToVisSubThread
|
||||
// SwitchToVisSubThread ) ( MovingToVisSubThread
|
||||
// DoneWithVisSubThread
|
||||
// MovingToMasterThread
|
||||
// SwitchToMasterThread
|
||||
// Called on the master thread before starting the vis sub-thread.
|
||||
void DoneWithMasterThread() override;
|
||||
// Called on the master thread after starting the vis sub-thread.
|
||||
@@ -69,12 +79,9 @@ class G4VtkQtViewer : public QVTKOpenGLNativeWidget, public G4VtkViewer
|
||||
// Called on the vis sub-thread when all events have been processed.
|
||||
void DoneWithVisSubThread() override;
|
||||
// Called on the vis sub-thread when all events have been processed.
|
||||
// virtual void MovingToMasterThread (); Not used in G4OpenGLQtViewer.
|
||||
// virtual void MovingToMasterThread (); Not used in G4VtkQtViewer.
|
||||
// Called on the master thread after the vis sub-thread has terminated.
|
||||
void SwitchToMasterThread() override;
|
||||
|
||||
inline void SetQGLContextVisSubThread(QThread* th) { fQGLContextVisSubThread = th; }
|
||||
inline void SetQGLContextMainThread(QThread* th) { fQGLContextMainThread = th; }
|
||||
#endif
|
||||
|
||||
void FinishView() override;
|
||||
@@ -103,14 +110,8 @@ class G4VtkQtViewer : public QVTKOpenGLNativeWidget, public G4VtkViewer
|
||||
QWidget* fGLWidget;
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
QThread* fQGLContextVisSubThread;
|
||||
QThread* fQGLContextMainThread;
|
||||
G4Mutex fmWaitForVisSubThreadQtOpenGLContextMoved;
|
||||
G4Mutex fmWaitForVisSubThreadQtOpenGLContextInitialized;
|
||||
G4Condition fc1_VisSubThreadQtOpenGLContextInitialized;
|
||||
G4Condition fc2_VisSubThreadQtOpenGLContextMoved;
|
||||
G4AutoLock* flWaitForVisSubThreadQtOpenGLContextInitialized;
|
||||
G4AutoLock* flWaitForVisSubThreadQtOpenGLContextMoved;
|
||||
QThread* fQVtkContextVisSubThread;
|
||||
QThread* fQVtkContextMainThread;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -229,6 +229,7 @@ class G4VtkViewer : public G4VViewer
|
||||
void ExportVRMLScene(G4String);
|
||||
void ExportVTPScene(G4String);
|
||||
void ExportGLTFScene(G4String);
|
||||
void ExportX3DScene(G4String);
|
||||
void ExportJSONRenderWindowScene(G4String);
|
||||
void ExportVTPCutter(G4String fileName);
|
||||
void ExportFormatStore(G4String fileName, G4String store);
|
||||
|
||||
@@ -62,12 +62,12 @@ G4VtkMessenger::G4VtkMessenger()
|
||||
fpCommandExport->SetGuidance("Export a screenshot or OBJ file of current Vtk viewer");
|
||||
|
||||
// File type for export
|
||||
auto parameterExport = new G4UIparameter("format", 's', omitable = true);
|
||||
fpCommandExport->SetGuidance("File type (jpg,tiff,eps,ps,obj,vtp,gltf,vrml)");
|
||||
auto parameterExport = new G4UIparameter("format", 's', omitable = false);
|
||||
fpCommandExport->SetGuidance("File type (jpg,tiff,eps,ps,obj,vtp,gltf,vrml,x3d)");
|
||||
fpCommandExport->SetParameter(parameterExport);
|
||||
|
||||
// File name for export
|
||||
parameterExport = new G4UIparameter("file-name", 's', omitable = true);
|
||||
parameterExport = new G4UIparameter("file-name", 's', omitable = false);
|
||||
fpCommandExport->SetGuidance("File name");
|
||||
fpCommandExport->SetParameter(parameterExport);
|
||||
|
||||
@@ -332,6 +332,8 @@ void G4VtkMessenger::SetNewValue(G4UIcommand* command, G4String newValue)
|
||||
pVtkViewer->ExportVTPScene(name);
|
||||
else if (format == "gltf")
|
||||
pVtkViewer->ExportGLTFScene(name);
|
||||
else if (format == "x3d")
|
||||
pVtkViewer->ExportX3DScene(name);
|
||||
else
|
||||
G4cout << "Unknown /vis/vtk/export file format" << G4endl;
|
||||
}
|
||||
|
||||
@@ -58,22 +58,12 @@
|
||||
G4VtkQtViewer::G4VtkQtViewer(G4VSceneHandler& sceneHandler, const G4String& name)
|
||||
: G4VtkViewer(sceneHandler, name)
|
||||
{
|
||||
#ifdef G4MULTITHREADED
|
||||
flWaitForVisSubThreadQtOpenGLContextInitialized =
|
||||
new G4AutoLock(fmWaitForVisSubThreadQtOpenGLContextInitialized, std::defer_lock);
|
||||
flWaitForVisSubThreadQtOpenGLContextMoved =
|
||||
new G4AutoLock(fmWaitForVisSubThreadQtOpenGLContextMoved, std::defer_lock);
|
||||
#endif
|
||||
G4Qt::getInstance();
|
||||
//this->setFormat(QVTKOpenGLNativeWidget::defaultFormat());
|
||||
}
|
||||
|
||||
G4VtkQtViewer::~G4VtkQtViewer()
|
||||
{
|
||||
#ifdef G4MULTITHREADED
|
||||
delete flWaitForVisSubThreadQtOpenGLContextInitialized;
|
||||
delete flWaitForVisSubThreadQtOpenGLContextMoved;
|
||||
#endif
|
||||
}
|
||||
|
||||
void G4VtkQtViewer::Initialise()
|
||||
@@ -113,100 +103,101 @@ void G4VtkQtViewer::CreateMainWindow(QVTKOpenGLNativeWidget* vtkWidget, const QS
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
|
||||
namespace {
|
||||
G4Mutex visSubThreadMutex = G4MUTEX_INITIALIZER;
|
||||
G4Condition waitForVisSubThreadInitialized = G4CONDITION_INITIALIZER;
|
||||
G4bool visSubThreadEstablished = false;
|
||||
G4bool qObjectsSwitched = false;
|
||||
QVTKOpenGLNativeWidget* qVtkW = nullptr;
|
||||
}
|
||||
|
||||
void G4VtkQtViewer::DoneWithMasterThread()
|
||||
{
|
||||
// Called by Main Thread !
|
||||
|
||||
// Useful to avoid two vis thread at the same time
|
||||
// G4MUTEXLOCK(&fmWaitForVisSubThreadQtOpenGLContextInitialized);
|
||||
if (!flWaitForVisSubThreadQtOpenGLContextInitialized->owns_lock())
|
||||
flWaitForVisSubThreadQtOpenGLContextInitialized->lock();
|
||||
// Initialise and check qVtkW - no need to check in subsequent functions
|
||||
qVtkW = dynamic_cast<QVTKOpenGLNativeWidget*>(fGLWidget);
|
||||
if (qVtkW == nullptr) return;
|
||||
|
||||
// Done with master thread
|
||||
qVtkW->doneCurrent();
|
||||
|
||||
// Set current QThread for the way back
|
||||
fQVtkContextMainThread = QThread::currentThread();
|
||||
}
|
||||
|
||||
void G4VtkQtViewer::MovingToVisSubThread()
|
||||
{
|
||||
// Still on master thread but vis thread has been launched
|
||||
|
||||
if (qVtkW == nullptr) return;
|
||||
|
||||
// Wait until SwitchToVisSubThread has found vis sub-thread QThread
|
||||
{
|
||||
G4AutoLock lock(&visSubThreadMutex);
|
||||
G4CONDITIONWAITLAMBDA(&waitForVisSubThreadInitialized, &lock, []{return visSubThreadEstablished;})
|
||||
}
|
||||
|
||||
// Move stuff to sub-thread
|
||||
if(qVtkW->context()) qVtkW->context()->moveToThread(fQVtkContextVisSubThread);
|
||||
|
||||
// Inform sub-thread
|
||||
G4AutoLock lock(&visSubThreadMutex);
|
||||
qObjectsSwitched = true;
|
||||
lock.unlock();
|
||||
G4CONDITIONBROADCAST(&waitForVisSubThreadInitialized);
|
||||
}
|
||||
|
||||
void G4VtkQtViewer::SwitchToVisSubThread()
|
||||
{
|
||||
// Called by VisSub Thread !
|
||||
|
||||
auto qGLW = dynamic_cast<QVTKOpenGLNativeWidget*>(fGLWidget);
|
||||
if (qGLW == nullptr) {
|
||||
return;
|
||||
if (qVtkW == nullptr) return;
|
||||
|
||||
fQVtkContextVisSubThread = QThread::currentThread();
|
||||
|
||||
// Let MovingToVisSubThread know we have the QThread
|
||||
{
|
||||
G4AutoLock lock(&visSubThreadMutex);
|
||||
visSubThreadEstablished = true;
|
||||
G4CONDITIONBROADCAST(&waitForVisSubThreadInitialized);
|
||||
}
|
||||
|
||||
// Set the current QThread to its static variable
|
||||
SetQGLContextVisSubThread(QThread::currentThread());
|
||||
|
||||
// - Wait for the vis thread to set its QThread
|
||||
G4CONDITIONBROADCAST(&fc1_VisSubThreadQtOpenGLContextInitialized);
|
||||
// a condition without a locked mutex is an undefined behavior.
|
||||
// we check if the mutex owns the lock, and if not, we lock it
|
||||
if (!flWaitForVisSubThreadQtOpenGLContextMoved->owns_lock())
|
||||
flWaitForVisSubThreadQtOpenGLContextMoved->lock();
|
||||
|
||||
// Unlock the vis thread if it is Qt Viewer
|
||||
G4CONDITIONWAIT(&fc2_VisSubThreadQtOpenGLContextMoved, flWaitForVisSubThreadQtOpenGLContextMoved);
|
||||
// Wait until MovingToVisSubThread has moved stuff
|
||||
{
|
||||
G4AutoLock lock(&visSubThreadMutex);
|
||||
G4CONDITIONWAITLAMBDA(&waitForVisSubThreadInitialized, &lock, []{return qObjectsSwitched;})
|
||||
}
|
||||
|
||||
// make context current
|
||||
qGLW->makeCurrent();
|
||||
qVtkW->makeCurrent();
|
||||
}
|
||||
|
||||
void G4VtkQtViewer::DoneWithVisSubThread()
|
||||
{
|
||||
// Called by vis sub thread
|
||||
auto qGLW = dynamic_cast<QVTKOpenGLNativeWidget*>(fGLWidget);
|
||||
if (qGLW == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (qVtkW == nullptr) return;
|
||||
|
||||
// finish with this vis sub thread context
|
||||
qGLW->doneCurrent();
|
||||
qVtkW->doneCurrent();
|
||||
|
||||
// and move it back to the main thread
|
||||
qGLW->context()->moveToThread(fQGLContextMainThread);
|
||||
if(qVtkW->context()) qVtkW->context()->moveToThread(fQVtkContextMainThread);
|
||||
}
|
||||
|
||||
void G4VtkQtViewer::SwitchToMasterThread()
|
||||
{
|
||||
// Called by VisSub Thread !
|
||||
|
||||
auto qGLW = dynamic_cast<QVTKOpenGLNativeWidget*>(fGLWidget);
|
||||
if (qGLW == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (qVtkW == nullptr) return;
|
||||
|
||||
// Useful to avoid two vis thread at the same time
|
||||
// G4MUTEXUNLOCK(&fmWaitForVisSubThreadQtOpenGLContextInitialized);
|
||||
if (flWaitForVisSubThreadQtOpenGLContextInitialized->owns_lock())
|
||||
flWaitForVisSubThreadQtOpenGLContextInitialized->unlock();
|
||||
qVtkW->makeCurrent();
|
||||
|
||||
qGLW->makeCurrent();
|
||||
visSubThreadEstablished = false;
|
||||
qObjectsSwitched = false;
|
||||
}
|
||||
|
||||
void G4VtkQtViewer::MovingToVisSubThread()
|
||||
{
|
||||
// Called by Main Thread !
|
||||
|
||||
auto qGLW = dynamic_cast<QVTKOpenGLNativeWidget*>(fGLWidget);
|
||||
if (qGLW == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// a condition without a locked mutex is an undefined behavior.
|
||||
// we check if the mutex owns the lock, and if not, we lock it
|
||||
if (!flWaitForVisSubThreadQtOpenGLContextInitialized->owns_lock())
|
||||
flWaitForVisSubThreadQtOpenGLContextInitialized->lock();
|
||||
|
||||
// - Wait for the vis sub thread to set its QThread
|
||||
G4CONDITIONWAIT(&fc1_VisSubThreadQtOpenGLContextInitialized,
|
||||
flWaitForVisSubThreadQtOpenGLContextInitialized);
|
||||
|
||||
// Set current QThread for the way back
|
||||
SetQGLContextMainThread(QThread::currentThread());
|
||||
|
||||
// finish with this main thread context
|
||||
qGLW->doneCurrent();
|
||||
qGLW->context()->moveToThread(fQGLContextVisSubThread);
|
||||
G4CONDITIONBROADCAST(&fc2_VisSubThreadQtOpenGLContextMoved);
|
||||
}
|
||||
#endif
|
||||
|
||||
void G4VtkQtViewer::FinishView()
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include <vtkOBJImporter.h>
|
||||
#include <vtkGLTFExporter.h>
|
||||
#include <vtkOOGLExporter.h>
|
||||
#include <vtkX3DExporter.h>
|
||||
#include <vtkJSONRenderWindowExporter.h>
|
||||
#include <vtkVtkJSSceneGraphSerializer.h>
|
||||
//#include <vtkBufferedArchiver.h>
|
||||
@@ -417,6 +418,14 @@ void G4VtkViewer::ExportGLTFScene(G4String fileName) {
|
||||
exporter->Write();
|
||||
}
|
||||
|
||||
void G4VtkViewer::ExportX3DScene(G4String fileName) {
|
||||
vtkSmartPointer<vtkX3DExporter> exporter = vtkSmartPointer<vtkX3DExporter>::New();
|
||||
exporter->SetRenderWindow(_renderWindow);
|
||||
exporter->SetFileName((fileName+".x3d").c_str());
|
||||
exporter->Write();
|
||||
}
|
||||
|
||||
|
||||
void G4VtkViewer::ExportJSONRenderWindowScene(G4String /*fileName*/) {
|
||||
vtkSmartPointer<vtkJSONRenderWindowExporter> exporter = vtkSmartPointer<vtkJSONRenderWindowExporter>::New();
|
||||
vtkSmartPointer<vtkVtkJSSceneGraphSerializer> serializer = vtkSmartPointer<vtkVtkJSSceneGraphSerializer>::New();
|
||||
|
||||
Reference in New Issue
Block a user