Files
geant4/source/visualization/management/src/G4Scene.cc
T
2022-07-01 10:44:02 +02:00

323 lines
11 KiB
C++

//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
//
//
// Scene data John Allison 19th July 1996.
#include "G4Scene.hh"
#include "G4Vector3D.hh"
#include "G4BoundingExtentScene.hh"
#include "G4VisAttributes.hh"
#include "G4PhysicalVolumeModel.hh"
#include "G4TransportationManager.hh"
#include <set>
G4Scene::G4Scene (const G4String& name):
fName (name),
fRefreshAtEndOfEvent(true),
fRefreshAtEndOfRun(true),
fMaxNumberOfKeptEvents(100)
{} // Note all other data members have default initial values.
G4Scene::~G4Scene () {}
namespace {
void PrintInvalidModel(const G4VModel* model)
{
G4ExceptionDescription ed;
ed << "Invalid model \"" << model->GetGlobalDescription()
<< "\".\n Not included in extent calculation.";
G4Exception
("G4Scene::CalculateExtent",
"visman0201", JustWarning, ed);
}
}
void G4Scene::CalculateExtent ()
{
G4BoundingExtentScene boundingExtentScene;
for (size_t i = 0; i < fRunDurationModelList.size(); i++) {
if (fRunDurationModelList[i].fActive) {
G4VModel* model = fRunDurationModelList[i].fpModel;
if (model -> Validate()) {
const G4VisExtent& thisExtent = model -> GetExtent ();
if (thisExtent != G4VisExtent::GetNullExtent()) {
boundingExtentScene.AccrueBoundingExtent(thisExtent);
}
} else {
PrintInvalidModel(model);
}
}
}
for (size_t i = 0; i < fEndOfEventModelList.size(); i++) {
if (fEndOfEventModelList[i].fActive) {
G4VModel* model = fEndOfEventModelList[i].fpModel;
if (model -> Validate()) {
const G4VisExtent& thisExtent = model -> GetExtent ();
if (thisExtent != G4VisExtent::GetNullExtent()) {
boundingExtentScene.AccrueBoundingExtent(thisExtent);
}
} else {
PrintInvalidModel(model);
}
}
}
for (size_t i = 0; i < fEndOfRunModelList.size(); i++) {
if (fEndOfRunModelList[i].fActive) {
G4VModel* model = fEndOfRunModelList[i].fpModel;
if (model -> Validate()) {
const G4VisExtent& thisExtent = model -> GetExtent ();
if (thisExtent != G4VisExtent::GetNullExtent()) {
boundingExtentScene.AccrueBoundingExtent(thisExtent);
}
} else {
PrintInvalidModel(model);
}
}
}
fExtent = boundingExtentScene.GetBoundingExtent ();
fStandardTargetPoint = fExtent.GetExtentCentre ();
if (fExtent.GetExtentRadius() <= 0.) {
G4Exception
("G4Scene::CalculateExtent",
"visman0202", JustWarning,
"Scene has no extent. Please activate or add something."
"\nThe camera needs to have something to point at!"
"\nAdd a volume. (You may need \"/run/initialize\".)"
"\nOr use \"/vis/scene/add/extent\"."
"\n\"/vis/scene/list\" to see list of models.");
}
}
G4bool G4Scene::AddWorldIfEmpty (G4bool warn) {
G4bool successful = true;
if (IsEmpty ()) {
successful = false;
G4VPhysicalVolume* pWorld =
G4TransportationManager::GetTransportationManager ()
-> GetNavigatorForTracking () -> GetWorldVolume ();
if (pWorld) {
const G4VisAttributes* pVisAttribs =
pWorld -> GetLogicalVolume () -> GetVisAttributes ();
if (!pVisAttribs || pVisAttribs -> IsVisible ()) {
if (warn) {
G4cout <<
"Your \"world\" has no vis attributes or is marked as visible."
"\n For a better view of the contents, mark the world as"
" invisible, e.g.,"
"\n myWorldLogicalVol ->"
" SetVisAttributes (G4VisAttributes::GetInvisible());"
<< G4endl;
}
}
successful = AddRunDurationModel (new G4PhysicalVolumeModel (pWorld));
// Note: default depth and no modeling parameters.
if (successful) {
if (warn) {
G4cout <<
"G4Scene::AddWorldIfEmpty: The scene had no extent."
"\n \"world\" has been added.";
G4cout << G4endl;
}
}
}
}
return successful;
}
G4bool G4Scene::AddRunDurationModel (G4VModel* pModel, G4bool warn)
{
std::vector<Model>::const_iterator i;
for (i = fRunDurationModelList.begin ();
i != fRunDurationModelList.end (); ++i) {
if (pModel -> GetGlobalDescription () ==
i->fpModel->GetGlobalDescription ()) break;
}
if (i != fRunDurationModelList.end ()) {
if (warn) {
G4cout << "G4Scene::AddRunDurationModel: model \""
<< pModel -> GetGlobalDescription ()
<< "\"\n is already in the run-duration list of scene \""
<< fName
<< "\"."
<< G4endl;
}
return false;
}
fRunDurationModelList.push_back (Model(pModel));
CalculateExtent ();
return true;
}
G4bool G4Scene::AddEndOfEventModel (G4VModel* pModel, G4bool warn) {
G4int i, nModels = fEndOfEventModelList.size ();
for (i = 0; i < nModels; i++) {
if (pModel -> GetGlobalDescription () ==
fEndOfEventModelList[i].fpModel -> GetGlobalDescription ()) break;
}
if (i < nModels) {
if (warn) {
G4cout << "G4Scene::AddEndOfEventModel: a model \""
<< pModel -> GetGlobalDescription ()
<< "\"\n is already in the end-of-event list of scene \""
<< fName << "\"."
<< G4endl;
}
return false;
}
fEndOfEventModelList.push_back (Model(pModel));
CalculateExtent ();
return true;
}
G4bool G4Scene::AddEndOfRunModel (G4VModel* pModel, G4bool warn) {
G4int i, nModels = fEndOfRunModelList.size ();
for (i = 0; i < nModels; i++) {
if (pModel -> GetGlobalDescription () ==
fEndOfRunModelList[i].fpModel -> GetGlobalDescription ()) break;
}
if (i < nModels) {
if (warn) {
G4cout << "G4Scene::AddEndOfRunModel: a model \""
<< pModel -> GetGlobalDescription ()
<< "\"\n is already in the end-of-run list of scene \""
<< fName << "\"."
<< G4endl;
}
return false;
}
fEndOfRunModelList.push_back (pModel);
CalculateExtent ();
return true;
}
std::ostream& operator << (std::ostream& os, const G4Scene& scene) {
size_t i;
os << "Scene data:";
os << "\n Run-duration model list:";
if (scene.fRunDurationModelList.size () == 0) {
os << " none";
}
for (i = 0; i < scene.fRunDurationModelList.size (); i++) {
if (scene.fRunDurationModelList[i].fActive) os << "\n Active: ";
else os << "\n Inactive: ";
os << *(scene.fRunDurationModelList[i].fpModel);
}
os << "\n End-of-event model list:";
if (scene.fEndOfEventModelList.size () == 0) {
os << " none";
}
for (i = 0; i < scene.fEndOfEventModelList.size (); i++) {
if (scene.fEndOfEventModelList[i].fActive) os << "\n Active: ";
else os << "\n Inactive: ";
os << *(scene.fEndOfEventModelList[i].fpModel);
}
os << "\n End-of-run model list:";
if (scene.fEndOfRunModelList.size () == 0) {
os << " none";
}
for (i = 0; i < scene.fEndOfRunModelList.size (); i++) {
if (scene.fEndOfRunModelList[i].fActive) os << "\n Active: ";
else os << "\n Inactive: ";
os << *(scene.fEndOfRunModelList[i].fpModel);
}
os << "\n Overall extent or bounding box: " << scene.fExtent;
os << "\n Standard target point: " << scene.fStandardTargetPoint;
os << "\n End of event action set to \"";
if (scene.fRefreshAtEndOfEvent) os << "refresh\"";
else {
os << "accumulate (maximum number of kept events: ";
if (scene.fMaxNumberOfKeptEvents >= 0) os << scene.fMaxNumberOfKeptEvents;
else os << "unlimited";
os << ")";
}
os << "\n End of run action set to \"";
if (scene.fRefreshAtEndOfRun) os << "refresh";
else os << "accumulate";
os << "\"";
return os;
}
G4bool G4Scene::operator != (const G4Scene& scene) const {
if (
(fRunDurationModelList.size () !=
scene.fRunDurationModelList.size ()) ||
(fEndOfEventModelList.size () !=
scene.fEndOfEventModelList.size ()) ||
(fEndOfRunModelList.size () !=
scene.fEndOfRunModelList.size ()) ||
(fExtent != scene.fExtent) ||
!(fStandardTargetPoint == scene.fStandardTargetPoint) ||
fRefreshAtEndOfEvent != scene.fRefreshAtEndOfEvent ||
fRefreshAtEndOfRun != scene.fRefreshAtEndOfRun ||
fMaxNumberOfKeptEvents != scene.fMaxNumberOfKeptEvents
) return true;
/* A complete comparison should, perhaps, include a comparison of
individual models, but it is not easy to implement operator!= for
all models. Also, it would be unfeasible to ask users to
implement opeerator!= if we ever get round to allowing
user-defined models. Moreover, there is no editing of G4Scene
objects, apart from changing fRefreshAtEndOfEvent, etc; as far as
models are concerned, all you can ever do is add them, so a test
on size (above) is enough.
for (size_t i = 0; i < fRunDurationModelList.size (); i++) {
if (fRunDurationModelList[i] != scene.fRunDurationModelList[i])
return true;
}
for (size_t i = 0; i < fEndOfEventModelList.size (); i++) {
if (fEndOfEventModelList[i] != scene.fEndOfEventModelList[i])
return true;
}
for (size_t i = 0; i < fEndOfRunModelList.size (); i++) {
if (fEndOfRunModelList[i] != scene.fEndOfRunModelList[i])
return true;
}
*/
return false;
}