Import Geant4 11.0.0 source tree
This commit is contained in:
committed by
Ben Morgan
parent
6399a014b6
commit
80e2389dd8
@@ -0,0 +1,4 @@
|
||||
# - G4visVtk category build
|
||||
|
||||
geant4_global_library_target(COMPONENTS sources.cmake)
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
-------------------------------------------------------------------
|
||||
|
||||
=========================================================
|
||||
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
|
||||
=========================================================
|
||||
|
||||
Category History file
|
||||
---------------------
|
||||
This file should be used by G4 developers and category coordinators
|
||||
to briefly summarize all major modifications introduced in the code
|
||||
and keep track of all category-tags.
|
||||
|
||||
----------------------------------------------------------
|
||||
* Reverse chronological order (last date on top), please *
|
||||
----------------------------------------------------------
|
||||
|
||||
History file for visualization/Vtk sub-category
|
||||
-----------------------------------------------
|
||||
8 November 2021 - Ben Morgan (visVtk-V10-07-03)
|
||||
- Retire G4UI/G4INTY_... preprocessor symbols in toolkit build, only required
|
||||
by obsolete GNUmake system
|
||||
|
||||
15 October 2021 John Allison (visVtk-V10-07-02)
|
||||
- Implement G4VtkQt::IsUISessionCompatible.
|
||||
|
||||
04 October 2021 Stewart Boogert / Laurie Nevay (visVtk-V10-07-01)
|
||||
- Operational VTK viewer (VtkNative and VtkQt)
|
||||
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// John Allison 5th April 2001
|
||||
// A template for a simplest possible graphics driver.
|
||||
//?? Lines beginning like this require specialisation for your driver.
|
||||
|
||||
#ifndef G4VTK_HH
|
||||
#define G4VTK_HH
|
||||
|
||||
#include "G4VGraphicsSystem.hh"
|
||||
|
||||
class G4Vtk: public G4VGraphicsSystem {
|
||||
public:
|
||||
G4Vtk();
|
||||
virtual ~G4Vtk();
|
||||
G4VSceneHandler* CreateSceneHandler(const G4String& name = "");
|
||||
G4VViewer* CreateViewer (G4VSceneHandler&, const G4String& name = "");
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,56 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
|
||||
#ifndef G4GVTKMESSENGER_HH
|
||||
#define G4GVTKMESSENGER_HH 1
|
||||
|
||||
#include "G4UImessenger.hh"
|
||||
#include <vector>
|
||||
|
||||
class G4UIdirectory;
|
||||
class G4UIcmdWithABool;
|
||||
class G4UIcmdWithAString;
|
||||
class G4UIcommand;
|
||||
class G4UIcmdWithoutParameter;
|
||||
|
||||
class G4VtkMessenger : public G4UImessenger {
|
||||
|
||||
public:
|
||||
|
||||
static G4VtkMessenger* GetInstance();
|
||||
virtual ~G4VtkMessenger();
|
||||
|
||||
virtual G4String GetCurrentValue(G4UIcommand * command);
|
||||
virtual void SetNewValue(G4UIcommand * command, G4String newValue);
|
||||
|
||||
private:
|
||||
static G4VtkMessenger* fpInstance;
|
||||
G4VtkMessenger();
|
||||
G4UIdirectory* fpDirectory;
|
||||
G4UIcommand* fpCommandExport;
|
||||
G4UIcmdWithABool* fpCommandWarnings;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
|
||||
|
||||
#ifndef G4VTKQT_HH
|
||||
#define G4VTKQT_HH
|
||||
|
||||
#include "G4VGraphicsSystem.hh"
|
||||
|
||||
class G4VtkQt: public G4VGraphicsSystem {
|
||||
public:
|
||||
G4VtkQt();
|
||||
virtual ~G4VtkQt();
|
||||
G4VSceneHandler* CreateSceneHandler(const G4String& name = "");
|
||||
G4VViewer* CreateViewer (G4VSceneHandler&, const G4String& name = "");
|
||||
G4bool IsUISessionCompatible () const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
|
||||
#ifndef G4VTKQTSCENEHANDLER_HH
|
||||
#define G4VTKQTSCENEHANDLER_HH
|
||||
|
||||
|
||||
#include "G4VSceneHandler.hh"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "G4VtkQtViewer.hh"
|
||||
#include "G4VtkSceneHandler.hh"
|
||||
|
||||
class G4VtkQtSceneHandler: public G4VtkSceneHandler {
|
||||
friend class G4VtkQtViewer;
|
||||
|
||||
public:
|
||||
G4VtkQtSceneHandler(G4VGraphicsSystem& system, const G4String& name);
|
||||
virtual ~G4VtkQtSceneHandler();
|
||||
|
||||
protected:
|
||||
static G4int fSceneIdCount; // Counter for Vtk scene handlers.
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
|
||||
#ifndef G4VTKQTVIEWER_HH
|
||||
#define G4VTKQTVIEWER_HH
|
||||
|
||||
// #define G4VTKDEBUG // Comment this out to suppress debug code.
|
||||
|
||||
#include "G4VViewer.hh"
|
||||
|
||||
class G4UIManager;
|
||||
class G4UIQt;
|
||||
|
||||
#include "QVTKOpenGLNativeWidget.h"
|
||||
#include "G4VtkViewer.hh"
|
||||
|
||||
class G4VtkQtViewer: public QVTKOpenGLNativeWidget, public G4VtkViewer {
|
||||
public:
|
||||
G4VtkQtViewer(G4VSceneHandler &, const G4String &name);
|
||||
virtual ~G4VtkQtViewer();
|
||||
void Initialise();
|
||||
virtual void CreateMainWindow(QVTKOpenGLNativeWidget*, const QString&);
|
||||
void FinishView();
|
||||
|
||||
private:
|
||||
|
||||
G4UIQt* fUiQt;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,171 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// John Allison 5th April 2001
|
||||
// A template for a simplest possible graphics driver.
|
||||
//?? Lines or sections marked like this require specialisation for your driver.
|
||||
|
||||
#ifndef G4VTKSCENEHANDLER_HH
|
||||
#define G4VTKSCENEHANDLER_HH
|
||||
|
||||
|
||||
#include "G4VSceneHandler.hh"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "G4VtkViewer.hh"
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wextra-semi"
|
||||
#include "vtkSmartPointer.h"
|
||||
#include "vtkPolyData.h"
|
||||
#include "vtkLine.h"
|
||||
#include "vtkNamedColors.h"
|
||||
#include "vtkProperty.h"
|
||||
#include "vtkTextProperty.h"
|
||||
#include "vtkPolyDataMapper.h"
|
||||
#include "vtkActor.h"
|
||||
#include "vtkFollower.h"
|
||||
#include "vtkTextActor.h"
|
||||
#include "vtkBillboardTextActor3D.h"
|
||||
#include "vtkRegularPolygonSource.h"
|
||||
#include "vtkSphereSource.h"
|
||||
#include "vtkFeatureEdges.h"
|
||||
#include "vtkCleanPolyData.h"
|
||||
#include "vtkPolyDataNormals.h"
|
||||
#include "vtkGlyph2D.h"
|
||||
#include "vtkGlyph3D.h"
|
||||
#include "vtkVertexGlyphFilter.h"
|
||||
#include "vtkMatrix4x4.h"
|
||||
#include "vtkDoubleArray.h"
|
||||
#include "vtkPointData.h"
|
||||
#include "vtkTriangleFilter.h"
|
||||
#include "vtkTensorGlyph.h"
|
||||
#include "vtkTensorGlyphColor.h"
|
||||
#include "vtkScalarsToColors.h"
|
||||
#include "vtkImageData.h"
|
||||
#include "vtkVolume.h"
|
||||
#include "vtkOpenGLGPUVolumeRayCastMapper.h"
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
class G4VtkSceneHandler: public G4VSceneHandler {
|
||||
friend class G4VtkViewer;
|
||||
|
||||
public:
|
||||
G4VtkSceneHandler(G4VGraphicsSystem& system, const G4String& name);
|
||||
virtual ~G4VtkSceneHandler() = default;
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Required implementation of pure virtual functions...
|
||||
|
||||
void AddPrimitive(const G4Polyline&);
|
||||
void AddPrimitive(const G4Text&);
|
||||
void AddPrimitive(const G4Circle&);
|
||||
void AddPrimitive(const G4Square&);
|
||||
void AddPrimitive(const G4Polyhedron&);
|
||||
void AddPrimitiveTensorGlyph(const G4Polyhedron&);
|
||||
void AddPrimitiveBakedTransform(const G4Polyhedron&);
|
||||
|
||||
// Further optional AddPrimitive methods. Explicitly invoke base
|
||||
// class methods if not otherwise defined to avoid warnings about
|
||||
// hiding of base class methods.
|
||||
void AddPrimitive(const G4Polymarker& polymarker)
|
||||
{
|
||||
#ifdef G4VTKDEBUG
|
||||
G4cout << "=================================" << G4endl;
|
||||
G4cout << "G4VtkSceneHandler::AddPrimitive(const G4Polymarker& polymarker) called." << G4endl;
|
||||
#endif
|
||||
G4VSceneHandler::AddPrimitive (polymarker);
|
||||
}
|
||||
/*
|
||||
void AddPrimitive(const G4Scale& scale)
|
||||
{
|
||||
#ifdef G4VTKDEBUG
|
||||
G4cout << "=================================" << G4endl;
|
||||
G4cout << "G4VtkSceneHandler::AddScale(const G4Scale& scale) called." <<
|
||||
G4endl; #endif G4VSceneHandler::AddPrimitive(scale);
|
||||
}
|
||||
*/
|
||||
|
||||
void AddSolid(const G4Box& box);
|
||||
void AddCompound(const G4Mesh& mesh);
|
||||
|
||||
void Modified();
|
||||
void Clear();
|
||||
|
||||
protected:
|
||||
static G4int fSceneIdCount; // Counter for Vtk scene handlers.
|
||||
|
||||
// maps for polylines
|
||||
std::map<std::size_t, const G4VisAttributes*> polylineVisAttributesMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkPoints>> polylineDataMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkCellArray>> polylineLineMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkPolyData>> polylinePolyDataMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkPolyDataMapper>> polylinePolyDataMapperMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkActor>> polylinePolyDataActorMap;
|
||||
|
||||
// maps for circles
|
||||
std::map<std::size_t, const G4VisAttributes*> circleVisAttributesMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkPoints>> circleDataMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkPolyData>> circlePolyDataMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkVertexGlyphFilter>> circleFilterMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkPolyDataMapper>> circlePolyDataMapperMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkActor>> circlePolyDataActorMap;
|
||||
|
||||
// maps for squares
|
||||
std::map<std::size_t, const G4VisAttributes*> squareVisAttributesMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkPoints>> squareDataMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkPolyData>> squarePolyDataMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkVertexGlyphFilter>> squareFilterMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkPolyDataMapper>> squarePolyDataMapperMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkActor>> squarePolyDataActorMap;
|
||||
|
||||
// map for polyhedra
|
||||
std::map<std::size_t, const G4VisAttributes*> polyhedronVisAttributesMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkPoints>> polyhedronDataMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkCellArray>> polyhedronPolyMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkPolyData>> polyhedronPolyDataMap;
|
||||
std::map<std::size_t, std::size_t> polyhedronPolyDataCountMap;
|
||||
|
||||
// map for polyhedra instances
|
||||
std::map<std::size_t, vtkSmartPointer<vtkPoints>> instancePositionMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkDoubleArray>> instanceRotationMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkDoubleArray>> instanceColoursMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkPolyData>> instancePolyDataMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkTensorGlyphColor>> instanceTensorGlyphMap;
|
||||
std::map<std::size_t, vtkSmartPointer<vtkActor>> instanceActorMap;
|
||||
|
||||
|
||||
private:
|
||||
#ifdef G4VTKDEBUG
|
||||
void PrintThings();
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,193 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// John Allison 5th April 2001
|
||||
// A template for a simplest possible graphics driver.
|
||||
//?? Lines or sections marked like this require specialisation for your driver.
|
||||
|
||||
#ifndef G4VTKVIEWER_HH
|
||||
#define G4VTKVIEWER_HH
|
||||
|
||||
// #define G4VTKDEBUG // Comment this out to suppress debug code.
|
||||
|
||||
#include "G4VViewer.hh"
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wextra-semi"
|
||||
#include "vtkObject.h"
|
||||
#include "vtkAutoInit.h"
|
||||
#include "vtkCamera.h"
|
||||
#include "vtkLight.h"
|
||||
#include "vtkRenderer.h"
|
||||
#include "vtkRenderWindow.h"
|
||||
#include "vtkRenderWindowInteractor.h"
|
||||
#include "vtkInteractorStyleTrackballCamera.h"
|
||||
#include "vtkInteractorStyleTerrain.h"
|
||||
#include "vtkTextActor.h"
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
VTK_MODULE_INIT(vtkRenderingOpenGL2)
|
||||
VTK_MODULE_INIT(vtkInteractionStyle);
|
||||
VTK_MODULE_INIT(vtkRenderingFreeType)
|
||||
|
||||
class vtkGeant4Callback : public vtkCommand
|
||||
{
|
||||
public:
|
||||
static vtkGeant4Callback* New() {return new vtkGeant4Callback;}
|
||||
|
||||
vtkGeant4Callback() { fVP = nullptr; }
|
||||
void SetGeant4ViewParameters(G4ViewParameters *VP) { fVP = VP;}
|
||||
void SetVtkInitialValues(G4double parallelScaleIn, G4double cameraDistanceIn)
|
||||
{
|
||||
parallelScale = parallelScaleIn;
|
||||
cameraDistance = cameraDistanceIn;
|
||||
}
|
||||
virtual void Execute(vtkObject *caller, unsigned long, void*)
|
||||
{
|
||||
vtkRenderer *ren = reinterpret_cast<vtkRenderer *>(caller);
|
||||
vtkCamera *cam = ren->GetActiveCamera();
|
||||
//G4cout << cam->GetFocalPoint()[0] << " " << cam->GetFocalPoint()[1] << " " << cam->GetFocalPoint()[2] << G4endl;
|
||||
//
|
||||
// G4cout << cam->GetPosition()[0] << " " << cam->GetPosition()[1] << " " << cam->GetPosition()[2] << G4endl;
|
||||
|
||||
auto cp = cam->GetPosition();
|
||||
auto fp = cam->GetFocalPoint();
|
||||
auto ud = cam->GetViewUp();
|
||||
|
||||
fVP->SetCurrentTargetPoint(G4Point3D(fp[0],fp[1],fp[2]));
|
||||
fVP->SetViewpointDirection((G4Point3D(cp[0],cp[1],cp[2]) -
|
||||
G4Point3D(fp[0],fp[1],fp[2])).unit());
|
||||
fVP->SetUpVector(G4Vector3D(ud[0],ud[1], ud[2]));
|
||||
|
||||
if(cam->GetParallelProjection()) {
|
||||
fVP->SetZoomFactor(parallelScale/cam->GetParallelScale());
|
||||
}
|
||||
else {
|
||||
auto cd = std::sqrt(std::pow(cp[0]-fp[0],2) +
|
||||
std::pow(cp[1]-cp[1],2) +
|
||||
std::pow(cp[2]-cp[2],2));
|
||||
fVP->SetZoomFactor(cameraDistance/cd);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
G4ViewParameters *fVP;
|
||||
G4double parallelScale;
|
||||
G4double cameraDistance;
|
||||
};
|
||||
|
||||
class vtkInfoCallback : public vtkCommand
|
||||
{
|
||||
public:
|
||||
static vtkInfoCallback *New() { return new vtkInfoCallback; }
|
||||
|
||||
vtkInfoCallback() {
|
||||
t1 = std::chrono::steady_clock::now();
|
||||
t2 = std::chrono::steady_clock::now();
|
||||
}
|
||||
void SetTextActor(vtkTextActor *txt) { this->TextActor = txt; }
|
||||
|
||||
virtual void Execute(vtkObject *caller, unsigned long, void*)
|
||||
{
|
||||
vtkRenderer *ren = reinterpret_cast<vtkRenderer *>(caller);
|
||||
int nActors = ren->GetActors()->GetNumberOfItems();
|
||||
vtkCamera *cam = ren->GetActiveCamera();
|
||||
if(!cam) return;
|
||||
|
||||
double *pos = cam->GetPosition();
|
||||
double *foc = cam->GetFocalPoint();
|
||||
double viewAngle = cam->GetViewAngle();
|
||||
double distance = cam->GetDistance();
|
||||
double parallelScale = cam->GetParallelScale();
|
||||
|
||||
if(!pos) return;
|
||||
|
||||
// Get current time
|
||||
t2 = std::chrono::steady_clock::now();
|
||||
|
||||
// Frame rate calculation
|
||||
std::chrono::duration<double> tdiff = t2-t1;
|
||||
t1 = t2;
|
||||
float fps = 1.0/tdiff.count();
|
||||
|
||||
// String for display
|
||||
sprintf(this->TextBuff,"camera position : %.1f %.1f %.1f \n"
|
||||
"camera focal point : %.1f %.1f %.1f \n"
|
||||
"view angle : %.1f\n"
|
||||
"distance : %.1f\n"
|
||||
"parallel scale : %.1f\n"
|
||||
"number actors : %i\n"
|
||||
"fps : %.1f",pos[0], pos[1], pos[2], foc[0], foc[1], foc[2], viewAngle, distance, parallelScale, nActors, fps);
|
||||
if(this->TextActor) {
|
||||
this->TextActor->SetInput(this->TextBuff);
|
||||
}
|
||||
}
|
||||
protected:
|
||||
vtkTextActor *TextActor;
|
||||
char TextBuff[256];
|
||||
std::chrono::time_point<std::chrono::steady_clock> t1;
|
||||
std::chrono::time_point<std::chrono::steady_clock> t2;
|
||||
};
|
||||
|
||||
class G4VtkViewer: public G4VViewer {
|
||||
public:
|
||||
G4VtkViewer(G4VSceneHandler&, const G4String& name);
|
||||
void Initialise();
|
||||
virtual ~G4VtkViewer();
|
||||
|
||||
void SetView();
|
||||
void ClearView();
|
||||
void DrawView();
|
||||
void ShowView();
|
||||
void FinishView();
|
||||
|
||||
void DrawViewHUD();
|
||||
void DrawShadows();
|
||||
|
||||
void ExportScreenShot(G4String, G4String);
|
||||
void ExportOBJScene(G4String);
|
||||
void ExportVRMLScene(G4String );
|
||||
void ExportVTPScene(G4String );
|
||||
|
||||
void ExportView(){};
|
||||
void SetGeant4View(){};
|
||||
|
||||
vtkNew<vtkTextActor> infoTextActor;
|
||||
vtkNew<vtkInfoCallback> infoCallback;
|
||||
vtkNew<vtkGeant4Callback> geant4Callback;
|
||||
vtkSmartPointer<vtkLight> light;
|
||||
vtkNew<vtkCamera> camera;
|
||||
vtkNew<vtkRenderer> renderer;
|
||||
vtkRenderWindow* _renderWindow;
|
||||
vtkRenderWindowInteractor* renderWindowInteractor;
|
||||
|
||||
private:
|
||||
G4bool firstSetView = true;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,261 @@
|
||||
/*=========================================================================
|
||||
|
||||
Program: Visualization Toolkit
|
||||
Module: vtkTensorGlyphColor.h
|
||||
|
||||
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
||||
All rights reserved.
|
||||
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the above copyright notice for more information.
|
||||
|
||||
=========================================================================*/
|
||||
/**
|
||||
* @class vtkTensorGlyphColor
|
||||
* @brief scale and orient glyph(s) according to eigenvalues and eigenvectors of symmetrical part of tensor
|
||||
*
|
||||
* vtkTensorGlyphColor is a filter that copies a geometric representation
|
||||
* (specified as polygonal data) to every input point. The geometric
|
||||
* representation, or glyph, can be scaled and/or rotated according to
|
||||
* the tensor at the input point. Scaling and rotation is controlled
|
||||
* by the eigenvalues/eigenvectors of the symmetrical part of the tensor
|
||||
* as follows:
|
||||
* For each tensor, the eigenvalues (and associated eigenvectors) are sorted
|
||||
* to determine the major, medium, and minor eigenvalues/eigenvectors.
|
||||
* The eigenvalue decomposition only makes sense for symmetric tensors,
|
||||
* hence the need to only consider the symmetric part of the tensor, which is
|
||||
* 1/2 (T + T.transposed()).
|
||||
*
|
||||
* If the boolean variable ThreeGlyphs is not set the major eigenvalue
|
||||
* scales the glyph in the x-direction, the medium in the y-direction,
|
||||
* and the minor in the z-direction. Then, the glyph is rotated so
|
||||
* that the glyph's local x-axis lies along the major eigenvector,
|
||||
* y-axis along the medium eigenvector, and z-axis along the minor.
|
||||
*
|
||||
* If the boolean variable ThreeGlyphs is set three glyphs are produced,
|
||||
* each of them oriented along an eigenvector and scaled according to the
|
||||
* corresponding eigenvector.
|
||||
*
|
||||
* If the boolean variable Symmetric is set each glyph is mirrored (2 or 6
|
||||
* glyphs will be produced)
|
||||
*
|
||||
* The x-axis of the source glyph will correspond to the eigenvector
|
||||
* on output. Point (0,0,0) in the source will be placed in the data point.
|
||||
* Variable Length will normally correspond to the distance from the
|
||||
* origin to the tip of the source glyph along the x-axis,
|
||||
* but can be changed to produce other results when Symmetric is on,
|
||||
* e.g. glyphs that do not touch or that overlap.
|
||||
*
|
||||
* Please note that when Symmetric is false it will generally be better
|
||||
* to place the source glyph from (-0.5,0,0) to (0.5,0,0), i.e. centred
|
||||
* at the origin. When symmetric is true the placement from (0,0,0) to
|
||||
* (1,0,0) will generally be more convenient.
|
||||
*
|
||||
* A scale factor is provided to control the amount of scaling. Also, you
|
||||
* can turn off scaling completely if desired. The boolean variable
|
||||
* ClampScaling controls the maximum scaling (in conjunction with
|
||||
* MaxScaleFactor.) This is useful in certain applications where
|
||||
* singularities or large order of magnitude differences exist in
|
||||
* the eigenvalues.
|
||||
*
|
||||
* If the boolean variable ColorGlyphs is set to true the glyphs are
|
||||
* colored. The glyphs can be colored using the input scalars
|
||||
* (SetColorModeToScalars), which is the default, or colored using the
|
||||
* eigenvalues (SetColorModeToEigenvalues).
|
||||
*
|
||||
* Another instance variable, ExtractEigenvalues, has been provided to
|
||||
* control extraction of eigenvalues/eigenvectors. If this boolean is
|
||||
* false, then eigenvalues/eigenvectors are not extracted, and the
|
||||
* columns of the tensor are taken as the eigenvectors (the norm of
|
||||
* column, always positive, is the eigenvalue). This allows
|
||||
* additional capability over the vtkGlyph3D object. That is, the
|
||||
* glyph can be oriented in three directions instead of one.
|
||||
*
|
||||
* @par Thanks:
|
||||
* Thanks to Jose Paulo Moitinho de Almeida for enhancements.
|
||||
*
|
||||
* @sa
|
||||
* vtkGlyph3D vtkPointLoad vtkHyperStreamline
|
||||
*/
|
||||
|
||||
#ifndef vtkTensorGlyphColor_h
|
||||
#define vtkTensorGlyphColor_h
|
||||
|
||||
#include "vtkFiltersCoreModule.h" // For export macro
|
||||
#include "vtkPolyDataAlgorithm.h"
|
||||
|
||||
class VTKFILTERSCORE_EXPORT vtkTensorGlyphColor : public vtkPolyDataAlgorithm
|
||||
{
|
||||
public:
|
||||
vtkTypeMacro(vtkTensorGlyphColor,vtkPolyDataAlgorithm)
|
||||
void PrintSelf(ostream& os, vtkIndent indent) override;
|
||||
|
||||
/**
|
||||
* Construct object with scaling on and scale factor 1.0. Eigenvalues are
|
||||
* extracted, glyphs are colored with input scalar data, and logarithmic
|
||||
* scaling is turned off.
|
||||
*/
|
||||
static vtkTensorGlyphColor *New();
|
||||
|
||||
//@{
|
||||
/**
|
||||
* Specify the geometry to copy to each point.
|
||||
* Note that this method does not connect the pipeline. The algorithm will
|
||||
* work on the input data as it is without updating the producer of the data.
|
||||
* See SetSourceConnection for connecting the pipeline.
|
||||
*/
|
||||
void SetSourceData(vtkPolyData *source);
|
||||
vtkPolyData *GetSource();
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/**
|
||||
* Specify a source object at a specified table location. New style.
|
||||
* Source connection is stored in port 1. This method is equivalent
|
||||
* to SetInputConnection(1, id, outputPort).
|
||||
*/
|
||||
void SetSourceConnection(int id, vtkAlgorithmOutput* algOutput);
|
||||
void SetSourceConnection(vtkAlgorithmOutput* algOutput)
|
||||
{
|
||||
this->SetSourceConnection(0, algOutput);
|
||||
}
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/**
|
||||
* Turn on/off scaling of glyph with eigenvalues.
|
||||
*/
|
||||
vtkSetMacro(Scaling,vtkTypeBool);
|
||||
vtkGetMacro(Scaling,vtkTypeBool);
|
||||
vtkBooleanMacro(Scaling,vtkTypeBool);
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/**
|
||||
* Specify scale factor to scale object by. (Scale factor always affects
|
||||
* output even if scaling is off.)
|
||||
*/
|
||||
vtkSetMacro(ScaleFactor,double);
|
||||
vtkGetMacro(ScaleFactor,double);
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/**
|
||||
* Turn on/off drawing three glyphs
|
||||
*/
|
||||
vtkSetMacro(ThreeGlyphs,vtkTypeBool);
|
||||
vtkGetMacro(ThreeGlyphs,vtkTypeBool);
|
||||
vtkBooleanMacro(ThreeGlyphs,vtkTypeBool);
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/**
|
||||
* Turn on/off drawing a mirror of each glyph
|
||||
*/
|
||||
vtkSetMacro(Symmetric,vtkTypeBool);
|
||||
vtkGetMacro(Symmetric,vtkTypeBool);
|
||||
vtkBooleanMacro(Symmetric,vtkTypeBool);
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/**
|
||||
* Set/Get the distance, along x, from the origin to the end of the
|
||||
* source glyph. It is used to draw the symmetric glyphs.
|
||||
*/
|
||||
vtkSetMacro(Length,double);
|
||||
vtkGetMacro(Length,double);
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/**
|
||||
* Turn on/off extraction of eigenvalues from tensor.
|
||||
*/
|
||||
vtkSetMacro(ExtractEigenvalues,vtkTypeBool);
|
||||
vtkBooleanMacro(ExtractEigenvalues,vtkTypeBool);
|
||||
vtkGetMacro(ExtractEigenvalues,vtkTypeBool);
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/**
|
||||
* Turn on/off coloring of glyph with input scalar data or
|
||||
* eigenvalues. If false, or input scalar data not present, then the
|
||||
* scalars from the source object are passed through the filter.
|
||||
*/
|
||||
vtkSetMacro(ColorGlyphs,vtkTypeBool);
|
||||
vtkGetMacro(ColorGlyphs,vtkTypeBool);
|
||||
vtkBooleanMacro(ColorGlyphs,vtkTypeBool);
|
||||
//@}
|
||||
|
||||
enum
|
||||
{
|
||||
COLOR_BY_SCALARS,
|
||||
COLOR_BY_EIGENVALUES
|
||||
};
|
||||
|
||||
//@{
|
||||
/**
|
||||
* Set the color mode to be used for the glyphs. This can be set to
|
||||
* use the input scalars (default) or to use the eigenvalues at the
|
||||
* point. If ThreeGlyphs is set and the eigenvalues are chosen for
|
||||
* coloring then each glyph is colored by the corresponding
|
||||
* eigenvalue and if not set the color corresponding to the largest
|
||||
* eigenvalue is chosen. The recognized values are:
|
||||
* COLOR_BY_SCALARS = 0 (default)
|
||||
* COLOR_BY_EIGENVALUES = 1
|
||||
*/
|
||||
vtkSetClampMacro(ColorMode, int, COLOR_BY_SCALARS, COLOR_BY_EIGENVALUES);
|
||||
vtkGetMacro(ColorMode, int);
|
||||
void SetColorModeToScalars()
|
||||
{this->SetColorMode(COLOR_BY_SCALARS);};
|
||||
void SetColorModeToEigenvalues()
|
||||
{this->SetColorMode(COLOR_BY_EIGENVALUES);};
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/**
|
||||
* Turn on/off scalar clamping. If scalar clamping is on, the ivar
|
||||
* MaxScaleFactor is used to control the maximum scale factor. (This is
|
||||
* useful to prevent uncontrolled scaling near singularities.)
|
||||
*/
|
||||
vtkSetMacro(ClampScaling,vtkTypeBool);
|
||||
vtkGetMacro(ClampScaling,vtkTypeBool);
|
||||
vtkBooleanMacro(ClampScaling,vtkTypeBool);
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/**
|
||||
* Set/Get the maximum allowable scale factor. This value is compared to the
|
||||
* combination of the scale factor times the eigenvalue. If less, the scale
|
||||
* factor is reset to the MaxScaleFactor. The boolean ClampScaling has to
|
||||
* be "on" for this to work.
|
||||
*/
|
||||
vtkSetMacro(MaxScaleFactor,double);
|
||||
vtkGetMacro(MaxScaleFactor,double);
|
||||
//@}
|
||||
|
||||
protected:
|
||||
vtkTensorGlyphColor();
|
||||
~vtkTensorGlyphColor() override;
|
||||
|
||||
int RequestUpdateExtent(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override;
|
||||
int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override;
|
||||
int FillInputPortInformation(int port, vtkInformation *info) override;
|
||||
|
||||
vtkTypeBool Scaling; // Determine whether scaling of geometry is performed
|
||||
double ScaleFactor; // Scale factor to use to scale geometry
|
||||
vtkTypeBool ExtractEigenvalues; // Boolean controls eigenfunction extraction
|
||||
vtkTypeBool ColorGlyphs; // Boolean controls coloring with input scalar data
|
||||
int ColorMode; // The coloring mode to use for the glyphs.
|
||||
vtkTypeBool ClampScaling; // Boolean controls whether scaling is clamped.
|
||||
double MaxScaleFactor; // Maximum scale factor (ScaleFactor*eigenvalue)
|
||||
vtkTypeBool ThreeGlyphs; // Boolean controls drawing 1 or 3 glyphs
|
||||
vtkTypeBool Symmetric; // Boolean controls drawing a "mirror" of each glyph
|
||||
double Length; // Distance, in x, from the origin to the end of the glyph
|
||||
private:
|
||||
vtkTensorGlyphColor(const vtkTensorGlyphColor&) = delete;
|
||||
void operator=(const vtkTensorGlyphColor&) = delete;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,73 @@
|
||||
#------------------------------------------------------------------------------
|
||||
# sources.cmake
|
||||
# Module : G4visVtk
|
||||
# Package: Geant4.src.G4visualization.G4visQt3D
|
||||
#
|
||||
# Sources description for a library.
|
||||
# Lists the sources and headers of the code explicitely.
|
||||
# Lists include paths needed.
|
||||
# Lists the internal granular and global dependencies of the library.
|
||||
# Source specific properties should be added at the end.
|
||||
#
|
||||
# Generated on : 24/9/2010
|
||||
#
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# Define the Geant4 Module.
|
||||
#
|
||||
|
||||
set(G4VIS_MODULE_VTK_HEADERS
|
||||
G4Vtk.hh
|
||||
G4VtkMessenger.hh
|
||||
G4VtkSceneHandler.hh
|
||||
G4VtkViewer.hh
|
||||
vtkTensorGlyphColor.h)
|
||||
|
||||
set(G4VIS_MODULE_VTK_SOURCES
|
||||
G4Vtk.cc
|
||||
G4VtkMessenger.cc
|
||||
G4VtkSceneHandler.cc
|
||||
G4VtkViewer.cc
|
||||
vtkTensorGlyphColor.cxx)
|
||||
|
||||
set(G4VIS_MODULE_VTK_DEFINITIONS
|
||||
-DG4VIS_USE_VTK)
|
||||
|
||||
if(GEANT4_USE_QT)
|
||||
list(APPEND G4VIS_MODULE_VTK_HEADERS
|
||||
G4VtkQt.hh
|
||||
G4VtkQtSceneHandler.hh
|
||||
G4VtkQtViewer.hh)
|
||||
|
||||
list(APPEND G4VIS_MODULE_VTK_SOURCES
|
||||
G4VtkQt.cc
|
||||
G4VtkQtSceneHandler.cc
|
||||
G4VtkQtViewer.cc)
|
||||
|
||||
list(APPEND G4VIS_MODULE_VTK_DEFINITIONS -DG4VIS_USE_VTK_QT)
|
||||
endif()
|
||||
|
||||
add_definitions(${G4VIS_MODULE_VTK_DEFINITIONS})
|
||||
|
||||
geant4_add_module(G4visVtk
|
||||
PUBLIC_HEADERS ${G4VIS_MODULE_VTK_HEADERS}
|
||||
SOURCES ${G4VIS_MODULE_VTK_SOURCES})
|
||||
|
||||
geant4_module_compile_definitions(G4visVtk PRIVATE ${G4VIS_MODULE_VTK_DEFINITIONS})
|
||||
geant4_module_compile_definitions(G4UIcommon PRIVATE ${G4VIS_MODULE_VTK_DEFINITIONS})
|
||||
|
||||
geant4_module_link_libraries(G4visVtk
|
||||
PUBLIC
|
||||
G4modeling
|
||||
G4globman
|
||||
G4hepgeometry
|
||||
G4vis_management
|
||||
${VTK_LIBRARIES}
|
||||
PRIVATE
|
||||
G4graphics_reps
|
||||
G4UIbasic
|
||||
G4UIcommon)
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// John Allison 5th April 2001
|
||||
// A template for a simplest possible graphics driver.
|
||||
//?? Lines or sections marked like this require specialisation for your driver.
|
||||
|
||||
#include "G4Vtk.hh"
|
||||
#include "G4VtkSceneHandler.hh"
|
||||
#include "G4VtkViewer.hh"
|
||||
#include "G4VtkMessenger.hh"
|
||||
|
||||
G4Vtk::G4Vtk(): G4VGraphicsSystem("VtkNative","VTKN","Vtk with native windowing",
|
||||
G4VGraphicsSystem::noFunctionality)
|
||||
{
|
||||
G4VtkMessenger::GetInstance();
|
||||
}
|
||||
|
||||
G4Vtk::~G4Vtk() {}
|
||||
|
||||
G4VSceneHandler* G4Vtk::CreateSceneHandler(const G4String& name) {
|
||||
G4VSceneHandler* pScene = new G4VtkSceneHandler(*this, name);
|
||||
return pScene;
|
||||
}
|
||||
|
||||
G4VViewer* G4Vtk::CreateViewer(G4VSceneHandler& scene,
|
||||
const G4String& name) {
|
||||
G4VViewer* pView = new G4VtkViewer((G4VtkSceneHandler&) scene, name);
|
||||
if (pView) {
|
||||
if (pView->GetViewId() < 0) {
|
||||
G4cerr << "G4Vtk::CreateViewer: ERROR flagged by negative"
|
||||
" view id in G4VtkViewer creation."
|
||||
"\n Destroying view and returning null pointer."
|
||||
<< G4endl;
|
||||
delete pView;
|
||||
pView = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
G4cerr << "G4Vtk::CreateViewer: ERROR: null pointer on new G4VtkViewer." << G4endl;
|
||||
}
|
||||
return pView;
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
|
||||
#include "G4VtkMessenger.hh"
|
||||
#include "G4VtkViewer.hh"
|
||||
|
||||
#include "G4UIdirectory.hh"
|
||||
#include "G4UIcmdWithABool.hh"
|
||||
#include "G4UIcmdWithAString.hh"
|
||||
#include "G4UIcmdWithoutParameter.hh"
|
||||
#include "G4UIcommand.hh"
|
||||
#include "G4Tokenizer.hh"
|
||||
|
||||
#include "G4VisManager.hh"
|
||||
|
||||
#include "vtkObject.h"
|
||||
|
||||
G4VtkMessenger* G4VtkMessenger::fpInstance = nullptr;
|
||||
|
||||
G4VtkMessenger* G4VtkMessenger::GetInstance()
|
||||
{
|
||||
if (!fpInstance) fpInstance = new G4VtkMessenger;
|
||||
return fpInstance;
|
||||
}
|
||||
|
||||
G4VtkMessenger::G4VtkMessenger() {
|
||||
G4bool omitable;
|
||||
|
||||
fpDirectory = new G4UIdirectory("/vis/vtk/");
|
||||
fpDirectory->SetGuidance("G4VtkViewer commands.");
|
||||
|
||||
// Export command
|
||||
fpCommandExport = new G4UIcommand("/vis/vtk/export", this);
|
||||
fpCommandExport->SetGuidance ("Export a screenshot or OBJ file of current Vtk viewer");
|
||||
|
||||
// File type for export
|
||||
auto parameterExport = new G4UIparameter ("name", 's', omitable = true);
|
||||
fpCommandExport->SetGuidance ("File type (jpg,tiff,eps,ps,obj,vrml)");
|
||||
fpCommandExport->SetParameter(parameterExport);
|
||||
|
||||
// File name for export
|
||||
parameterExport = new G4UIparameter ("name", 's', omitable = true);
|
||||
fpCommandExport->SetGuidance ("File name");
|
||||
fpCommandExport->SetParameter(parameterExport);
|
||||
|
||||
// Vtk warnings output
|
||||
fpCommandWarnings = new G4UIcmdWithABool("/vis/vtk/warnings", this);
|
||||
fpCommandExport->SetGuidance ("Enable (True) or disable (False) VTK warnings");
|
||||
}
|
||||
|
||||
G4VtkMessenger::~G4VtkMessenger()
|
||||
{
|
||||
delete fpDirectory;
|
||||
delete fpCommandExport;
|
||||
delete fpCommandWarnings;
|
||||
}
|
||||
G4String G4VtkMessenger::GetCurrentValue(G4UIcommand * /*command*/) {
|
||||
return G4String();
|
||||
}
|
||||
|
||||
void G4VtkMessenger::SetNewValue(G4UIcommand *command, G4String newValue)
|
||||
{
|
||||
|
||||
G4VisManager* pVisManager = G4VisManager::GetInstance();
|
||||
|
||||
G4VViewer* pViewer = pVisManager->GetCurrentViewer();
|
||||
if (!pViewer) {
|
||||
G4cout << "G4VtkMessenger::SetNewValue: No current viewer.\n"
|
||||
<< "\"/vis/open\", or similar, to get one."
|
||||
<< G4endl;
|
||||
return;
|
||||
}
|
||||
|
||||
auto* pVtkViewer = dynamic_cast<G4VtkViewer*>(pViewer);
|
||||
if (!pVtkViewer) {
|
||||
G4cout << "G4OpenGLViewerMessenger::SetNewValue: Current viewer is not of type VTK. \n"
|
||||
<< "(It is \""
|
||||
<< pViewer->GetName()
|
||||
<< "\".)\n"
|
||||
<< "Use \"/vis/viewer/select\" or \"/vis/open\"."
|
||||
<< G4endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (command == fpCommandExport)
|
||||
{
|
||||
G4String format, name;
|
||||
|
||||
std::istringstream iss(newValue);
|
||||
iss >> format >> name;
|
||||
|
||||
if(format == "jpg" || format == "tiff" ||
|
||||
format == "png" || format == "bmp" ||
|
||||
format == "pnm" || format == "ps")
|
||||
pVtkViewer->ExportScreenShot(name, format);
|
||||
else if(format == "obj")
|
||||
pVtkViewer->ExportOBJScene(name);
|
||||
else if(format == "vrml")
|
||||
pVtkViewer->ExportVRMLScene(name);
|
||||
else if(format == "vtp")
|
||||
pVtkViewer->ExportVTPScene(name);
|
||||
else
|
||||
G4cout << "Unknown /vis/vtk/export file format" << G4endl;
|
||||
}
|
||||
else if (command == fpCommandWarnings)
|
||||
{
|
||||
vtkObject::GlobalWarningDisplayOff();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
|
||||
#include "G4VtkQt.hh"
|
||||
#include "G4VtkQtSceneHandler.hh"
|
||||
#include "G4VtkQtViewer.hh"
|
||||
|
||||
#include "G4UIQt.hh"
|
||||
#include "G4UImanager.hh"
|
||||
#include "G4UIbatch.hh"
|
||||
|
||||
G4VtkQt::G4VtkQt(): G4VGraphicsSystem("VtkQt","VTKQt","VTK with Qt",
|
||||
G4VGraphicsSystem::noFunctionality)
|
||||
{}
|
||||
|
||||
G4VtkQt::~G4VtkQt() {}
|
||||
|
||||
G4VSceneHandler* G4VtkQt::CreateSceneHandler(const G4String& name) {
|
||||
G4VSceneHandler* pScene = new G4VtkQtSceneHandler(*this, name);
|
||||
return pScene;
|
||||
}
|
||||
|
||||
G4VViewer* G4VtkQt::CreateViewer(G4VSceneHandler& scene,
|
||||
const G4String& name) {
|
||||
G4VViewer* pView = new G4VtkQtViewer((G4VtkQtSceneHandler&) scene, name);
|
||||
if (pView) {
|
||||
if (pView->GetViewId() < 0) {
|
||||
G4cerr << "G4VtkQt::CreateViewer: ERROR flagged by negative"
|
||||
" view id in G4VtkViewer creation."
|
||||
"\n Destroying view and returning null pointer."
|
||||
<< G4endl;
|
||||
delete pView;
|
||||
pView = nullptr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
G4cerr << "G4Vtk::CreateViewer: ERROR: null pointer on new G4VtkViewer." << G4endl;
|
||||
}
|
||||
return pView;
|
||||
}
|
||||
|
||||
G4bool G4VtkQt::IsUISessionCompatible () const
|
||||
{
|
||||
G4bool isCompatible = false;
|
||||
G4UImanager* ui = G4UImanager::GetUIpointer();
|
||||
G4UIsession* session = ui->GetSession();
|
||||
|
||||
// If session is a batch session, it may be:
|
||||
// a) this is a batch job (the user has not instantiated any UI session);
|
||||
// b) we are currently processing a UI command, in which case the UI
|
||||
// manager creates a temporary batch session and to find out if there is
|
||||
// a genuine UI session that the user has instantiated we must drill
|
||||
// down through previous sessions to a possible non-batch session.
|
||||
while (G4UIbatch* batch = dynamic_cast<G4UIbatch*>(session)) {
|
||||
session = batch->GetPreviousSession();
|
||||
}
|
||||
|
||||
// Qt windows are only appropriate in a Qt session.
|
||||
if (session) {
|
||||
// If non-zero, this is the originating non-batch session
|
||||
// The user has instantiated a UI session...
|
||||
if (dynamic_cast<G4UIQt*>(session)) {
|
||||
// ...and it's a G4UIQt session, which is OK.
|
||||
isCompatible = true;
|
||||
}
|
||||
}
|
||||
return isCompatible;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
|
||||
#include "G4VtkQtSceneHandler.hh"
|
||||
|
||||
#include "G4PhysicalVolumeModel.hh"
|
||||
#include "G4LogicalVolumeModel.hh"
|
||||
#include "G4VPhysicalVolume.hh"
|
||||
#include "G4LogicalVolume.hh"
|
||||
#include "G4Polyline.hh"
|
||||
#include "G4Text.hh"
|
||||
#include "G4Circle.hh"
|
||||
#include "G4Square.hh"
|
||||
#include "G4Polyhedron.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4Box.hh"
|
||||
|
||||
G4int G4VtkQtSceneHandler::fSceneIdCount = 0;
|
||||
// Counter for XXX scene handlers.
|
||||
|
||||
G4VtkQtSceneHandler::G4VtkQtSceneHandler(G4VGraphicsSystem& system,
|
||||
const G4String& name) :
|
||||
G4VtkSceneHandler(system, name)
|
||||
{}
|
||||
|
||||
G4VtkQtSceneHandler::~G4VtkQtSceneHandler() {}
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
|
||||
#include "G4VSceneHandler.hh"
|
||||
|
||||
#include "G4VtkQtViewer.hh"
|
||||
#include "G4VtkQtSceneHandler.hh"
|
||||
|
||||
#include "G4UImanager.hh"
|
||||
#include "G4UIQt.hh"
|
||||
#include "G4Qt.hh"
|
||||
|
||||
#include <array>
|
||||
#include "vtkVersion.h"
|
||||
#include "vtkNew.h"
|
||||
#include "vtkNamedColors.h"
|
||||
#include "vtkCylinderSource.h"
|
||||
#include "vtkPolyDataMapper.h"
|
||||
#include "vtkProperty.h"
|
||||
#include "vtkCamera.h"
|
||||
#include "vtkActor.h"
|
||||
#include "vtkRenderer.h"
|
||||
#include "vtkGenericOpenGLRenderWindow.h"
|
||||
|
||||
G4VtkQtViewer::G4VtkQtViewer (G4VSceneHandler& sceneHandler, const G4String& name) :
|
||||
G4VtkViewer(sceneHandler, name) {
|
||||
}
|
||||
|
||||
G4VtkQtViewer::~G4VtkQtViewer() {}
|
||||
|
||||
void G4VtkQtViewer::Initialise()
|
||||
{
|
||||
CreateMainWindow(this, QString(GetName()));
|
||||
|
||||
// Specific GL render window and interactor for Qt
|
||||
_renderWindow = vtkGenericOpenGLRenderWindow::New();
|
||||
renderWindowInteractor = vtkRenderWindowInteractor::New();
|
||||
|
||||
_renderWindow->AddRenderer(renderer);
|
||||
#if VTK_MAJOR_VERSION == 8
|
||||
this->SetRenderWindow(_renderWindow);
|
||||
#else
|
||||
this->setRenderWindow(_renderWindow);
|
||||
#endif
|
||||
|
||||
// Set callback to match VTK parameters to Geant4
|
||||
geant4Callback->SetGeant4ViewParameters(&fVP);
|
||||
renderer->AddObserver(vtkCommand::EndEvent, geant4Callback);
|
||||
}
|
||||
|
||||
void G4VtkQtViewer::CreateMainWindow(QVTKOpenGLNativeWidget *vtkWidget,
|
||||
const QString& name) {
|
||||
// G4Qt* interactorManager = G4Qt::getInstance ();
|
||||
G4UImanager* UI = G4UImanager::GetUIpointer();
|
||||
fUiQt = static_cast<G4UIQt*> (UI->GetG4UIWindow());
|
||||
fUiQt->AddTabWidget((QWidget*)vtkWidget,name);
|
||||
}
|
||||
|
||||
void G4VtkQtViewer::FinishView()
|
||||
{
|
||||
G4VtkViewer::FinishView();
|
||||
// force a widget repaint as there should already
|
||||
// be a rendered buffer when visualiser starts up
|
||||
// paintGL();
|
||||
// repaint();
|
||||
}
|
||||
@@ -0,0 +1,876 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// John Allison 5th April 2001
|
||||
// A template for a simplest possible graphics driver.
|
||||
//?? Lines or sections marked like this require specialisation for your driver.
|
||||
|
||||
#include "G4VtkSceneHandler.hh"
|
||||
|
||||
#include "G4PhysicalVolumeModel.hh"
|
||||
#include "G4LogicalVolumeModel.hh"
|
||||
#include "G4VPhysicalVolume.hh"
|
||||
#include "G4LogicalVolume.hh"
|
||||
#include "G4Polyline.hh"
|
||||
#include "G4Text.hh"
|
||||
#include "G4Circle.hh"
|
||||
#include "G4Square.hh"
|
||||
#include "G4Polyhedron.hh"
|
||||
#include "G4Mesh.hh"
|
||||
#include "G4PseudoScene.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4Box.hh"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace std
|
||||
{
|
||||
inline void hash_combine(std::size_t) {}
|
||||
|
||||
template <typename T, typename... Rest>
|
||||
inline void hash_combine(std::size_t &seed, const T &v, Rest... rest) {
|
||||
std::hash<T> hasher;
|
||||
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
std::hash_combine(seed, rest...);
|
||||
}
|
||||
|
||||
template<> struct hash<G4VisAttributes> {
|
||||
std::size_t operator()(const G4VisAttributes &va) const {
|
||||
using std::size_t;
|
||||
using std::hash;
|
||||
|
||||
std::size_t h = 0;
|
||||
|
||||
std::hash_combine(h,va.IsVisible());
|
||||
std::hash_combine(h,va.IsDaughtersInvisible());
|
||||
std::hash_combine(h,va.GetColour().GetRed());
|
||||
std::hash_combine(h,va.GetColour().GetGreen());
|
||||
std::hash_combine(h,va.GetColour().GetBlue());
|
||||
std::hash_combine(h,va.GetColour().GetAlpha());
|
||||
std::hash_combine(h,static_cast<int>(va.GetLineStyle()));
|
||||
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct hash<G4Polyhedron> {
|
||||
std::size_t operator()(const G4Polyhedron &ph) const {
|
||||
using std::size_t;
|
||||
using std::hash;
|
||||
|
||||
G4bool notLastFace;
|
||||
G4Point3D vertex[4];
|
||||
G4int edgeFlag[4];
|
||||
G4Normal3D normals[4];
|
||||
G4int nEdges;
|
||||
|
||||
std::size_t h = 0;
|
||||
|
||||
do {
|
||||
notLastFace = ph.GetNextFacet(nEdges, vertex, edgeFlag, normals);
|
||||
|
||||
for (int i = 0; i < nEdges; i++) {
|
||||
std::size_t hx = std::hash<double>()(vertex[i].x());
|
||||
std::size_t hy = std::hash<double>()(vertex[i].y());
|
||||
std::size_t hz = std::hash<double>()(vertex[i].z());
|
||||
std::hash_combine(h,hx);
|
||||
std::hash_combine(h,hy);
|
||||
std::hash_combine(h,hz);
|
||||
}
|
||||
} while (notLastFace);
|
||||
|
||||
return h;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
G4int G4VtkSceneHandler::fSceneIdCount = 0;
|
||||
// Counter for XXX scene handlers.
|
||||
|
||||
G4VtkSceneHandler::G4VtkSceneHandler(G4VGraphicsSystem& system,
|
||||
const G4String& name) :
|
||||
G4VSceneHandler(system, fSceneIdCount++, name)
|
||||
{}
|
||||
|
||||
#ifdef G4VTKDEBUG
|
||||
void G4VtkSceneHandler::PrintThings() {
|
||||
G4cout << " with transformation " << fObjectTransformation.xx() << G4endl;
|
||||
if (fpModel) {
|
||||
G4cout << " from " << fpModel->GetCurrentDescription()
|
||||
<< " (tag " << fpModel->GetCurrentTag()
|
||||
<< ')';
|
||||
}
|
||||
else {
|
||||
G4cout << "(not from a model)";
|
||||
}
|
||||
G4PhysicalVolumeModel* pPVModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
|
||||
if (pPVModel) {
|
||||
G4cout << "\n current physical volume: " << pPVModel->GetCurrentPV()->GetName()
|
||||
<< "\n current logical volume : " << pPVModel->GetCurrentLV()->GetName() // There might be a problem with the LV pointer if this is a G4LogicalVolumeModel
|
||||
<< "\n current depth of geometry tree: " << pPVModel->GetCurrentDepth();
|
||||
}
|
||||
G4cout << G4endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
void G4VtkSceneHandler::AddPrimitive(const G4Polyline& polyline) {
|
||||
|
||||
G4VSceneHandler::MarkerSizeType sizeType;
|
||||
// GetMarkerSize(text,sizeType);
|
||||
if(fProcessing2D) {sizeType = screen;}
|
||||
else {sizeType = world;}
|
||||
|
||||
// Get vis attributes - pick up defaults if none.
|
||||
const G4VisAttributes* pVA = fpViewer -> GetApplicableVisAttributes(polyline.GetVisAttributes());
|
||||
G4Color colour = pVA->GetColour();
|
||||
G4double opacity = colour.GetAlpha();
|
||||
G4double lineWidth = pVA->GetLineWidth();
|
||||
|
||||
#ifdef G4VTKDEBUG
|
||||
G4cout << "=================================" << G4endl;
|
||||
G4cout << "G4VtkSceneHandler::AddPrimitive(const G4Polyline& polyline) called> vis hash: " << sizeType << " " << std::hash<G4VisAttributes>{}(*pVA) << G4endl;
|
||||
G4cout << "G4VtkSceneHandler::AddPrimitive(const G4Polyline& polyline) called> sizeType: " << sizeType << G4endl;
|
||||
G4cout << "G4VtkSceneHandler::AddPrimitive(const G4Polyline& polyline) called> isVisible: " << pVA->IsVisible() << G4endl;
|
||||
G4cout << "G4VtkSceneHandler::AddPrimitive(const G4Polyline& polyline) called> isDaughtersInvisible: " << pVA->IsDaughtersInvisible() << G4endl;
|
||||
G4cout << "G4VtkSceneHandler::AddPrimitive(const G4Polyline& polyline) called> colour: " << colour.GetRed() << " " << colour.GetGreen() << " " << colour.GetBlue() << G4endl;
|
||||
G4cout << "G4VtkSceneHandler::AddPrimitive(const G4Polyline& polyline) called> alpha: " << colour.GetAlpha() << G4endl;
|
||||
G4cout << "G4VtkSceneHandler::AddPrimitive(const G4Polyline& polyline) called> lineWidth: " << lineWidth << G4endl;
|
||||
#endif
|
||||
|
||||
if(sizeType == world) {
|
||||
std::size_t hash = std::hash<G4VisAttributes>{}(*pVA);
|
||||
if (polylineVisAttributesMap.find(hash) == polylineVisAttributesMap.end()) {
|
||||
polylineVisAttributesMap.insert(std::pair<std::size_t, const G4VisAttributes *>(hash, pVA));
|
||||
|
||||
vtkSmartPointer <vtkPoints> data = vtkSmartPointer<vtkPoints>::New();
|
||||
vtkSmartPointer <vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
|
||||
vtkSmartPointer <vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
|
||||
vtkSmartPointer <vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||
vtkSmartPointer <vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||
|
||||
polyData->SetPoints(data);
|
||||
polyData->SetLines(lines);
|
||||
mapper->SetInputData(polyData);
|
||||
actor->SetMapper(mapper);
|
||||
|
||||
// Setup actor and mapper
|
||||
actor->GetProperty()->SetLineWidth(lineWidth);
|
||||
actor->GetProperty()->SetColor(colour.GetRed(), colour.GetGreen(),
|
||||
colour.GetBlue());
|
||||
actor->GetProperty()->SetOpacity(opacity);
|
||||
actor->SetVisibility(1);
|
||||
// actor->GetProperty()->BackfaceCullingOn();
|
||||
// actor->GetProperty()->FrontfaceCullingOn();
|
||||
|
||||
auto pVtkViewer = dynamic_cast<G4VtkViewer*>(fpViewer);
|
||||
pVtkViewer->renderer->AddActor(actor);
|
||||
|
||||
polylineDataMap.insert(
|
||||
std::pair<std::size_t, vtkSmartPointer<vtkPoints>>(hash, data));
|
||||
polylineLineMap.insert(
|
||||
std::pair<std::size_t, vtkSmartPointer<vtkCellArray>>(hash, lines));
|
||||
polylinePolyDataMap.insert(
|
||||
std::pair<std::size_t, vtkSmartPointer<vtkPolyData>>(hash, polyData));
|
||||
polylinePolyDataMapperMap.insert(
|
||||
std::pair<std::size_t, vtkSmartPointer<vtkPolyDataMapper>>(hash,
|
||||
mapper));
|
||||
polylinePolyDataActorMap.insert(
|
||||
std::pair<std::size_t, vtkSmartPointer<vtkActor>>(hash, actor));
|
||||
}
|
||||
|
||||
// Data data
|
||||
const size_t nLines = polyline.size();
|
||||
|
||||
for (size_t i = 0; i < nLines; ++i) {
|
||||
auto id = polylineDataMap[hash]->InsertNextPoint(polyline[i].x(),
|
||||
polyline[i].y(),
|
||||
polyline[i].z());
|
||||
if (i < nLines - 1) {
|
||||
vtkSmartPointer <vtkLine> line = vtkSmartPointer<vtkLine>::New();
|
||||
line->GetPointIds()->SetId(0, id);
|
||||
line->GetPointIds()->SetId(1, id + 1);
|
||||
polylineLineMap[hash]->InsertNextCell(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sizeType == screen ) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void G4VtkSceneHandler::AddPrimitive(const G4Text& text) {
|
||||
|
||||
G4VSceneHandler::MarkerSizeType sizeType;
|
||||
if(fProcessing2D) {sizeType = screen;}
|
||||
else {sizeType = world;}
|
||||
|
||||
const G4VisAttributes* pVA = fpViewer -> GetApplicableVisAttributes(text.GetVisAttributes());
|
||||
G4Color colour = pVA->GetColour();
|
||||
G4double opacity = colour.GetAlpha();
|
||||
// G4Text::Layout layout = text.GetLayout();
|
||||
// G4double xOffset = text.GetXOffset();
|
||||
// G4double yOffset = text.GetYOffset();
|
||||
|
||||
double x = text.GetPosition().x();
|
||||
double y = text.GetPosition().y();
|
||||
double z = text.GetPosition().z();
|
||||
|
||||
#ifdef G4VTKDEBUG
|
||||
G4cout << "=================================" << G4endl;
|
||||
G4cout << "G4VtkSeneHandler::AddPrimitive(const G4Text& text) called> text: " << text.GetText() << " sizeType:" << sizeType << " " << fProcessing2D << G4endl;
|
||||
G4cout << "G4VtkSeneHandler::AddPrimitive(const G4Text& text) called> colour: " << colour.GetRed() << " " << colour.GetBlue() << " " << colour.GetGreen() << G4endl;
|
||||
G4cout << "G4VtkSeneHandler::AddPrimitive(const G4Text& text) called> alpha: " << colour.GetAlpha() << G4endl;
|
||||
G4cout << "G4VtkSeneHandler::AddPrimitive(const G4Text& text) called> position: " << x << " " << y << " " << z << G4endl;
|
||||
#endif
|
||||
|
||||
switch (sizeType) {
|
||||
default:
|
||||
case (screen): {
|
||||
vtkSmartPointer <vtkTextActor> actor = vtkSmartPointer<vtkTextActor>::New();
|
||||
actor->SetInput(text.GetText().c_str());
|
||||
actor->GetPositionCoordinate()->SetCoordinateSystemToNormalizedViewport();
|
||||
// actor->SetTextScaleModeToViewport();
|
||||
actor->SetPosition((x+1.)/2.0, (y+1.)/2.);
|
||||
actor->GetTextProperty()->SetFontSize(text.GetScreenSize());
|
||||
actor->GetTextProperty()->SetColor(colour.GetRed(), colour.GetBlue(), colour.GetGreen());
|
||||
actor->GetTextProperty()->SetOpacity(opacity);
|
||||
|
||||
auto *pVtkViewer = dynamic_cast<G4VtkViewer *>(fpViewer);
|
||||
pVtkViewer->renderer->AddActor(actor);
|
||||
break;
|
||||
}
|
||||
case world: {
|
||||
vtkSmartPointer <vtkBillboardTextActor3D> actor = vtkSmartPointer<vtkBillboardTextActor3D>::New();
|
||||
actor->SetInput(text.GetText().c_str());
|
||||
actor->SetPosition(x, y, z);
|
||||
actor->GetTextProperty()->SetFontSize(text.GetScreenSize());
|
||||
actor->GetTextProperty()->SetColor(colour.GetRed(), colour.GetBlue(), colour.GetGreen());
|
||||
actor->GetTextProperty()->SetOpacity(opacity);
|
||||
|
||||
auto *pVtkViewer = dynamic_cast<G4VtkViewer*>(fpViewer);
|
||||
pVtkViewer->renderer->AddActor(actor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void G4VtkSceneHandler::AddPrimitive(const G4Circle& circle) {
|
||||
|
||||
MarkerSizeType sizeType;
|
||||
G4double size= GetMarkerSize(circle, sizeType);
|
||||
if(fProcessing2D) {sizeType = screen;}
|
||||
else {sizeType = world;}
|
||||
|
||||
// Get vis attributes - pick up defaults if none.
|
||||
const G4VisAttributes *pVA = fpViewer->GetApplicableVisAttributes(circle.GetVisAttributes());
|
||||
G4Color colour = pVA->GetColour();
|
||||
G4double opacity = colour.GetAlpha();
|
||||
// G4bool isVisible = pVA->IsVisible();
|
||||
|
||||
#ifdef G4VTKDEBUG
|
||||
G4cout << "=================================" << G4endl;
|
||||
G4cout << "G4VtkSceneHandler::AddPrimitive(const G4Circle& circle) called> " << " radius:" << size << " sizeType:" << sizeType << G4endl;
|
||||
G4cout << "G4VtkSceneHandler::AddPrimitive(const G4Circle& circle) called> colour: " << colour.GetRed() << " " << colour.GetBlue() << " " << colour.GetGreen() << G4endl;
|
||||
G4cout << "G4VtkSceneHandler::AddPrimitive(const G4Circle& circle) called> alpha: " << colour.GetAlpha() << G4endl;
|
||||
#endif
|
||||
|
||||
if (sizeType == world) {
|
||||
std::size_t hash = std::hash<G4VisAttributes>{}(*pVA);
|
||||
if (circleVisAttributesMap.find(hash) == circleVisAttributesMap.end()) {
|
||||
circleVisAttributesMap.insert(std::pair<std::size_t, const G4VisAttributes *>(hash, pVA));
|
||||
|
||||
vtkSmartPointer<vtkPoints> data = vtkSmartPointer<vtkPoints>::New();
|
||||
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
|
||||
vtkSmartPointer<vtkVertexGlyphFilter> filter = vtkSmartPointer<vtkVertexGlyphFilter>::New();
|
||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||
|
||||
polyData->SetPoints(data);
|
||||
filter->SetInputData(polyData);
|
||||
mapper->SetInputConnection(filter->GetOutputPort());
|
||||
actor->SetMapper(mapper);
|
||||
|
||||
// Setup actor and mapper
|
||||
actor->GetProperty()->SetColor(colour.GetRed(), colour.GetGreen(), colour.GetBlue());
|
||||
actor->GetProperty()->SetOpacity(opacity);
|
||||
actor->SetVisibility(1);
|
||||
actor->GetProperty()->SetRenderPointsAsSpheres(true);
|
||||
actor->GetProperty()->SetPointSize(size*5);
|
||||
|
||||
auto *pVtkViewer = dynamic_cast<G4VtkViewer *>(fpViewer);
|
||||
pVtkViewer->renderer->AddActor(actor);
|
||||
|
||||
circleDataMap.insert(std::pair<std::size_t,vtkSmartPointer<vtkPoints>>(hash, data));
|
||||
circlePolyDataMap.insert(std::pair<std::size_t, vtkSmartPointer < vtkPolyData>>(hash, polyData));
|
||||
circleFilterMap.insert(std::pair<std::size_t, vtkSmartPointer<vtkVertexGlyphFilter>>(hash, filter));
|
||||
circlePolyDataMapperMap.insert(std::pair<std::size_t, vtkSmartPointer < vtkPolyDataMapper>>(hash, mapper));
|
||||
circlePolyDataActorMap.insert(std::pair<std::size_t, vtkSmartPointer < vtkActor>>(hash, actor));
|
||||
}
|
||||
|
||||
// Data data point
|
||||
const CLHEP::HepRotation rot = fObjectTransformation.getRotation();
|
||||
G4Point3D posPrime = rot*circle.GetPosition();
|
||||
circleDataMap[hash]->InsertNextPoint(fObjectTransformation.dx() + posPrime.x(),
|
||||
fObjectTransformation.dy() + posPrime.y(),
|
||||
fObjectTransformation.dz() + posPrime.z());
|
||||
}
|
||||
else if (sizeType == screen) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void G4VtkSceneHandler::AddPrimitive(const G4Square& square) {
|
||||
|
||||
MarkerSizeType sizeType;
|
||||
G4double size = GetMarkerSize (square, sizeType);
|
||||
|
||||
// Get vis attributes - pick up defaults if none.
|
||||
const G4VisAttributes* pVA = fpViewer -> GetApplicableVisAttributes(square.GetVisAttributes());
|
||||
G4Color colour = pVA->GetColour();
|
||||
G4double opacity = colour.GetAlpha();
|
||||
// G4bool isVisible = pVA->IsVisible();
|
||||
|
||||
// Draw in world coordinates.
|
||||
vtkSmartPointer<vtkRegularPolygonSource> polygonSource = vtkSmartPointer<vtkRegularPolygonSource>::New();
|
||||
polygonSource->SetNumberOfSides(4);
|
||||
polygonSource->SetRadius(size);
|
||||
|
||||
|
||||
#ifdef G4VTKDEBUG
|
||||
G4cout << "=================================" << G4endl;
|
||||
G4cout << "G4VtkSceneHandler::AddPrimitive(const G4Square& square) called" << G4endl;
|
||||
G4cout << square.GetPosition().x() << " " << square.GetPosition().y() << " " << square.GetPosition().z() << G4endl;
|
||||
//PrintThings();
|
||||
#endif
|
||||
|
||||
if (sizeType == world) {
|
||||
std::size_t hash = std::hash<G4VisAttributes>{}(*pVA);
|
||||
if (squareVisAttributesMap.find(hash) == squareVisAttributesMap.end()) {
|
||||
squareVisAttributesMap.insert(std::pair<std::size_t, const G4VisAttributes *>(hash, pVA));
|
||||
|
||||
vtkSmartPointer<vtkPoints> data = vtkSmartPointer<vtkPoints>::New();
|
||||
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
|
||||
vtkSmartPointer<vtkVertexGlyphFilter> filter = vtkSmartPointer<vtkVertexGlyphFilter>::New();
|
||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||
|
||||
polyData->SetPoints(data);
|
||||
filter->SetInputData(polyData);
|
||||
mapper->SetInputConnection(filter->GetOutputPort());
|
||||
actor->SetMapper(mapper);
|
||||
|
||||
// Setup actor and mapper
|
||||
actor->GetProperty()->SetColor(colour.GetRed(), colour.GetGreen(), colour.GetBlue());
|
||||
actor->GetProperty()->SetOpacity(opacity);
|
||||
actor->SetVisibility(1);
|
||||
actor->GetProperty()->SetPointSize(size*5);
|
||||
|
||||
auto *pVtkViewer = dynamic_cast<G4VtkViewer *>(fpViewer);
|
||||
pVtkViewer->renderer->AddActor(actor);
|
||||
|
||||
squareDataMap.insert(std::pair<std::size_t,vtkSmartPointer<vtkPoints>>(hash, data));
|
||||
squarePolyDataMap.insert(std::pair<std::size_t, vtkSmartPointer < vtkPolyData>>(hash, polyData));
|
||||
squareFilterMap.insert(std::pair<std::size_t, vtkSmartPointer<vtkVertexGlyphFilter>>(hash, filter));
|
||||
squarePolyDataMapperMap.insert(std::pair<std::size_t, vtkSmartPointer < vtkPolyDataMapper>>(hash, mapper));
|
||||
squarePolyDataActorMap.insert(std::pair<std::size_t, vtkSmartPointer < vtkActor>>(hash, actor));
|
||||
}
|
||||
|
||||
// Data data point
|
||||
const CLHEP::HepRotation rot = fObjectTransformation.getRotation();
|
||||
G4Point3D posPrime = rot*square.GetPosition();
|
||||
squareDataMap[hash]->InsertNextPoint(fObjectTransformation.dx() + posPrime.x(),
|
||||
fObjectTransformation.dy() + posPrime.y(),
|
||||
fObjectTransformation.dz() + posPrime.z());
|
||||
}
|
||||
else if (sizeType == screen) {
|
||||
|
||||
}
|
||||
}
|
||||
void G4VtkSceneHandler::AddPrimitive(const G4Polyhedron& polyhedron) {
|
||||
AddPrimitiveTensorGlyph(polyhedron);
|
||||
}
|
||||
|
||||
void G4VtkSceneHandler::AddPrimitiveTensorGlyph(const G4Polyhedron& polyhedron) {
|
||||
// only have a single polydata object for each LV but bake in the PV
|
||||
// transformation so clippers and cutters can be implemented
|
||||
|
||||
//Get colour, etc..
|
||||
if (polyhedron.GetNoFacets() == 0) {return;}
|
||||
|
||||
// Get vis attributes - pick up defaults if none.
|
||||
const G4VisAttributes *pVA = fpViewer->GetApplicableVisAttributes(polyhedron.GetVisAttributes());
|
||||
G4Color colour = pVA->GetColour();
|
||||
// G4bool isVisible = pVA->IsVisible();
|
||||
// G4double lineWidth = pVA->GetLineWidth();
|
||||
// G4VisAttributes::LineStyle lineStyle = pVA->GetLineStyle();
|
||||
|
||||
// G4double lineWidthScale = drawing_style.GetGlobalLineWidthScale();
|
||||
|
||||
// Get view parameters that the user can force through the vis attributes, thereby over-riding the current view parameter.
|
||||
G4ViewParameters::DrawingStyle drawing_style = GetDrawingStyle(pVA);
|
||||
//G4bool isAuxEdgeVisible = GetAuxEdgeVisible (pVA);
|
||||
|
||||
#ifdef G4VTKDEBUG
|
||||
G4cout << "=================================" << G4endl;
|
||||
G4cout << "G4VtkSceneHandler::AddPrimitive(const G4Polyhedron& polyhedron) called> " << G4endl;
|
||||
G4cout << "G4VtkSceneHandler::AddPrimitive(const G4Polyhedron& polyhedron) called> colour:" << colour.GetRed() << " " << colour.GetBlue() << " " << colour.GetGreen() << G4endl;
|
||||
G4cout << "G4VtkSceneHandler::AddPrimitive(const G4Polyhedron& polyhedron) called> alpha:" << colour.GetAlpha() << G4endl;
|
||||
G4cout << "G4VtkSceneHandler::AddPrimitive(const G4Polyhedron& polyhedron) called> lineWidth:" << lineWidth << G4endl;
|
||||
G4cout << "G4VtkSceneHandler::AddPrimitive(const G4Polyhedron& polyhedron) called> lineStyle:" << lineStyle << G4endl;
|
||||
#endif
|
||||
|
||||
//std::size_t vhash = std::hash<G4VisAttributes>{}(*pVA);
|
||||
|
||||
std::size_t vhash = 0;
|
||||
std::hash_combine(vhash,static_cast<int>(drawing_style));
|
||||
|
||||
std::size_t phash = std::hash<G4Polyhedron>{}(polyhedron);
|
||||
|
||||
std::size_t hash = 0;
|
||||
std::hash_combine(hash, phash);
|
||||
std::hash_combine(hash, vhash);
|
||||
|
||||
if (polyhedronPolyDataMap.find(hash) == polyhedronPolyDataMap.end()) {
|
||||
|
||||
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
|
||||
vtkSmartPointer<vtkCellArray> polys = vtkSmartPointer<vtkCellArray>::New();
|
||||
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
|
||||
|
||||
G4bool notLastFace;
|
||||
int iVert = 0;
|
||||
do {
|
||||
G4Point3D vertex[4];
|
||||
G4int edgeFlag[4];
|
||||
G4Normal3D normals[4];
|
||||
G4int nEdges;
|
||||
notLastFace = polyhedron.GetNextFacet(nEdges, vertex, edgeFlag, normals);
|
||||
|
||||
vtkSmartPointer<vtkIdList> poly = vtkSmartPointer<vtkIdList>::New();
|
||||
// loop over vertices
|
||||
for (int i = 0; i < nEdges; i++) {
|
||||
points->InsertNextPoint(vertex[i].x(), vertex[i].y(), vertex[i].z());
|
||||
poly->InsertNextId(iVert);
|
||||
iVert++;
|
||||
}
|
||||
polys->InsertNextCell(poly);
|
||||
|
||||
} while (notLastFace);
|
||||
|
||||
polydata->SetPoints(points);
|
||||
polydata->SetPolys(polys);
|
||||
|
||||
polyhedronDataMap.insert(std::pair<std::size_t, vtkSmartPointer<vtkPoints>>(hash, points));
|
||||
polyhedronPolyMap.insert(std::pair<std::size_t, vtkSmartPointer<vtkCellArray>>(hash, polys));
|
||||
polyhedronPolyDataMap.insert(std::pair<std::size_t, vtkSmartPointer<vtkPolyData>>(hash, polydata));
|
||||
polyhedronPolyDataCountMap.insert(std::pair<std::size_t, std::size_t>(hash, 0));
|
||||
|
||||
vtkSmartPointer<vtkPoints> instancePosition = vtkSmartPointer<vtkPoints>::New();
|
||||
vtkSmartPointer<vtkDoubleArray> instanceRotation = vtkSmartPointer<vtkDoubleArray>::New();
|
||||
vtkSmartPointer<vtkDoubleArray> instanceColors = vtkSmartPointer<vtkDoubleArray>::New();
|
||||
vtkSmartPointer<vtkPolyDataMapper> instanceMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||
vtkSmartPointer<vtkActor> instanceActor = vtkSmartPointer<vtkActor>::New();
|
||||
instanceColors->SetName("colors");
|
||||
|
||||
instanceColors->SetNumberOfComponents(4);
|
||||
instanceRotation->SetNumberOfComponents(9);
|
||||
|
||||
vtkSmartPointer<vtkPolyData> instancePolyData = vtkSmartPointer<vtkPolyData>::New();
|
||||
instancePolyData->SetPoints(instancePosition);
|
||||
instancePolyData->GetPointData()->SetTensors(instanceRotation);
|
||||
instancePolyData->GetPointData()->SetVectors(instanceColors);
|
||||
instancePolyData->GetPointData()->SetScalars(instanceColors);
|
||||
|
||||
vtkSmartPointer<vtkCleanPolyData> filterClean = vtkSmartPointer<vtkCleanPolyData>::New();
|
||||
filterClean->PointMergingOn();
|
||||
filterClean->AddInputData(polydata);
|
||||
|
||||
vtkSmartPointer<vtkTriangleFilter> filterTriangle = vtkSmartPointer<vtkTriangleFilter>::New();
|
||||
filterTriangle->SetInputConnection(filterClean->GetOutputPort());
|
||||
|
||||
vtkSmartPointer<vtkPolyDataNormals> filterNormals = vtkSmartPointer<vtkPolyDataNormals>::New();
|
||||
filterNormals->SetFeatureAngle(45);
|
||||
filterNormals->SetInputConnection(filterTriangle->GetOutputPort());
|
||||
|
||||
vtkSmartPointer<vtkFeatureEdges> filterEdge = vtkSmartPointer<vtkFeatureEdges>::New();
|
||||
filterEdge->SetFeatureEdges(1);
|
||||
filterEdge->SetManifoldEdges(0);
|
||||
filterEdge->SetBoundaryEdges(0);
|
||||
filterEdge->SetFeatureAngle(45); // TODO need to have a function and command to set this
|
||||
filterEdge->SetInputConnection(filterTriangle->GetOutputPort());
|
||||
|
||||
vtkSmartPointer<vtkTensorGlyphColor> tensorGlyph = vtkSmartPointer<vtkTensorGlyphColor>::New();
|
||||
tensorGlyph->SetInputData(instancePolyData);
|
||||
tensorGlyph->SetSourceConnection(filterNormals->GetOutputPort());
|
||||
tensorGlyph->ColorGlyphsOn();
|
||||
tensorGlyph->ScalingOff();
|
||||
tensorGlyph->ThreeGlyphsOff();
|
||||
tensorGlyph->ExtractEigenvaluesOff();
|
||||
tensorGlyph->SetColorModeToScalars();
|
||||
tensorGlyph->Update();
|
||||
|
||||
instanceMapper->SetInputData(tensorGlyph->GetOutput());
|
||||
instanceMapper->SetColorModeToDirectScalars();
|
||||
|
||||
instanceActor->SetMapper(instanceMapper);
|
||||
// instanceActor->GetProperty()->SetLineWidth(10);
|
||||
instanceActor->SetVisibility(1);
|
||||
|
||||
if(drawing_style == G4ViewParameters::hsr) {
|
||||
|
||||
}
|
||||
|
||||
if(drawing_style == G4ViewParameters::hlr) {
|
||||
}
|
||||
|
||||
if(drawing_style == G4ViewParameters::wireframe) {
|
||||
instanceActor->GetProperty()->SetRepresentationToWireframe();
|
||||
}
|
||||
|
||||
auto *pVtkViewer = dynamic_cast<G4VtkViewer *>(fpViewer);
|
||||
pVtkViewer->renderer->AddActor(instanceActor);
|
||||
|
||||
instancePositionMap.insert(std::pair<std::size_t, vtkSmartPointer<vtkPoints>>(hash, instancePosition));
|
||||
instanceRotationMap.insert(std::pair<std::size_t, vtkSmartPointer<vtkDoubleArray>>(hash, instanceRotation));
|
||||
instanceColoursMap.insert(std::pair<std::size_t, vtkSmartPointer<vtkDoubleArray>>(hash, instanceColors));
|
||||
instancePolyDataMap.insert(std::pair<std::size_t, vtkSmartPointer<vtkPolyData>>(hash,instancePolyData));
|
||||
instanceActorMap.insert(std::pair<std::size_t, vtkSmartPointer<vtkActor>>(hash, instanceActor));
|
||||
instanceTensorGlyphMap.insert(std::pair<std::size_t, vtkSmartPointer<vtkTensorGlyphColor>>(hash, tensorGlyph));
|
||||
}
|
||||
|
||||
polyhedronPolyDataCountMap[hash]++;
|
||||
|
||||
double red = colour.GetRed();
|
||||
double green = colour.GetGreen();
|
||||
double blue = colour.GetBlue();
|
||||
double alpha = colour.GetAlpha();
|
||||
|
||||
instanceColoursMap[hash]->InsertNextTuple4(red, green, blue, alpha);
|
||||
|
||||
instancePositionMap[hash]->InsertNextPoint(fObjectTransformation.dx(),
|
||||
fObjectTransformation.dy(),
|
||||
fObjectTransformation.dz());
|
||||
|
||||
G4Transform3D fInvObjTrans = fObjectTransformation.inverse();
|
||||
|
||||
instanceRotationMap[hash]->InsertNextTuple9(fInvObjTrans.xx(), fInvObjTrans.xy(),fInvObjTrans.xz(),
|
||||
fInvObjTrans.yx(), fInvObjTrans.yy(),fInvObjTrans.yz(),
|
||||
fInvObjTrans.zx(), fInvObjTrans.zy(),fInvObjTrans.zz());
|
||||
|
||||
}
|
||||
|
||||
void G4VtkSceneHandler::AddPrimitiveBakedTransform(const G4Polyhedron& polyhedron)
|
||||
{
|
||||
// only have a single polydata object for each LV but bake in the PV
|
||||
// transformation so clippers and cutters can be implemented
|
||||
AddPrimitiveTensorGlyph(polyhedron);
|
||||
}
|
||||
void G4VtkSceneHandler::Modified() {
|
||||
for (auto it = polylineDataMap.begin(); it != polylineDataMap.end(); it++)
|
||||
{
|
||||
it->second->Modified();
|
||||
}
|
||||
|
||||
for (auto it = polylineLineMap.begin(); it != polylineLineMap.end(); it++)
|
||||
{
|
||||
it->second->Modified();
|
||||
}
|
||||
for (auto it = circleDataMap.begin(); it != circleDataMap.end(); it++)
|
||||
{
|
||||
it->second->Modified();
|
||||
}
|
||||
|
||||
for (auto it = squareDataMap.begin(); it != squareDataMap.end(); it++)
|
||||
{
|
||||
it->second->Modified();
|
||||
}
|
||||
|
||||
for(auto it = instancePositionMap.begin(); it != instancePositionMap.end(); it++)
|
||||
{
|
||||
it->second->Modified();
|
||||
}
|
||||
|
||||
for(auto it = instanceRotationMap.begin(); it != instanceRotationMap.end(); it++)
|
||||
{
|
||||
it->second->Modified();
|
||||
}
|
||||
|
||||
for(auto it = instanceColoursMap.begin(); it != instanceColoursMap.end(); it++)
|
||||
{
|
||||
it->second->Modified();
|
||||
}
|
||||
|
||||
for(auto it = instancePolyDataMap.begin(); it != instancePolyDataMap.end(); it++)
|
||||
{
|
||||
it->second->Modified();
|
||||
}
|
||||
|
||||
for(auto it = instanceActorMap.begin(); it != instanceActorMap.end(); it++)
|
||||
{
|
||||
it->second->Modified();
|
||||
}
|
||||
|
||||
for(auto it = instanceTensorGlyphMap.begin(); it != instanceTensorGlyphMap.end(); it++)
|
||||
{
|
||||
it->second->Update();
|
||||
}
|
||||
|
||||
#ifdef G4VTKDEBUG
|
||||
G4cout << "G4VtkSceneHandler::Modified() polyline styles: " << polylineVisAttributesMap.size() << G4endl;
|
||||
for (auto it = polylineLineMap.begin(); it != polylineLineMap.end(); it++)
|
||||
{
|
||||
G4cout << "G4VtkSceneHandler::Modified() polyline segments: "
|
||||
<< it->second->GetNumberOfCells() << G4endl;
|
||||
}
|
||||
G4cout << "G4VtkSceneHandler::Modified() circle styles: " << circleVisAttributesMap.size() << G4endl;
|
||||
for (auto it = circleDataMap.begin(); it != circleDataMap.end(); it++)
|
||||
{
|
||||
G4cout << "G4VtkSceneHandler::Modified() circles: "
|
||||
<< it->second->GetNumberOfPoints() << G4endl;
|
||||
}
|
||||
|
||||
G4cout << "G4VtkSceneHandler::Modified() square styles: " << squareVisAttributesMap.size() << G4endl;
|
||||
for (auto it = squareDataMap.begin(); it != squareDataMap.end(); it++)
|
||||
{
|
||||
G4cout << "G4VtkSceneHanler::Modified() squares: "
|
||||
<< it->second->GetNumberOfPoints() << G4endl;
|
||||
}
|
||||
|
||||
G4cout << "G4VtkSceneHandler::Modified() unique polyhedra: " << polyhedronDataMap.size() << G4endl;
|
||||
|
||||
int nPlacements = 0;
|
||||
int nCells = 0;
|
||||
for (auto it = polyhedronPolyDataMap.begin(); it != polyhedronPolyDataMap.end(); it++) {
|
||||
G4cout << "G4VtkSceneHandler::Modified() polyhedronPolyData: " << it->second->GetPoints()->GetNumberOfPoints() << " " << it->second->GetPolys()->GetNumberOfCells() << " " << polyhedronPolyDataCountMap[it->first] <<G4endl;
|
||||
nCells += it->second->GetPolys()->GetNumberOfCells()*polyhedronPolyDataCountMap[it->first];
|
||||
nPlacements += polyhedronPolyDataCountMap[it->first];
|
||||
}
|
||||
G4cout << "G4VtkSceneHandler::Modified() polyhedronPolyData: " << nPlacements << " " << nCells << G4endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
void G4VtkSceneHandler::Clear() {
|
||||
|
||||
polylineVisAttributesMap.clear();
|
||||
polylineDataMap.clear();
|
||||
polylineLineMap.clear();
|
||||
polylinePolyDataMap.clear();
|
||||
polylinePolyDataMapperMap.clear();
|
||||
polylinePolyDataActorMap.clear();
|
||||
|
||||
for (auto& v : polylineDataMap)
|
||||
{v.second->Reset();}
|
||||
for (auto& v : polylineLineMap)
|
||||
{v.second->Reset();}
|
||||
|
||||
circleVisAttributesMap.clear();
|
||||
circleDataMap.clear();
|
||||
circlePolyDataMap.clear();
|
||||
circleFilterMap.clear();
|
||||
circlePolyDataMapperMap.clear();
|
||||
circlePolyDataActorMap.clear();
|
||||
|
||||
squareVisAttributesMap.clear();
|
||||
squareDataMap.clear();
|
||||
squarePolyDataMap.clear();
|
||||
squareFilterMap.clear();
|
||||
squarePolyDataMapperMap.clear();
|
||||
squarePolyDataActorMap.clear();
|
||||
|
||||
for (auto& v : squareDataMap)
|
||||
{v.second->Reset();}
|
||||
|
||||
polyhedronVisAttributesMap.clear();
|
||||
polyhedronDataMap.clear();
|
||||
polyhedronPolyMap.clear();
|
||||
polyhedronPolyDataMap.clear();
|
||||
polyhedronPolyDataCountMap.clear();
|
||||
|
||||
instancePositionMap.clear();
|
||||
instanceRotationMap.clear();
|
||||
instanceColoursMap.clear();
|
||||
instancePolyDataMap.clear();
|
||||
instanceTensorGlyphMap.clear();
|
||||
instanceActorMap.clear();
|
||||
}
|
||||
|
||||
void G4VtkSceneHandler::AddSolid (const G4Box& box) {
|
||||
|
||||
G4VSceneHandler::AddSolid(box);
|
||||
|
||||
#if 0
|
||||
return;
|
||||
|
||||
const G4VModel* pv_model = GetModel();
|
||||
if (!pv_model) { return ; }
|
||||
|
||||
G4PhysicalVolumeModel* pPVModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
|
||||
if (!pPVModel) { return ; }
|
||||
|
||||
//-- debug information
|
||||
if(1) {
|
||||
G4VPhysicalVolume *pv = pPVModel->GetCurrentPV();
|
||||
G4LogicalVolume *lv = pv->GetLogicalVolume();
|
||||
G4cout << "name=" << box.GetName() << " volumeType=" << pv->VolumeType() << " pvName=" << pv->GetName() << " lvName=" << lv->GetName() << " multiplicity=" << pv->GetMultiplicity() << " isparametrised=" << pv->IsParameterised() << " isreplicated=" << pv->IsReplicated() << " parametrisation=" << pv->GetParameterisation() << G4endl;
|
||||
}
|
||||
|
||||
if(0) {
|
||||
G4Material *mat = pPVModel->GetCurrentMaterial();
|
||||
G4String name = mat->GetName();
|
||||
G4double dens = mat->GetDensity()/(g/cm3);
|
||||
G4int copyNo = pPVModel->GetCurrentPV()->GetCopyNo();
|
||||
G4int depth = pPVModel->GetCurrentDepth();
|
||||
G4cout << " name : " << box.GetName() << G4endl;
|
||||
G4cout << " copy no.: " << copyNo << G4endl;
|
||||
G4cout << " depth : " << depth << G4endl;
|
||||
G4cout << " density : " << dens << " [g/cm3]" << G4endl;
|
||||
G4cout << " location: " << pPVModel->GetCurrentPV()->GetObjectTranslation() << G4endl;
|
||||
G4cout << " Multiplicity : " << pPVModel->GetCurrentPV()->GetMultiplicity() << G4endl;
|
||||
G4cout << " Is replicated? : " << pPVModel->GetCurrentPV()->IsReplicated() << G4endl;
|
||||
G4cout << " Is parameterised? : " << pPVModel->GetCurrentPV()->IsParameterised() << G4endl;
|
||||
G4cout << " top phys. vol. name : " << pPVModel->GetTopPhysicalVolume()->GetName() << G4endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void G4VtkSceneHandler::AddCompound(const G4Mesh& mesh)
|
||||
{
|
||||
#ifdef G4VTKDEBUG
|
||||
G4cout << "G4VtkSceneHandler::AddCompound" << G4endl;
|
||||
#endif
|
||||
|
||||
if(mesh.GetMeshType() != G4Mesh::rectangle || mesh.GetMeshDepth() != 3)
|
||||
{
|
||||
G4VSceneHandler::AddCompound(mesh);
|
||||
}
|
||||
|
||||
auto container = mesh.GetContainerVolume();
|
||||
auto rep1 = container->GetLogicalVolume()->GetDaughter(0);
|
||||
auto rep2 = rep1->GetLogicalVolume()->GetDaughter(0);
|
||||
auto rep3 = rep2->GetLogicalVolume()->GetDaughter(0);
|
||||
|
||||
EAxis rep1_axis, rep2_axis, rep3_axis;
|
||||
G4int rep1_nReplicas, rep2_nReplicas, rep3_nReplicas;
|
||||
G4double rep1_width, rep2_width, rep3_width;
|
||||
G4double rep1_offset, rep2_offset, rep3_offset;
|
||||
G4bool rep1_consuming, rep2_consuming, rep3_consuming;
|
||||
|
||||
rep1->GetReplicationData(rep1_axis,rep1_nReplicas, rep1_width, rep1_offset, rep1_consuming);
|
||||
rep2->GetReplicationData(rep2_axis,rep2_nReplicas, rep2_width, rep2_offset, rep2_consuming);
|
||||
rep3->GetReplicationData(rep3_axis,rep3_nReplicas, rep3_width, rep3_offset, rep3_consuming);
|
||||
|
||||
// Instantiate a temporary G4PhysicalVolumeModel
|
||||
G4ModelingParameters tmpMP;
|
||||
tmpMP.SetCulling(false); // This avoids drawing transparent...
|
||||
tmpMP.SetCullingInvisible(false); // ... or invisble volumes.
|
||||
const G4bool useFullExtent = false; // To avoid calculating the extent
|
||||
|
||||
G4PhysicalVolumeModel tmpPVModel(container, G4PhysicalVolumeModel::UNLIMITED,
|
||||
G4Transform3D(), &tmpMP, useFullExtent);
|
||||
|
||||
// Instantiate a pseudo scene so that we can make a "private" descent and fill vtkImageData
|
||||
vtkSmartPointer<vtkImageData> imagedata = vtkSmartPointer<vtkImageData>::New();
|
||||
imagedata->SetDimensions(rep1_nReplicas+1,rep2_nReplicas+1,rep3_nReplicas+1);
|
||||
imagedata->SetSpacing(rep1_width,rep2_width,rep2_width);
|
||||
imagedata->SetOrigin(0,0,0);
|
||||
imagedata->AllocateScalars(VTK_DOUBLE, 1);
|
||||
|
||||
G4double halfX = 0., halfY = 0., halfZ = 0.;
|
||||
struct PseudoScene : public G4PseudoScene
|
||||
{
|
||||
PseudoScene(
|
||||
G4PhysicalVolumeModel* pvModel, // input...the following are output
|
||||
vtkImageData *vtkId,
|
||||
G4int nx, G4int ny, G4int nz,
|
||||
G4double& halfX, G4double& halfY, G4double& halfZ) : fpPVModel(pvModel)
|
||||
, fVtkId(vtkId)
|
||||
, fNx(nx)
|
||||
, fNy(ny)
|
||||
, fNz(nz)
|
||||
, fHalfX(halfX)
|
||||
, fHalfY(halfY)
|
||||
, fHalfZ(halfZ)
|
||||
{}
|
||||
using G4PseudoScene::AddSolid; // except for...
|
||||
void AddSolid(const G4Box& box)
|
||||
{
|
||||
const G4Colour& colour = fpPVModel->GetCurrentLV()->GetVisAttributes()->GetColour();
|
||||
// G4double density = fpPVModel->GetCurrentLV()->GetMaterial()->GetDensity();
|
||||
const G4ThreeVector& position = fpCurrentObjectTransformation->getTranslation();
|
||||
fHalfX = box.GetXHalfLength();
|
||||
fHalfY = box.GetYHalfLength();
|
||||
fHalfZ = box.GetZHalfLength();
|
||||
fVtkId->SetScalarComponentFromDouble(int(position.x()/(2*fHalfX))+fNx,
|
||||
int(position.y()/(2*fHalfY))+fNy,
|
||||
int(position.z()/(2*fHalfZ))+fNz,
|
||||
0,
|
||||
(colour.GetRed() + colour.GetBlue() + colour.GetGreen())/3.0);
|
||||
}
|
||||
G4PhysicalVolumeModel* fpPVModel;
|
||||
vtkImageData *fVtkId;
|
||||
G4int fNx, fNy, fNz;
|
||||
G4double &fHalfX, &fHalfY, &fHalfZ;
|
||||
}
|
||||
// construct the pseudoScene
|
||||
pseudoScene(&tmpPVModel, imagedata, rep1_nReplicas, rep2_nReplicas, rep3_nReplicas, halfX, halfY, halfZ);
|
||||
|
||||
// Make private descent into the nested parameterisation
|
||||
tmpPVModel.DescribeYourselfTo(pseudoScene);
|
||||
|
||||
vtkSmartPointer<vtkOpenGLGPUVolumeRayCastMapper> volumeMapper = vtkSmartPointer<vtkOpenGLGPUVolumeRayCastMapper>::New();
|
||||
volumeMapper->SetInputData(imagedata);
|
||||
|
||||
vtkNew<vtkVolume> volume;
|
||||
volume->SetMapper(volumeMapper);
|
||||
|
||||
vtkSmartPointer<vtkMatrix4x4> vtkMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
|
||||
|
||||
vtkMatrix->SetElement(0,0,fObjectTransformation.xx());
|
||||
vtkMatrix->SetElement(0,1,fObjectTransformation.xy());
|
||||
vtkMatrix->SetElement(0,2,fObjectTransformation.xz());
|
||||
|
||||
vtkMatrix->SetElement(1,0,fObjectTransformation.yx());
|
||||
vtkMatrix->SetElement(1,1,fObjectTransformation.yy());
|
||||
vtkMatrix->SetElement(1,2,fObjectTransformation.yz());
|
||||
|
||||
vtkMatrix->SetElement(2,0,fObjectTransformation.zx());
|
||||
vtkMatrix->SetElement(2,1,fObjectTransformation.zy());
|
||||
vtkMatrix->SetElement(2,2,fObjectTransformation.zz());
|
||||
|
||||
vtkMatrix->SetElement(3,0, fObjectTransformation.dx());
|
||||
vtkMatrix->SetElement(3,1, fObjectTransformation.dy());
|
||||
vtkMatrix->SetElement(3,2, fObjectTransformation.dz());
|
||||
vtkMatrix->SetElement(3,3, 1);
|
||||
|
||||
volume->SetUserMatrix(vtkMatrix);
|
||||
|
||||
auto *pVtkViewer = dynamic_cast<G4VtkViewer *>(fpViewer);
|
||||
pVtkViewer->renderer->AddVolume(volume);
|
||||
}
|
||||
@@ -0,0 +1,399 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// John Allison 5th April 2001
|
||||
// A template for a simplest possible graphics driver.
|
||||
//?? Lines or sections marked like this require specialisation for your driver.
|
||||
|
||||
#include "G4VtkViewer.hh"
|
||||
|
||||
#include "G4VSceneHandler.hh"
|
||||
#include "G4VtkSceneHandler.hh"
|
||||
|
||||
#include "vtkRendererCollection.h"
|
||||
#include "vtkLightCollection.h"
|
||||
|
||||
#include "vtkWindowToImageFilter.h"
|
||||
#include "vtkImageWriter.h"
|
||||
#include "vtkBMPWriter.h"
|
||||
#include "vtkJPEGWriter.h"
|
||||
#include "vtkPNGWriter.h"
|
||||
#include "vtkPNMWriter.h"
|
||||
#include "vtkTIFFWriter.h"
|
||||
#include "vtkPostScriptWriter.h"
|
||||
#include "vtkOBJExporter.h"
|
||||
#include "vtkVRMLExporter.h"
|
||||
#include "vtkSingleVTPExporter.h"
|
||||
|
||||
#include "vtkShadowMapPass.h"
|
||||
#include "vtkShadowMapBakerPass.h"
|
||||
#include "vtkSequencePass.h"
|
||||
#include "vtkCameraPass.h"
|
||||
#include "vtkRenderPass.h"
|
||||
#include "vtkRenderPassCollection.h"
|
||||
|
||||
#include "vtkOpenGLRenderer.h"
|
||||
|
||||
G4VtkViewer::G4VtkViewer(G4VSceneHandler& sceneHandler, const G4String& name)
|
||||
: G4VViewer(sceneHandler, sceneHandler.IncrementViewCount(), name)
|
||||
{
|
||||
// Set default and current view parameters
|
||||
fVP.SetAutoRefresh(true);
|
||||
fDefaultVP.SetAutoRefresh(true);
|
||||
}
|
||||
|
||||
void G4VtkViewer::Initialise()
|
||||
{
|
||||
_renderWindow = vtkRenderWindow::New();
|
||||
renderWindowInteractor = vtkRenderWindowInteractor::New();
|
||||
|
||||
#ifdef G4VTKDEBUG
|
||||
G4cout << "G4VtkViewer::G4VtkViewer" << G4endl;
|
||||
|
||||
G4cout << "G4VtkViewer::G4VtkViewer> " << fVP.GetWindowSizeHintX() << " "
|
||||
<< fVP.GetWindowSizeHintY() << G4endl;
|
||||
G4cout << "G4VtkViewer::G4VtkViewer> " << fVP.GetWindowLocationHintX() << " "
|
||||
<< fVP.GetWindowLocationHintY() << G4endl;
|
||||
#endif
|
||||
|
||||
_renderWindow->SetSize(fVP.GetWindowSizeHintX(), fVP.GetWindowSizeHintY());
|
||||
_renderWindow->SetPosition(fVP.GetWindowLocationHintX(),
|
||||
fVP.GetWindowLocationHintY());
|
||||
_renderWindow->SetWindowName("Vtk viewer");
|
||||
|
||||
_renderWindow->AddRenderer(renderer);
|
||||
renderWindowInteractor->SetRenderWindow(_renderWindow);
|
||||
|
||||
// TODO proper camera parameter settings
|
||||
camera->SetPosition(0, 0, 1000);
|
||||
camera->SetFocalPoint(0, 0, 0);
|
||||
renderer->SetActiveCamera(camera);
|
||||
|
||||
//renderer->SetUseHiddenLineRemoval(1); // TODO needs to be an option
|
||||
//renderer->SetUseShadows(1); // TODO needs to be an option
|
||||
|
||||
// Set callback to match VTK parameters to Geant4
|
||||
geant4Callback->SetGeant4ViewParameters(&fVP);
|
||||
renderer->AddObserver(vtkCommand::EndEvent, geant4Callback);
|
||||
|
||||
vtkSmartPointer<vtkInteractorStyleTrackballCamera> style =
|
||||
vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
|
||||
renderWindowInteractor->SetInteractorStyle(style);
|
||||
|
||||
// DrawShadows();
|
||||
}
|
||||
|
||||
G4VtkViewer::~G4VtkViewer() {}
|
||||
|
||||
void G4VtkViewer::SetView() {
|
||||
|
||||
// background colour
|
||||
const G4Colour backgroundColour = fVP.GetBackgroundColour();
|
||||
renderer->SetBackground(backgroundColour.GetRed(), backgroundColour.GetGreen(), backgroundColour.GetBlue());
|
||||
|
||||
// target and camera positions
|
||||
G4double radius = fSceneHandler.GetExtent().GetExtentRadius();
|
||||
if(radius <= 0.)
|
||||
{radius = 1.;}
|
||||
G4double cameraDistance = fVP.GetCameraDistance(radius);
|
||||
G4Point3D viewpointDirection = fVP.GetViewpointDirection();
|
||||
G4Point3D targetPoint = fVP.GetCurrentTargetPoint();
|
||||
G4Point3D cameraPosition =
|
||||
targetPoint + viewpointDirection.unit() * cameraDistance;
|
||||
renderer->GetActiveCamera()->SetFocalPoint(targetPoint.x(),
|
||||
targetPoint.y(),
|
||||
targetPoint.z());
|
||||
renderer->GetActiveCamera()->SetPosition(cameraPosition.x(),
|
||||
cameraPosition.y(),
|
||||
cameraPosition.z());
|
||||
renderer->GetActiveCamera()->SetParallelScale(cameraDistance);
|
||||
|
||||
// need to set camera distance and parallel scale on first set view
|
||||
if(firstSetView)
|
||||
{
|
||||
geant4Callback->SetVtkInitialValues(cameraDistance, cameraDistance);
|
||||
firstSetView = false;
|
||||
}
|
||||
|
||||
// projection type and view angle and zoom factor
|
||||
G4double fieldHalfAngle = fVP.GetFieldHalfAngle();
|
||||
G4double zoomFactor = fVP.GetZoomFactor();
|
||||
vtkCamera* activeCamera = renderer->GetActiveCamera();
|
||||
if(fieldHalfAngle == 0) {
|
||||
activeCamera->SetParallelProjection(1);
|
||||
activeCamera->SetParallelScale(activeCamera->GetParallelScale()/zoomFactor);
|
||||
}
|
||||
else {
|
||||
activeCamera->SetParallelProjection(0);
|
||||
activeCamera->SetViewAngle(2*fieldHalfAngle/M_PI*180);
|
||||
activeCamera->SetPosition(cameraPosition.x()/zoomFactor,
|
||||
cameraPosition.y()/zoomFactor,
|
||||
cameraPosition.z()/zoomFactor);
|
||||
}
|
||||
|
||||
// camera roll
|
||||
// renderer->GetActiveCamera()->SetRoll(0);
|
||||
|
||||
// camera up direction
|
||||
const G4Vector3D upVector = fVP.GetUpVector();
|
||||
renderer->GetActiveCamera()->SetViewUp(upVector.x(),
|
||||
upVector.y(),
|
||||
upVector.z());
|
||||
|
||||
// Light
|
||||
const G4Vector3D lightDirection = fVP.GetLightpointDirection();
|
||||
G4bool lightsMoveWithCamera = fVP.GetLightsMoveWithCamera();
|
||||
G4Vector3D lightPosition =
|
||||
targetPoint + lightDirection.unit() * cameraDistance;
|
||||
|
||||
vtkLightCollection* currentLights = renderer->GetLights();
|
||||
if (currentLights->GetNumberOfItems() != 0)
|
||||
{
|
||||
auto currentLight = dynamic_cast<vtkLight*>(currentLights->GetItemAsObject(0));
|
||||
if (currentLight)
|
||||
{
|
||||
currentLight->SetPosition(lightPosition.x(),
|
||||
lightPosition.y(),
|
||||
lightPosition.z());
|
||||
if (lightsMoveWithCamera)
|
||||
{currentLight->SetLightTypeToCameraLight();}
|
||||
else
|
||||
{currentLight->SetLightTypeToSceneLight();}
|
||||
}
|
||||
}
|
||||
|
||||
// Rotation style
|
||||
G4ViewParameters::RotationStyle rotationStyle = fVP.GetRotationStyle();
|
||||
if (rotationStyle == G4ViewParameters::RotationStyle::freeRotation) {
|
||||
vtkSmartPointer<vtkInteractorStyleTrackballCamera> style =
|
||||
vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
|
||||
renderWindowInteractor->SetInteractorStyle(style);
|
||||
}
|
||||
else if(rotationStyle == G4ViewParameters::RotationStyle::constrainUpDirection) {
|
||||
// camera->SetViewUp(upVector.x(), upVector.y(), upVector.z());
|
||||
vtkSmartPointer<vtkInteractorStyleTerrain> style =
|
||||
vtkSmartPointer<vtkInteractorStyleTerrain>::New();
|
||||
renderWindowInteractor->SetInteractorStyle(style);
|
||||
}
|
||||
}
|
||||
|
||||
void G4VtkViewer::ClearView() {
|
||||
vtkActorCollection *actors = renderer->GetActors();
|
||||
vtkActor *actor = actors->GetLastActor();
|
||||
|
||||
while(actor) {
|
||||
#ifdef G4VTKDEBUG
|
||||
G4cout << "G4VtkViewer::ClearView() remove actor " << actor << G4endl;
|
||||
#endif
|
||||
renderer->RemoveActor(actor);
|
||||
actor = actors->GetLastActor();
|
||||
}
|
||||
|
||||
vtkPropCollection *props = renderer->GetViewProps();
|
||||
vtkProp *prop = props->GetLastProp();
|
||||
|
||||
while(prop) {
|
||||
#ifdef G4VTKDEBUG
|
||||
G4cout << "G4VtkViewer::ClearView() remove prop " << prop << G4endl;
|
||||
#endif
|
||||
renderer->RemoveViewProp(prop);
|
||||
prop = props->GetLastProp();
|
||||
}
|
||||
|
||||
G4VtkSceneHandler& fVtkSceneHandler =
|
||||
dynamic_cast<G4VtkSceneHandler&>(fSceneHandler);
|
||||
fVtkSceneHandler.Clear();
|
||||
}
|
||||
|
||||
void G4VtkViewer::DrawView() {
|
||||
// First, a view should decide when to re-visit the G4 kernel.
|
||||
// Sometimes it might not be necessary, e.g., if the scene is stored
|
||||
// in a graphical database (e.g., OpenGL's display lists) and only
|
||||
// the viewing angle has changed. But graphics systems without a
|
||||
// graphical database will always need to visit the G4 kernel.
|
||||
|
||||
NeedKernelVisit(); // Default is - always visit G4 kernel.
|
||||
// Note: this routine sets the fNeedKernelVisit flag of *all* the
|
||||
// views of the scene.
|
||||
|
||||
ProcessView(); // The basic logic is here.
|
||||
|
||||
// Add HUD
|
||||
DrawViewHUD();
|
||||
|
||||
// ...before finally...
|
||||
FinishView(); // Flush streams and/or swap buffers.
|
||||
}
|
||||
|
||||
void G4VtkViewer::DrawViewHUD()
|
||||
{
|
||||
// make sure text is always visible
|
||||
G4Colour colour = fVP.GetBackgroundColour();
|
||||
infoTextActor->GetTextProperty()->SetColor(std::fmod(colour.GetRed() + 0.5, 1.0),
|
||||
std::fmod(colour.GetGreen() + 0.5, 1.0),
|
||||
std::fmod(colour.GetBlue() + 0.5, 1.0));
|
||||
infoTextActor->GetTextProperty()->SetFontSize(20);
|
||||
infoCallback->SetTextActor(infoTextActor);
|
||||
renderer->AddObserver(vtkCommand::EndEvent, infoCallback);
|
||||
renderer->AddActor(infoTextActor);
|
||||
}
|
||||
|
||||
void G4VtkViewer::DrawShadows()
|
||||
{
|
||||
_renderWindow->SetMultiSamples(0);
|
||||
|
||||
vtkNew<vtkShadowMapPass> shadows;
|
||||
vtkNew<vtkSequencePass> seq;
|
||||
|
||||
vtkNew<vtkRenderPassCollection> passes;
|
||||
passes->AddItem(shadows->GetShadowMapBakerPass());
|
||||
passes->AddItem(shadows);
|
||||
seq->SetPasses(passes);
|
||||
|
||||
vtkNew<vtkCameraPass> cameraP;
|
||||
cameraP->SetDelegatePass(seq);
|
||||
|
||||
// tell the renderer to use our render pass pipeline
|
||||
vtkOpenGLRenderer* glrenderer = dynamic_cast<vtkOpenGLRenderer*>(renderer.GetPointer());
|
||||
glrenderer->SetPass(cameraP);
|
||||
}
|
||||
|
||||
void G4VtkViewer::ShowView()
|
||||
{
|
||||
#ifdef G4VTKDEBUG
|
||||
G4cout << "G4VtkViewer::ShowView() called." << G4endl;
|
||||
// static_cast<G4VtkSceneHandler&>(fSceneHandler).PrintStores();
|
||||
#endif
|
||||
|
||||
G4VtkSceneHandler& fVtkSceneHandler =
|
||||
dynamic_cast<G4VtkSceneHandler&>(fSceneHandler);
|
||||
fVtkSceneHandler.Modified();
|
||||
|
||||
infoTextActor->GetTextProperty()->SetFontSize(28);
|
||||
G4Colour colour = fVP.GetBackgroundColour();
|
||||
|
||||
// make sure text is always visible
|
||||
infoTextActor->GetTextProperty()->SetColor(std::fmod(colour.GetRed() + 0.5, 1.0),
|
||||
std::fmod(colour.GetGreen() + 0.5, 1.0),
|
||||
std::fmod(colour.GetBlue() + 0.5, 1.0));
|
||||
infoTextActor->GetTextProperty()->SetFontSize(20);
|
||||
infoCallback->SetTextActor(infoTextActor);
|
||||
renderer->AddObserver(vtkCommand::EndEvent, infoCallback);
|
||||
geant4Callback->SetGeant4ViewParameters(&fVP);
|
||||
renderer->AddObserver(vtkCommand::EndEvent, geant4Callback);
|
||||
renderer->AddActor(infoTextActor);
|
||||
|
||||
_renderWindow->Render();
|
||||
renderWindowInteractor->Initialize();
|
||||
renderWindowInteractor->Start();
|
||||
}
|
||||
|
||||
void G4VtkViewer::FinishView()
|
||||
{
|
||||
G4VtkSceneHandler& fVtkSceneHandler =
|
||||
dynamic_cast<G4VtkSceneHandler&>(fSceneHandler);
|
||||
fVtkSceneHandler.Modified();
|
||||
|
||||
_renderWindow->Render();
|
||||
}
|
||||
|
||||
void G4VtkViewer::ExportScreenShot(G4String path, G4String format)
|
||||
{
|
||||
|
||||
vtkImageWriter *imWriter = nullptr;
|
||||
|
||||
if(format == "bmp") {
|
||||
imWriter = vtkBMPWriter::New();
|
||||
}
|
||||
else if (format == "jpg") {
|
||||
imWriter = vtkJPEGWriter::New();
|
||||
}
|
||||
else if (format == "pnm") {
|
||||
imWriter = vtkPNMWriter::New();
|
||||
}
|
||||
else if (format == "png") {
|
||||
imWriter = vtkPNGWriter::New();
|
||||
}
|
||||
else if (format == "tiff") {
|
||||
imWriter = vtkTIFFWriter::New();
|
||||
}
|
||||
else if (format == "ps") {
|
||||
imWriter = vtkPostScriptWriter::New();
|
||||
}
|
||||
else {
|
||||
imWriter = vtkPNGWriter::New();
|
||||
}
|
||||
|
||||
_renderWindow->Render();
|
||||
|
||||
vtkSmartPointer<vtkWindowToImageFilter> winToImage = vtkSmartPointer<vtkWindowToImageFilter>::New();
|
||||
winToImage->SetInput(_renderWindow);
|
||||
winToImage->SetScale(1);
|
||||
if(format == "ps")
|
||||
{
|
||||
winToImage->SetInputBufferTypeToRGB();
|
||||
winToImage->ReadFrontBufferOff();
|
||||
winToImage->Update();
|
||||
}
|
||||
else
|
||||
{winToImage->SetInputBufferTypeToRGBA();}
|
||||
|
||||
imWriter->SetFileName((path+"."+format).c_str());
|
||||
imWriter->SetInputConnection(winToImage->GetOutputPort());
|
||||
imWriter->Write();
|
||||
}
|
||||
|
||||
void G4VtkViewer::ExportOBJScene(G4String path)
|
||||
{
|
||||
vtkSmartPointer<vtkRenderWindow> _rw1 = vtkSmartPointer<vtkRenderWindow>::New();
|
||||
_rw1->AddRenderer(_renderWindow->GetRenderers()->GetFirstRenderer());
|
||||
vtkSmartPointer<vtkOBJExporter> exporter = vtkSmartPointer<vtkOBJExporter>::New();
|
||||
exporter->SetRenderWindow(_rw1);
|
||||
exporter->SetFilePrefix(path.c_str());
|
||||
exporter->Write();
|
||||
}
|
||||
|
||||
void G4VtkViewer::ExportVRMLScene(G4String path)
|
||||
{
|
||||
vtkSmartPointer<vtkRenderWindow> _rw1 = vtkSmartPointer<vtkRenderWindow>::New();
|
||||
_rw1->AddRenderer(_renderWindow->GetRenderers()->GetFirstRenderer());
|
||||
vtkSmartPointer<vtkVRMLExporter> exporter = vtkSmartPointer<vtkVRMLExporter>::New();
|
||||
exporter->SetRenderWindow(_rw1);
|
||||
exporter->SetFileName((path+".vrml").c_str());
|
||||
exporter->Write();
|
||||
}
|
||||
|
||||
void G4VtkViewer::ExportVTPScene(G4String path)
|
||||
{
|
||||
vtkSmartPointer<vtkRenderWindow> _rw1 = vtkSmartPointer<vtkRenderWindow>::New();
|
||||
_rw1->AddRenderer(_renderWindow->GetRenderers()->GetFirstRenderer());
|
||||
vtkSmartPointer<vtkSingleVTPExporter> exporter = vtkSmartPointer<vtkSingleVTPExporter>::New();
|
||||
exporter->SetRenderWindow(_rw1);
|
||||
exporter->SetFileName((path+".vtp").c_str());
|
||||
exporter->Write();
|
||||
}
|
||||
@@ -0,0 +1,565 @@
|
||||
/*=========================================================================
|
||||
|
||||
Program: Visualization Toolkit
|
||||
Module: vtkTensorGlyphColor.cxx
|
||||
|
||||
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
||||
All rights reserved.
|
||||
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the above copyright notice for more information.
|
||||
|
||||
=========================================================================*/
|
||||
#include "vtkTensorGlyphColor.h"
|
||||
|
||||
#include "vtkStreamingDemandDrivenPipeline.h"
|
||||
#include "vtkCell.h"
|
||||
#include "vtkCellArray.h"
|
||||
#include "vtkDataSet.h"
|
||||
#include "vtkExecutive.h"
|
||||
#include "vtkFloatArray.h"
|
||||
#include "vtkDoubleArray.h"
|
||||
#include "vtkMath.h"
|
||||
#include "vtkInformation.h"
|
||||
#include "vtkInformationVector.h"
|
||||
#include "vtkObjectFactory.h"
|
||||
#include "vtkPointData.h"
|
||||
#include "vtkPolyData.h"
|
||||
#include "vtkTransform.h"
|
||||
|
||||
vtkStandardNewMacro(vtkTensorGlyphColor)
|
||||
|
||||
// Construct object with scaling on and scale factor 1.0. Eigenvalues are
|
||||
// extracted, glyphs are colored with input scalar data, and logarithmic
|
||||
// scaling is turned off.
|
||||
vtkTensorGlyphColor::vtkTensorGlyphColor()
|
||||
{
|
||||
this->Scaling = 1;
|
||||
this->ScaleFactor = 1.0;
|
||||
this->ExtractEigenvalues = 1;
|
||||
this->ColorGlyphs = 1;
|
||||
this->ColorMode = COLOR_BY_SCALARS;
|
||||
this->ClampScaling = 0;
|
||||
this->MaxScaleFactor = 100;
|
||||
this->ThreeGlyphs = 0;
|
||||
this->Symmetric = 0;
|
||||
this->Length = 1.0;
|
||||
|
||||
this->SetNumberOfInputPorts(2);
|
||||
|
||||
// by default, process active point tensors
|
||||
this->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS,
|
||||
vtkDataSetAttributes::TENSORS);
|
||||
|
||||
// by default, process active point scalars
|
||||
this->SetInputArrayToProcess(1, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS,
|
||||
vtkDataSetAttributes::SCALARS);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
vtkTensorGlyphColor::~vtkTensorGlyphColor() = default;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int vtkTensorGlyphColor::RequestUpdateExtent(
|
||||
vtkInformation *vtkNotUsed(request),
|
||||
vtkInformationVector **inputVector,
|
||||
vtkInformationVector *outputVector)
|
||||
{
|
||||
// get the info objects
|
||||
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
|
||||
vtkInformation *sourceInfo = inputVector[1]->GetInformationObject(0);
|
||||
vtkInformation *outInfo = outputVector->GetInformationObject(0);
|
||||
|
||||
if (sourceInfo)
|
||||
{
|
||||
sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(),
|
||||
0);
|
||||
sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),
|
||||
1);
|
||||
sourceInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(),
|
||||
0);
|
||||
}
|
||||
|
||||
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(),
|
||||
outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()));
|
||||
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),
|
||||
outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES()));
|
||||
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(),
|
||||
outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS()));
|
||||
inInfo->Set(vtkStreamingDemandDrivenPipeline::EXACT_EXTENT(), 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int vtkTensorGlyphColor::RequestData(
|
||||
vtkInformation *vtkNotUsed(request),
|
||||
vtkInformationVector **inputVector,
|
||||
vtkInformationVector *outputVector)
|
||||
{
|
||||
// get the info objects
|
||||
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
|
||||
vtkInformation *sourceInfo = inputVector[1]->GetInformationObject(0);
|
||||
vtkInformation *outInfo = outputVector->GetInformationObject(0);
|
||||
|
||||
// get the input and output
|
||||
vtkDataSet *input = vtkDataSet::SafeDownCast(
|
||||
inInfo->Get(vtkDataObject::DATA_OBJECT()));
|
||||
vtkPolyData *source = vtkPolyData::SafeDownCast(
|
||||
sourceInfo->Get(vtkDataObject::DATA_OBJECT()));
|
||||
vtkPolyData *output = vtkPolyData::SafeDownCast(
|
||||
outInfo->Get(vtkDataObject::DATA_OBJECT()));
|
||||
|
||||
vtkDataArray *inTensors;
|
||||
double tensor[9];
|
||||
vtkDataArray *inScalars;
|
||||
vtkIdType numPts, numSourcePts, numSourceCells, inPtId, i;
|
||||
int j;
|
||||
vtkPoints *sourcePts;
|
||||
vtkDataArray *sourceNormals;
|
||||
vtkCellArray *sourceCells, *cells;
|
||||
vtkPoints *newPts;
|
||||
vtkFloatArray *newScalars=nullptr;
|
||||
vtkFloatArray *newNormals=nullptr;
|
||||
double x[3], s;
|
||||
vtkTransform *trans;
|
||||
vtkCell *cell;
|
||||
vtkIdList *cellPts;
|
||||
int npts;
|
||||
vtkIdType *pts;
|
||||
vtkIdType ptIncr, cellId;
|
||||
vtkIdType subIncr;
|
||||
int numDirs, dir, eigen_dir, symmetric_dir;
|
||||
vtkMatrix4x4 *matrix;
|
||||
double *m[3], w[3], *v[3];
|
||||
double m0[3], m1[3], m2[3];
|
||||
double v0[3], v1[3], v2[3];
|
||||
double xv[3], yv[3], zv[3];
|
||||
double maxScale;
|
||||
|
||||
numDirs = (this->ThreeGlyphs?3:1)*(this->Symmetric+1);
|
||||
|
||||
// set up working matrices
|
||||
m[0] = m0; m[1] = m1; m[2] = m2;
|
||||
v[0] = v0; v[1] = v1; v[2] = v2;
|
||||
|
||||
vtkDebugMacro(<<"Generating tensor glyphs");
|
||||
|
||||
vtkPointData *outPD = output->GetPointData();
|
||||
inTensors = this->GetInputArrayToProcess(0, inputVector);
|
||||
inScalars = this->GetInputArrayToProcess(1, inputVector);
|
||||
numPts = input->GetNumberOfPoints();
|
||||
|
||||
if ( !inTensors || numPts < 1 )
|
||||
{
|
||||
vtkErrorMacro(<<"No data to glyph!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
pts = new vtkIdType[source->GetMaxCellSize()];
|
||||
trans = vtkTransform::New();
|
||||
matrix = vtkMatrix4x4::New();
|
||||
|
||||
//
|
||||
// Allocate storage for output PolyData
|
||||
//
|
||||
sourcePts = source->GetPoints();
|
||||
numSourcePts = sourcePts->GetNumberOfPoints();
|
||||
numSourceCells = source->GetNumberOfCells();
|
||||
|
||||
newPts = vtkPoints::New();
|
||||
newPts->Allocate(numDirs*numPts*numSourcePts);
|
||||
|
||||
// Setting up for calls to PolyData::InsertNextCell()
|
||||
if ( (sourceCells=source->GetVerts())->GetNumberOfCells() > 0 )
|
||||
{
|
||||
cells = vtkCellArray::New();
|
||||
cells->Allocate(numDirs*numPts*sourceCells->GetSize());
|
||||
output->SetVerts(cells);
|
||||
cells->Delete();
|
||||
}
|
||||
if ( (sourceCells=this->GetSource()->GetLines())->GetNumberOfCells() > 0 )
|
||||
{
|
||||
cells = vtkCellArray::New();
|
||||
cells->Allocate(numDirs*numPts*sourceCells->GetSize());
|
||||
output->SetLines(cells);
|
||||
cells->Delete();
|
||||
}
|
||||
if ( (sourceCells=this->GetSource()->GetPolys())->GetNumberOfCells() > 0 )
|
||||
{
|
||||
cells = vtkCellArray::New();
|
||||
cells->Allocate(numDirs*numPts*sourceCells->GetSize());
|
||||
output->SetPolys(cells);
|
||||
cells->Delete();
|
||||
}
|
||||
if ( (sourceCells=this->GetSource()->GetStrips())->GetNumberOfCells() > 0 )
|
||||
{
|
||||
cells = vtkCellArray::New();
|
||||
cells->Allocate(numDirs*numPts*sourceCells->GetSize());
|
||||
output->SetStrips(cells);
|
||||
cells->Delete();
|
||||
}
|
||||
|
||||
// only copy scalar data through
|
||||
vtkPointData *pd = this->GetSource()->GetPointData();
|
||||
// generate scalars if eigenvalues are chosen or if scalars exist.
|
||||
if (this->ColorGlyphs &&
|
||||
((this->ColorMode == COLOR_BY_EIGENVALUES) ||
|
||||
(inScalars && (this->ColorMode == COLOR_BY_SCALARS)) ) )
|
||||
{
|
||||
newScalars = vtkFloatArray::New();
|
||||
newScalars->SetNumberOfComponents(4);
|
||||
newScalars->Allocate(numDirs*numPts*numSourcePts);
|
||||
if (this->ColorMode == COLOR_BY_EIGENVALUES)
|
||||
{
|
||||
newScalars->SetName("MaxEigenvalue");
|
||||
}
|
||||
else
|
||||
{
|
||||
newScalars->SetName(inScalars->GetName());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
outPD->CopyAllOff();
|
||||
outPD->CopyScalarsOn();
|
||||
outPD->CopyAllocate(pd,numDirs*numPts*numSourcePts);
|
||||
}
|
||||
if ( (sourceNormals = pd->GetNormals()) )
|
||||
{
|
||||
newNormals = vtkFloatArray::New();
|
||||
newNormals->SetNumberOfComponents(3);
|
||||
newNormals->SetName("Normals");
|
||||
newNormals->Allocate(numDirs*3*numPts*numSourcePts);
|
||||
}
|
||||
//
|
||||
// First copy all topology (transformation independent)
|
||||
//
|
||||
for (inPtId=0; inPtId < numPts; inPtId++)
|
||||
{
|
||||
ptIncr = numDirs * inPtId * numSourcePts;
|
||||
for (cellId=0; cellId < numSourceCells; cellId++)
|
||||
{
|
||||
cell = this->GetSource()->GetCell(cellId);
|
||||
cellPts = cell->GetPointIds();
|
||||
npts = cellPts->GetNumberOfIds();
|
||||
for (dir=0; dir < numDirs; dir++)
|
||||
{
|
||||
// This variable may be removed, but that
|
||||
// will not improve readability
|
||||
subIncr = ptIncr + dir*numSourcePts;
|
||||
for (i=0; i < npts; i++)
|
||||
{
|
||||
pts[i] = cellPts->GetId(i) + subIncr;
|
||||
}
|
||||
output->InsertNextCell(cell->GetCellType(),npts,pts);
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// Traverse all Input points, transforming glyph at Source points
|
||||
//
|
||||
trans->PreMultiply();
|
||||
|
||||
for (inPtId=0; inPtId < numPts; inPtId++)
|
||||
{
|
||||
ptIncr = numDirs * inPtId * numSourcePts;
|
||||
|
||||
// Translation is postponed
|
||||
// Symmetric tensor support
|
||||
inTensors->GetTuple(inPtId, tensor);
|
||||
if (inTensors->GetNumberOfComponents() == 6)
|
||||
{
|
||||
vtkMath::TensorFromSymmetricTensor(tensor);
|
||||
}
|
||||
|
||||
// compute orientation vectors and scale factors from tensor
|
||||
if ( this->ExtractEigenvalues ) // extract appropriate eigenfunctions
|
||||
{
|
||||
// We are interested in the symmetrical part of the tensor only, since
|
||||
// eigenvalues are real if and only if the matrice of reals is symmetrical
|
||||
for (j=0; j<3; j++)
|
||||
{
|
||||
for (i=0; i<3; i++)
|
||||
{
|
||||
m[i][j] = 0.5 * (tensor[i + 3 * j] + tensor[j + 3 * i]);
|
||||
}
|
||||
}
|
||||
vtkMath::Jacobi(m, w, v);
|
||||
|
||||
//copy eigenvectors
|
||||
xv[0] = v[0][0]; xv[1] = v[1][0]; xv[2] = v[2][0];
|
||||
yv[0] = v[0][1]; yv[1] = v[1][1]; yv[2] = v[2][1];
|
||||
zv[0] = v[0][2]; zv[1] = v[1][2]; zv[2] = v[2][2];
|
||||
}
|
||||
else //use tensor columns as eigenvectors
|
||||
{
|
||||
for (i=0; i<3; i++)
|
||||
{
|
||||
xv[i] = tensor[i];
|
||||
yv[i] = tensor[i+3];
|
||||
zv[i] = tensor[i+6];
|
||||
}
|
||||
w[0] = vtkMath::Normalize(xv);
|
||||
w[1] = vtkMath::Normalize(yv);
|
||||
w[2] = vtkMath::Normalize(zv);
|
||||
}
|
||||
|
||||
// compute scale factors
|
||||
w[0] *= this->ScaleFactor;
|
||||
w[1] *= this->ScaleFactor;
|
||||
w[2] *= this->ScaleFactor;
|
||||
|
||||
if ( this->ClampScaling )
|
||||
{
|
||||
for (maxScale=0.0, i=0; i<3; i++)
|
||||
{
|
||||
if ( maxScale < fabs(w[i]) )
|
||||
{
|
||||
maxScale = fabs(w[i]);
|
||||
}
|
||||
}
|
||||
if ( maxScale > this->MaxScaleFactor )
|
||||
{
|
||||
maxScale = this->MaxScaleFactor / maxScale;
|
||||
for (i=0; i<3; i++)
|
||||
{
|
||||
w[i] *= maxScale; //preserve overall shape of glyph
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// normalization is postponed
|
||||
|
||||
// make sure scale is okay (non-zero) and scale data
|
||||
for (maxScale=0.0, i=0; i<3; i++)
|
||||
{
|
||||
if ( w[i] > maxScale )
|
||||
{
|
||||
maxScale = w[i];
|
||||
}
|
||||
}
|
||||
if ( maxScale == 0.0 )
|
||||
{
|
||||
maxScale = 1.0;
|
||||
}
|
||||
for (i=0; i<3; i++)
|
||||
{
|
||||
if ( w[i] == 0.0 )
|
||||
{
|
||||
w[i] = maxScale * 1.0e-06;
|
||||
}
|
||||
}
|
||||
|
||||
// Now do the real work for each "direction"
|
||||
|
||||
for (dir=0; dir < numDirs; dir++)
|
||||
{
|
||||
eigen_dir = dir%(this->ThreeGlyphs?3:1);
|
||||
symmetric_dir = dir/(this->ThreeGlyphs?3:1);
|
||||
|
||||
// Remove previous scales ...
|
||||
trans->Identity();
|
||||
|
||||
// translate Source to Input point
|
||||
input->GetPoint(inPtId, x);
|
||||
trans->Translate(x[0], x[1], x[2]);
|
||||
|
||||
// normalized eigenvectors rotate object for eigen direction 0
|
||||
matrix->Element[0][0] = xv[0];
|
||||
matrix->Element[0][1] = yv[0];
|
||||
matrix->Element[0][2] = zv[0];
|
||||
matrix->Element[1][0] = xv[1];
|
||||
matrix->Element[1][1] = yv[1];
|
||||
matrix->Element[1][2] = zv[1];
|
||||
matrix->Element[2][0] = xv[2];
|
||||
matrix->Element[2][1] = yv[2];
|
||||
matrix->Element[2][2] = zv[2];
|
||||
trans->Concatenate(matrix);
|
||||
|
||||
if (eigen_dir == 1)
|
||||
{
|
||||
trans->RotateZ(90.0);
|
||||
}
|
||||
|
||||
if (eigen_dir == 2)
|
||||
{
|
||||
trans->RotateY(-90.0);
|
||||
}
|
||||
|
||||
if (this->ThreeGlyphs)
|
||||
{
|
||||
trans->Scale(w[eigen_dir], this->ScaleFactor, this->ScaleFactor);
|
||||
}
|
||||
else
|
||||
{
|
||||
trans->Scale(w[0], w[1], w[2]);
|
||||
}
|
||||
|
||||
// Mirror second set to the symmetric position
|
||||
if (symmetric_dir == 1)
|
||||
{
|
||||
trans->Scale(-1.,1.,1.);
|
||||
}
|
||||
|
||||
// if the eigenvalue is negative, shift to reverse direction.
|
||||
// The && is there to ensure that we do not change the
|
||||
// old behaviour of vtkTensorGlyphColors (which only used one dir),
|
||||
// in case there is an oriented glyph, e.g. an arrow.
|
||||
if (w[eigen_dir] < 0 && numDirs > 1)
|
||||
{
|
||||
trans->Translate(-this->Length, 0., 0.);
|
||||
}
|
||||
|
||||
// multiply points (and normals if available) by resulting
|
||||
// matrix
|
||||
trans->TransformPoints(sourcePts,newPts);
|
||||
|
||||
// Apply the transformation to a series of points,
|
||||
// and append the results to outPts.
|
||||
if ( newNormals )
|
||||
{
|
||||
// a negative determinant means the transform turns the
|
||||
// glyph surface inside out, and its surface normals all
|
||||
// point inward. The following scale corrects the surface
|
||||
// normals to point outward.
|
||||
if (trans->GetMatrix()->Determinant() < 0)
|
||||
{
|
||||
trans->Scale(-1.0,-1.0,-1.0);
|
||||
}
|
||||
trans->TransformNormals(sourceNormals,newNormals);
|
||||
}
|
||||
|
||||
// Copy point data from source
|
||||
if ( this->ColorGlyphs && inScalars &&
|
||||
(this->ColorMode == COLOR_BY_SCALARS) )
|
||||
{
|
||||
for (i=0; i < numSourcePts; i++)
|
||||
{
|
||||
auto st = inScalars->GetTuple(inPtId);
|
||||
newScalars->InsertTuple4(ptIncr+i,st[0],st[1],st[2],st[3]);
|
||||
}
|
||||
}
|
||||
else if (this->ColorGlyphs &&
|
||||
(this->ColorMode == COLOR_BY_EIGENVALUES) )
|
||||
{
|
||||
// If ThreeGlyphs is false we use the first (largest)
|
||||
// eigenvalue as scalar.
|
||||
s = w[eigen_dir];
|
||||
for (i=0; i < numSourcePts; i++)
|
||||
{
|
||||
newScalars->InsertTuple(ptIncr+i, &s);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < numSourcePts; i++)
|
||||
{
|
||||
outPD->CopyData(pd,i,ptIncr+i);
|
||||
}
|
||||
}
|
||||
ptIncr += numSourcePts;
|
||||
}
|
||||
}
|
||||
vtkDebugMacro(<<"Generated " << numPts <<" tensor glyphs");
|
||||
//
|
||||
// Update output and release memory
|
||||
//
|
||||
delete [] pts;
|
||||
|
||||
output->SetPoints(newPts);
|
||||
newPts->Delete();
|
||||
|
||||
if ( newScalars )
|
||||
{
|
||||
int idx = outPD->AddArray(newScalars);
|
||||
outPD->SetActiveAttribute(idx, vtkDataSetAttributes::SCALARS);
|
||||
newScalars->Delete();
|
||||
}
|
||||
|
||||
if ( newNormals )
|
||||
{
|
||||
outPD->SetNormals(newNormals);
|
||||
newNormals->Delete();
|
||||
}
|
||||
|
||||
output->Squeeze();
|
||||
trans->Delete();
|
||||
matrix->Delete();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void vtkTensorGlyphColor::SetSourceConnection(int id, vtkAlgorithmOutput* algOutput)
|
||||
{
|
||||
if (id < 0)
|
||||
{
|
||||
vtkErrorMacro("Bad index " << id << " for source.");
|
||||
return;
|
||||
}
|
||||
|
||||
int numConnections = this->GetNumberOfInputConnections(1);
|
||||
if (id < numConnections)
|
||||
{
|
||||
this->SetNthInputConnection(1, id, algOutput);
|
||||
}
|
||||
else if (id == numConnections && algOutput)
|
||||
{
|
||||
this->AddInputConnection(1, algOutput);
|
||||
}
|
||||
else if (algOutput)
|
||||
{
|
||||
vtkWarningMacro("The source id provided is larger than the maximum "
|
||||
"source id, using " << numConnections << " instead.");
|
||||
this->AddInputConnection(1, algOutput);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void vtkTensorGlyphColor::SetSourceData(vtkPolyData *source)
|
||||
{
|
||||
this->SetInputData(1, source);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
vtkPolyData *vtkTensorGlyphColor::GetSource()
|
||||
{
|
||||
if (this->GetNumberOfInputConnections(1) < 1)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return vtkPolyData::SafeDownCast(this->GetExecutive()->GetInputData(1, 0));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int vtkTensorGlyphColor::FillInputPortInformation(int port, vtkInformation *info)
|
||||
{
|
||||
if (port == 1)
|
||||
{
|
||||
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPolyData");
|
||||
return 1;
|
||||
}
|
||||
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
|
||||
return 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void vtkTensorGlyphColor::PrintSelf(ostream& os, vtkIndent indent)
|
||||
{
|
||||
this->Superclass::PrintSelf(os,indent);
|
||||
|
||||
os << indent << "Source: " << this->GetSource() << "\n";
|
||||
os << indent << "Scaling: " << (this->Scaling ? "On\n" : "Off\n");
|
||||
os << indent << "Scale Factor: " << this->ScaleFactor << "\n";
|
||||
os << indent << "Extract Eigenvalues: " << (this->ExtractEigenvalues ? "On\n" : "Off\n");
|
||||
os << indent << "Color Glyphs: " << (this->ColorGlyphs ? "On\n" : "Off\n");
|
||||
os << indent << "Color Mode: " << this->ColorMode << endl;
|
||||
os << indent << "Clamp Scaling: " << (this->ClampScaling ? "On\n" : "Off\n");
|
||||
os << indent << "Max Scale Factor: " << this->MaxScaleFactor << "\n";
|
||||
os << indent << "Three Glyphs: " << (this->ThreeGlyphs ? "On\n" : "Off\n");
|
||||
os << indent << "Symmetric: " << (this->Symmetric ? "On\n" : "Off\n");
|
||||
os << indent << "Length: " << this->Length << "\n";
|
||||
}
|
||||
Reference in New Issue
Block a user