Import Geant4 11.1.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2022-07-01 10:44:02 +02:00
parent b3bf75a2a1
commit c07cea1fe0
2172 changed files with 183300 additions and 123938 deletions
+2 -5
View File
@@ -1,6 +1,3 @@
# - G4graphics_reps category build(s)
# Add allocation export symbol for the graphics_reps category
add_definitions(-DG4GREPS_ALLOC_EXPORT)
geant4_global_library_target(NAME G4graphics_reps COMPONENTS sources.cmake)
include(sources.cmake)
geant4_add_category(G4graphics_reps MODULES G4graphics_reps)
+54 -16
View File
@@ -1,23 +1,61 @@
-------------------------------------------------------------------
# Category greps History
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
which **must** added in reverse chronological order (newest at the top). It must **not**
be used as a substitute for writing good git commit messages!
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.
It DOES NOT substitute the CVS log-message one should put at every
committal in the CVS repository !
## 2022-05-01 Evgueni Tcherniaev (greps-V11-00-09)
- Faster version of HepPolyhedronTetMesh
----------------------------------------------------------
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
## 2022-04-22 Evgueni Tcherniaev (greps-V11-00-08)
- `G4Polyhedron`: added move constructor and move assignment
History file for graphics_reps category
---------------------------------------
## 2022-04-10 Evgueni Tcherniaev (greps-V11-00-07)
- `HepPolyhedron`, `G4Polyhedron`:
- Added `HepPolyhedronBoxMesh`, `G4PolyhedronBoxMesh`
- Selection of most coplanar neighboring facets in `JoinCoplanarFacets()`
## 2022-04-06 John Allison (greps-V11-00-06)
- `G4Visible`:
- Add "user" data member `fInfo`, with access and operator<< functions.
- This is intended to offer the user/developer a way of communicating
information. For example, with "special mesh rendering" in G4 vis, we
use it to communicate the name of the material - heart, lungs, etc. - to
the viewer and the vis user can identify the different organs.
- `G4VMarker`:
- Previously, `fInfo` was here. It has been moved to `G4Visible`.
- `G4VMarker` *is* a `G4Visible`, so it still has a `fInfo` data member
by inheritance (and access and operator<< functions).
## 2022-04-05 Evgueni Tcherniaev (greps-V11-00-05)
- Implemented `HepPolyhedron::JoinCoplanarFacets()`
## 2022-04-01 Evgueni Tcherniaev (greps-V11-00-04)
- `HepPolyhedron`, `G4Polyhedron`:
- Added `HepPolyhedron(Nvert, Nface)`, `G4Polyhedron(nvert, nface)`
- Added derived classes `HepPolyhedronTetMesh`, `G4PolyhedronTetMesh`
- Added `SetVertex()`, `SetFacet()`
- Made public `SetReferences()`, `InvertFacets()`;
## 2022-01-28 Ben Morgan (greps-V11-00-03)
- Replace `geant4_global_library_target` with direct file inclusion and
call to `geant4_add_category` to define library build from source modules.
- Make DLL export symbol a CMake module-level compile definition to aid
future modularization
## 2022-01-21 Evgueni Tcherniaev (greps-V11-00-02)
- Revised HepPolyhedronEllipsoid, it fixes visibility
of edges in case of cut ellipsoid
## 2021-12-11 John Allison (greps-V11-00-01)
- G4VisExtent::Transform: Use const auto& to avoid copying.
## 2021-12-10 Ben Morgan (greps-V11-00-00)
- Change to new Markdown History format
---
# History entries prior to 11.0
28 October 2021 Guy Barrand (greps-V10-07-13)
- sources.cmake: declare G4Plotter.hh,.cc.
+40 -5
View File
@@ -78,6 +78,10 @@
// tan1,tan2,halfz) - create polyhedron for Hype;
// G4PolyhedronHyperbolicMirror(a,h,r) - create polyhedron for Hyperbolic mirror;
//
// G4PolyhedronTetMesh(vector<p>) - create polyhedron for tetrahedron mesh;
//
// G4PolyhedronBoxMesh(sx,sy,sz,vector<p>) - create polyhedron for box mesh;
//
// Public functions inherited from HepPolyhedron (this list might be
// incomplete):
// GetNoVertices() - returns number of vertices
@@ -100,8 +104,13 @@
// returns false for the last edge;
// GetNextEdge(p1, p2, edgeFlag) - get next edge;
// returns false for the last edge;
// SetNumberOfRotationSteps(G4int n) - Set number of steps for whole circle;
// SetVertex(index, v) - set vertex;
// SetFacet(index,iv1,iv2,iv3,iv4) - set facet;
// SetReferences() - set references to neighbouring facets;
// JoinCoplanarFacets(tol) - join couples of triangles into quadrilaterals;
// InvertFacets() - invert the order on nodes in facets;
// SetNumberOfRotationSteps(G4int n) - set number of steps for whole circle;
//
// History:
// 21st February 2000 Evgeni Chernaev, John Allison
// - Re-written to inherit HepPolyhedron.
@@ -122,17 +131,29 @@
class G4Polyhedron : public HepPolyhedron, public G4Visible {
public:
// Default constructor
G4Polyhedron ();
// Constructors
G4Polyhedron (G4int Nvert, G4int Nface);
G4Polyhedron (const HepPolyhedron& from);
// Use compiler defaults for copy contructor and assignment. (They
// invoke their counterparts in HepPolyhedron and G4Visible.)
// Copy and move constructors
G4Polyhedron (const G4Polyhedron& from) = default;
G4Polyhedron (G4Polyhedron&& from) = default;
// Assignment and move assignment
G4Polyhedron & operator=(const G4Polyhedron & from) = default;
G4Polyhedron & operator=(G4Polyhedron && from) = default;
// Destructor
virtual ~G4Polyhedron ();
G4int GetNumberOfRotationStepsAtTimeOfCreation() const {
return fNumberOfRotationStepsAtTimeOfCreation;
}
private:
G4int fNumberOfRotationStepsAtTimeOfCreation;
G4int fNumberOfRotationStepsAtTimeOfCreation = fNumberOfRotationSteps;
};
class G4PolyhedronBox: public G4Polyhedron {
@@ -281,6 +302,20 @@ class G4PolyhedronHyperbolicMirror : public G4Polyhedron {
virtual ~G4PolyhedronHyperbolicMirror ();
};
class G4PolyhedronTetMesh : public G4Polyhedron {
public:
G4PolyhedronTetMesh(const std::vector<G4ThreeVector>& tetrahedra);
virtual ~G4PolyhedronTetMesh ();
};
class G4PolyhedronBoxMesh : public G4Polyhedron {
public:
G4PolyhedronBoxMesh(G4double sizeX, G4double sizeY, G4double sizeZ,
const std::vector<G4ThreeVector>& positions);
virtual ~G4PolyhedronBoxMesh ();
};
std::ostream& operator<<(std::ostream& os, const G4Polyhedron&);
#endif /* G4POLYHEDRON_HH */
@@ -143,19 +143,11 @@ public: // With description
void SetScreenRadius (G4double);
void SetFillStyle (FillStyle);
// Access functions to the string for user customizable information
virtual const G4String& GetInfo() const;
virtual void SetInfo( const G4String& info );
private:
G4Point3D fPosition;
G4double fWorldSize; // Default 0. means use screen size.
G4double fScreenSize; // Default 0. means use global default.
FillStyle fFillStyle;
// String for user customizable information
G4String fInfo ;
};
#include "G4VMarker.icc"
@@ -104,7 +104,3 @@ inline void G4VMarker::SetScreenRadius (G4double scr) {
inline void G4VMarker::SetFillStyle (G4VMarker::FillStyle style) {
fFillStyle = style;
}
inline const G4String& G4VMarker::GetInfo() const {return fInfo;}
inline void G4VMarker::SetInfo(const G4String& info) {fInfo = info;}
@@ -77,8 +77,13 @@ public: // With description
// A copy of the G4VisAttributes object is created on the heap to
// ensure a long life.
// Access functions to the string for user customizable information
virtual const G4String& GetInfo() const;
virtual void SetInfo(const G4String& info);
protected:
G4String fInfo; // String for user customizable information
const G4VisAttributes* fpVisAttributes;
G4bool fAllocatedVisAttributes;
};
@@ -28,6 +28,11 @@
//
// John Allison 30th October 1996
inline const G4String& G4Visible::GetInfo() const {return fInfo;}
inline void G4Visible::SetInfo(const G4String& info) {fInfo = info;}
inline const G4VisAttributes* G4Visible::GetVisAttributes () const {
return fpVisAttributes;
}
+55 -8
View File
@@ -71,6 +71,10 @@
// - create polyhedron for Hype;
// HepPolyhedronHyperbolicMirror (a,h,r)
// - create polyhedron for Hyperbolic mirror;
// HepPolyhedronTetMesh (vector<p>)
// - create polyhedron for tetrahedron mesh;
// HepPolyhedronBoxMesh (sx,sy,sz,vector<p>)
// - create polyhedron for box mesh;
// Public functions:
//
// GetNoVertices () - returns number of vertices;
@@ -107,7 +111,12 @@
// in order; returns false when finished all faces;
// GetSurfaceArea() - get surface area of the polyhedron;
// GetVolume() - get volume of the polyhedron;
// GetNumberOfRotationSteps() - get number of steps for whole circle;
// GetNumberOfRotationSteps() - get number of steps for whole circle;
// SetVertex(index, v) - set vertex;
// SetFacet(index,iv1,iv2,iv3,iv4) - set facet;
// SetReferences() - set references to neighbouring facets;
// JoinCoplanarFacets(tolerance) - join coplanar facets where it is possible
// InvertFacets() - invert the order on nodes in facets;
// SetNumberOfRotationSteps (n) - set number of steps for whole circle;
// ResetNumberOfRotationSteps() - reset number of steps for whole circle
// to default value;
@@ -180,6 +189,14 @@
// - added TriangulatePolygon(), RotateContourAroundZ()
// - added HepPolyhedronPgon, HepPolyhedronPcon given by rz-countour
//
// 26.03.22 E.Chernyaev
// - added HepPolyhedronTetMesh
//
// 04.04.22 E.Chernyaev
// - added JoinCoplanarFacets()
//
// 07.04.22 E.Chernyaev
// - added HepPolyhedronBoxMesh
#ifndef HEP_POLYHEDRON_HH
#define HEP_POLYHEDRON_HH
@@ -187,6 +204,7 @@
#include <vector>
#include "G4Types.hh"
#include "G4TwoVector.hh"
#include "G4ThreeVector.hh"
#include "G4Point3D.hh"
#include "G4Normal3D.hh"
#include "G4Transform3D.hh"
@@ -261,16 +279,13 @@ class HepPolyhedron {
G4int a, G4int b, G4int c,
G4int n, const G4int* V);
// For each edge set reference to neighbouring facet
void SetReferences();
// Invert the order on nodes in facets
void InvertFacets();
public:
// Constructor
// Default constructor
HepPolyhedron() : nvert(0), nface(0), pV(0), pF(0) {}
// Constructor with allocation of memory
HepPolyhedron(G4int Nvert, G4int Nface);
// Copy constructor
HepPolyhedron(const HepPolyhedron & from);
@@ -366,6 +381,23 @@ class HepPolyhedron {
// Get number of steps for whole circle
static G4int GetNumberOfRotationSteps();
// Set vertex (1 <= index <= Nvert)
void SetVertex(G4int index, const G4Point3D& v);
// Set facet (1 <= index <= Nface)
void SetFacet(G4int index, G4int iv1, G4int iv2, G4int iv3, G4int iv4 = 0);
// For each edge set reference to neighbouring facet,
// call this after all vertices and facets have been set
void SetReferences();
// Join couples of triangular facets to quadrangular facets
// where it is possible
void JoinCoplanarFacets(G4double tolerance);
// Invert the order on nodes in facets
void InvertFacets();
// Set number of steps for whole circle
static void SetNumberOfRotationSteps(G4int n);
@@ -575,4 +607,19 @@ class HepPolyhedronHyperbolicMirror : public HepPolyhedron
virtual ~HepPolyhedronHyperbolicMirror();
};
class HepPolyhedronTetMesh : public HepPolyhedron
{
public:
HepPolyhedronTetMesh(const std::vector<G4ThreeVector>& tetrahedra);
virtual ~HepPolyhedronTetMesh();
};
class HepPolyhedronBoxMesh : public HepPolyhedron
{
public:
HepPolyhedronBoxMesh(G4double sizeX, G4double sizeY, G4double sizeZ,
const std::vector<G4ThreeVector>& positions);
virtual ~HepPolyhedronBoxMesh();
};
#endif /* HEP_POLYHEDRON_HH */
+1 -1
View File
@@ -74,5 +74,5 @@ geant4_add_module(G4graphics_reps
HepPolyhedron.cc
HepPolyhedronProcessor.src)
geant4_module_compile_definitions(G4graphics_reps PRIVATE G4GREPS_ALLOC_EXPORT)
geant4_module_link_libraries(G4graphics_reps PUBLIC G4globman G4hepgeometry G4intercoms)
+18 -2
View File
@@ -27,8 +27,11 @@
#include "G4Polyhedron.hh"
G4Polyhedron::G4Polyhedron ():
fNumberOfRotationStepsAtTimeOfCreation (fNumberOfRotationSteps)
G4Polyhedron::G4Polyhedron ()
{}
G4Polyhedron::G4Polyhedron (G4int Nvert, G4int Nface):
HepPolyhedron (Nvert, Nface)
{}
G4Polyhedron::~G4Polyhedron () {}
@@ -180,6 +183,19 @@ G4PolyhedronHyperbolicMirror::G4PolyhedronHyperbolicMirror (G4double a,
G4PolyhedronHyperbolicMirror::~G4PolyhedronHyperbolicMirror () {}
G4PolyhedronTetMesh::
G4PolyhedronTetMesh(const std::vector<G4ThreeVector>& tetrahedra):
G4Polyhedron (HepPolyhedronTetMesh(tetrahedra)) {}
G4PolyhedronTetMesh::~G4PolyhedronTetMesh () {}
G4PolyhedronBoxMesh::
G4PolyhedronBoxMesh(G4double sizeX, G4double sizeY, G4double sizeZ,
const std::vector<G4ThreeVector>& positions):
G4Polyhedron (HepPolyhedronBoxMesh(sizeX, sizeY, sizeZ, positions)) {}
G4PolyhedronBoxMesh::~G4PolyhedronBoxMesh () {}
std::ostream& operator<<(std::ostream& os, const G4Polyhedron& polyhedron)
{
os << "G4Polyhedron: "
+4 -11
View File
@@ -36,19 +36,14 @@ G4VMarker::G4VMarker ():
fWorldSize (0.),
fScreenSize (0.),
fFillStyle (noFill)
{
// fInfo: default initialisation.
}
{}
G4VMarker::G4VMarker (const G4Point3D& pos):
fPosition (pos),
fWorldSize (0.),
fScreenSize (0.),
fFillStyle (noFill),
fInfo (G4String())
{
// fInfo: default initialisation.
}
fFillStyle (noFill)
{}
G4VMarker::~G4VMarker () {}
@@ -57,8 +52,7 @@ G4bool G4VMarker::operator != (const G4VMarker& mk) const {
(fWorldSize != mk.fWorldSize) ||
(fScreenSize != mk.fScreenSize) ||
(fFillStyle != mk.fFillStyle) ||
!(fPosition == mk.fPosition) ||
(fInfo != mk.fInfo) );
!(fPosition == mk.fPosition) );
}
std::ostream& operator << (std::ostream& os, const G4VMarker& marker) {
@@ -79,7 +73,6 @@ std::ostream& operator << (std::ostream& os, const G4VMarker& marker) {
default:
os << "unrecognised"; break;
}
if (!marker.fInfo.empty()) os << "\n User information: " << marker.fInfo;
os << "\n " << (const G4Visible&) marker;
return os;
}
+2 -2
View File
@@ -101,8 +101,8 @@ G4bool G4VisExtent::operator != (const G4VisExtent& e) const {
G4VisExtent& G4VisExtent::Transform (const G4Transform3D& transform)
{
auto rotation = transform.getRotation();
auto translation = transform.getTranslation();
const auto& rotation = transform.getRotation();
const auto& translation = transform.getTranslation();
G4ThreeVector nnn(fXmin,fYmin,fZmin);
G4ThreeVector nnx(fXmin,fYmin,fZmax);
+6
View File
@@ -63,6 +63,7 @@ G4Visible::~G4Visible () {
G4Visible& G4Visible::operator= (const G4Visible& rhs) {
if (&rhs == this) return *this;
fInfo = rhs.fInfo;
fAllocatedVisAttributes = rhs.fAllocatedVisAttributes;
if (fAllocatedVisAttributes) {
delete fpVisAttributes;
@@ -74,6 +75,7 @@ G4Visible& G4Visible::operator= (const G4Visible& rhs) {
G4Visible& G4Visible::operator= (G4Visible&& rhs) {
if (&rhs == this) return *this;
fInfo = rhs.fInfo;
if (fAllocatedVisAttributes) delete fpVisAttributes;
fpVisAttributes = rhs.fpVisAttributes;
fAllocatedVisAttributes = rhs.fAllocatedVisAttributes;
@@ -101,6 +103,7 @@ void G4Visible::SetVisAttributes (const G4VisAttributes* pVA) {
}
G4bool G4Visible::operator != (const G4Visible& right) const {
if (fInfo != right.fInfo) return false;
if (fpVisAttributes && right.fpVisAttributes)
return *fpVisAttributes != *right.fpVisAttributes;
else if (!fpVisAttributes && !right.fpVisAttributes) return false;
@@ -108,6 +111,9 @@ G4bool G4Visible::operator != (const G4Visible& right) const {
}
std::ostream& operator << (std::ostream& os, const G4Visible& v) {
os << "G4Visible: ";
if (!v.fInfo.empty()) os << "User information: " << v.fInfo;
os << '\n';
if (v.fpVisAttributes) return os << *(v.fpVisAttributes);
else return os << "No Visualization Attributes";
}
+636 -79
View File
@@ -44,16 +44,16 @@
// - implemented boolean operations (add, subtract, intersect) on polyhedra;
//
// 25.05.01 E.Chernyaev
// - added GetSurfaceArea() and GetVolume();
// - added GetSurfaceArea() and GetVolume()
//
// 05.11.02 E.Chernyaev
// - added createTwistedTrap() and createPolyhedron();
// - added createTwistedTrap() and createPolyhedron()
//
// 20.06.05 G.Cosmo
// - added HepPolyhedronEllipsoid;
// - added HepPolyhedronEllipsoid
//
// 18.07.07 T.Nikitina
// - added HepPolyhedronParaboloid;
// - added HepPolyhedronParaboloid
//
// 22.02.20 E.Chernyaev
// - added HepPolyhedronTet, HepPolyhedronHyberbolicMirror
@@ -62,6 +62,15 @@
// - added TriangulatePolygon(), RotateContourAroundZ()
// - added HepPolyhedronPgon, HepPolyhedronPcon given by rz-contour
//
// 26.03.22 E.Chernyaev
// - added SetVertex(), SetFacet()
// - added HepPolyhedronTetMesh
//
// 04.04.22 E.Chernyaev
// - added JoinCoplanarFacets()
//
// 07.04.22 E.Chernyaev
// - added HepPolyhedronBoxMesh
#include "HepPolyhedron.h"
#include "G4PhysicalConstants.hh"
@@ -108,6 +117,19 @@ std::ostream & operator<<(std::ostream & ostr, const HepPolyhedron & ph) {
return ostr;
}
HepPolyhedron::HepPolyhedron(G4int Nvert, G4int Nface)
/***********************************************************************
* *
* Name: HepPolyhedron constructor with Date: 26.03.2022 *
* allocation of memory Revised: *
* Author: E.Tcherniaev (E.Chernyaev) *
* *
***********************************************************************/
: nvert(0), nface(0), pV(0), pF(0)
{
AllocateMemory(Nvert, Nface);
}
HepPolyhedron::HepPolyhedron(const HepPolyhedron &from)
/***********************************************************************
* *
@@ -227,8 +249,8 @@ G4Normal3D HepPolyhedron::FindNodeNormal(G4int iFace, G4int iNode) const
* *
***********************************************************************/
{
G4Normal3D normal = GetUnitNormal(iFace);
G4int k = iFace, iOrder = 1, n = 1;
G4Normal3D normal = GetUnitNormal(iFace);
G4int k = iFace, iOrder = 1, n = 1;
for(;;) {
k = FindNeighbour(k, iNode, iOrder);
@@ -258,6 +280,63 @@ G4int HepPolyhedron::GetNumberOfRotationSteps()
return fNumberOfRotationSteps;
}
void HepPolyhedron::SetVertex(G4int index, const G4Point3D& v)
/***********************************************************************
* *
* Name: HepPolyhedron::SetVertex Date: 26.03.22 *
* Author: E.Tcherniaev (E.Chernyaev) Revised: *
* *
* Function: Set vertex *
* *
***********************************************************************/
{
if (index < 1 || index > nvert)
{
std::cerr
<< "HepPolyhedron::SetVertex: vertex index = " << index
<< " is out of range\n"
<< " N. of vertices = " << nvert << "\n"
<< " N. of facets = " << nface << std::endl;
return;
}
pV[index] = v;
}
void
HepPolyhedron::SetFacet(G4int index, G4int iv1, G4int iv2, G4int iv3, G4int iv4)
/***********************************************************************
* *
* Name: HepPolyhedron::SetFacet Date: 26.03.22 *
* Author: E.Tcherniaev (E.Chernyaev) Revised: *
* *
* Function: Set facet *
* *
***********************************************************************/
{
if (index < 1 || index > nface)
{
std::cerr
<< "HepPolyhedron::SetFacet: facet index = " << index
<< " is out of range\n"
<< " N. of vertices = " << nvert << "\n"
<< " N. of facets = " << nface << std::endl;
return;
}
if (iv1 < 1 || iv1 > nvert ||
iv2 < 1 || iv2 > nvert ||
iv3 < 1 || iv3 > nvert ||
iv4 < 0 || iv4 > nvert)
{
std::cerr
<< "HepPolyhedron::SetFacet: incorrectly specified facet"
<< " (" << iv1 << ", " << iv2 << ", " << iv3 << ", " << iv4 << ")\n"
<< " N. of vertices = " << nvert << "\n"
<< " N. of facets = " << nface << std::endl;
return;
}
pF[index] = G4Facet(iv1, 0, iv2, 0, iv3, 0, iv4, 0);
}
void HepPolyhedron::SetNumberOfRotationSteps(G4int n)
/***********************************************************************
* *
@@ -1183,6 +1262,95 @@ void HepPolyhedron::SetReferences()
delete [] headList;
}
void HepPolyhedron::JoinCoplanarFacets(G4double tolerance)
/***********************************************************************
* *
* Name: HepPolyhedron::JoinCoplanarFacets Date: 04.04.22 *
* Author: E.Tcherniaev (E.Chernyaev) Revised: *
* *
* Function: Join couples of triangular facets to quadrangular facets *
* where it is possible *
* *
***********************************************************************/
{
G4int njoin = 0;
for (G4int icur = 1; icur <= nface; ++icur)
{
// skip if already joined or quadrangle
if (pF[icur].edge[0].v == 0) continue;
if (pF[icur].edge[3].v != 0) continue;
// skip if all references point to already checked facets
if (pF[icur].edge[0].f < icur &&
pF[icur].edge[1].f < icur &&
pF[icur].edge[2].f < icur) continue;
// compute plane equation
G4Normal3D norm = GetUnitNormal(icur);
G4double dd = norm.dot(pV[pF[icur].edge[0].v]);
G4int vcur0 = std::abs(pF[icur].edge[0].v);
G4int vcur1 = std::abs(pF[icur].edge[1].v);
G4int vcur2 = std::abs(pF[icur].edge[2].v);
// select neighbouring facet
G4int kcheck = 0, icheck = 0, vcheck = 0;
G4double dist = DBL_MAX;
for (G4int k = 0; k < 3; ++k)
{
G4int itmp = pF[icur].edge[k].f;
// skip if already checked, joined or quadrangle
if (itmp < icur) continue;
if (pF[itmp].edge[0].v == 0 ||
pF[itmp].edge[3].v != 0) continue;
// get candidate vertex
G4int vtmp = 0;
for (G4int j = 0; j < 3; ++j)
{
vtmp = std::abs(pF[itmp].edge[j].v);
if (vtmp != vcur0 && vtmp != vcur1 && vtmp != vcur2) break;
}
// check distance to the plane
G4double dtmp = std::abs(norm.dot(pV[vtmp]) - dd);
if (dtmp > tolerance || dtmp >= dist) continue;
dist = dtmp;
kcheck = k;
icheck = itmp;
vcheck = vtmp;
}
if (icheck == 0) continue; // no facet selected
// join facets
njoin++;
pF[icheck].edge[0].v = 0; // mark facet as joined
if (kcheck == 0)
{
pF[icur].edge[3].v = pF[icur].edge[2].v;
pF[icur].edge[2].v = pF[icur].edge[1].v;
pF[icur].edge[1].v = vcheck;
}
else if (kcheck == 1)
{
pF[icur].edge[3].v = pF[icur].edge[2].v;
pF[icur].edge[2].v = vcheck;
}
else
{
pF[icur].edge[3].v = vcheck;
}
}
if (njoin == 0) return; // no joined facets
// restructure facets
G4int nnew = 0;
for (G4int icur = 1; icur <= nface; ++icur)
{
if (pF[icur].edge[0].v == 0) continue;
nnew++;
pF[nnew].edge[0].v = pF[icur].edge[0].v;
pF[nnew].edge[1].v = pF[icur].edge[1].v;
pF[nnew].edge[2].v = pF[icur].edge[2].v;
pF[nnew].edge[3].v = pF[icur].edge[3].v;
}
nface = nnew;
SetReferences();
}
void HepPolyhedron::InvertFacets()
/***********************************************************************
* *
@@ -2527,6 +2695,7 @@ HepPolyhedronEllipsoid::HepPolyhedronEllipsoid(G4double ax, G4double by,
* *
* Name: HepPolyhedronEllipsoid Date: 25.02.05 *
* Author: G.Guerrieri Revised: *
* Evgueni Tcherniaev 20.01.22 *
* *
* Function: Constructor of polyhedron for ELLIPSOID *
* *
@@ -2552,96 +2721,55 @@ HepPolyhedronEllipsoid::HepPolyhedronEllipsoid(G4double ax, G4double by,
return;
}
G4double dthe;
G4double sthe;
G4int cutflag;
cutflag= 0;
if (zCut2 >= cz)
{
sthe= 0.0;
}
else
{
sthe= std::acos(zCut2/cz);
cutflag++;
}
if (zCut1 <= -cz)
{
dthe= pi - sthe;
}
else
{
dthe= std::acos(zCut1/cz)-sthe;
cutflag++;
}
// P R E P A R E T W O P O L Y L I N E S
// generate sphere of radius cz first, then rescale x and y later
G4int nds = (GetNumberOfRotationSteps() + 1) / 2;
G4int np1 = G4int(dthe*nds/pi) + 2 + cutflag;
G4double sthe = std::acos(zCut2/cz);
G4double dthe = std::acos(zCut1/cz) - sthe;
G4int nds = (GetNumberOfRotationSteps() + 1)/2;
G4int np1 = G4int(dthe*nds/pi + 0.5) + 1;
if (np1 <= 1) np1 = 2;
G4int np2 = 2;
G4double *zz, *rr;
zz = new G4double[np1+1];
rr = new G4double[np1+1];
zz = new G4double[np1 + np2];
rr = new G4double[np1 + np2];
if (!zz || !rr)
{
G4Exception("HepPolyhedronEllipsoid::HepPolyhedronEllipsoid",
"greps1002", FatalException, "Out of memory");
}
G4double a = dthe/(np1-cutflag-1);
G4double cosa, sina;
G4int j=0;
if (sthe > 0.0)
{
zz[j]= zCut2;
rr[j]= 0.;
j++;
}
for (G4int i=0; i<np1-cutflag; i++) {
cosa = std::cos(sthe+i*a);
sina = std::sin(sthe+i*a);
zz[j] = cz*cosa;
rr[j] = cz*sina;
j++;
{
G4Exception("HepPolyhedronEllipsoid::HepPolyhedronEllipsoid",
"greps1002", FatalException, "Out of memory");
}
if (j < np1)
{
zz[j]= zCut1;
rr[j]= 0.;
j++;
}
if (j > np1)
{
std::cerr << "Logic error in HepPolyhedronEllipsoid, memory corrupted!"
<< std::endl;
}
if (j < np1)
{
std::cerr << "Warning: logic error in HepPolyhedronEllipsoid."
<< std::endl;
np1= j;
}
zz[j] = 0.;
rr[j] = 0.;
G4double a = dthe/(np1 - 1);
G4double cosa, sina;
for (G4int i = 0; i < np1; ++i)
{
cosa = std::cos(sthe + i*a);
sina = std::sin(sthe + i*a);
zz[i] = cz*cosa;
rr[i] = cz*sina;
}
zz[np1 + 0] = zCut2;
rr[np1 + 0] = 0.;
zz[np1 + 1] = zCut1;
rr[np1 + 1] = 0.;
// R O T A T E P O L Y L I N E S
RotateAroundZ(0, 0.0, twopi, np1, 1, zz, rr, -1, 1);
RotateAroundZ(0, 0., twopi, np1, np2, zz, rr, -1, -1);
SetReferences();
delete [] zz;
delete [] rr;
// rescale x and y vertex coordinates
G4double kx = ax/cz;
G4double ky = by/cz;
G4Point3D* p = pV;
for (G4int i = 0; i < nvert; ++i, ++p)
{
G4Point3D * p= pV;
for (G4int i=0; i<nvert; i++, p++) {
p->setX( p->x() * ax/cz );
p->setY( p->y() * by/cz );
}
p->setX(p->x()*kx);
p->setY(p->y()*ky);
}
}
@@ -2773,7 +2901,436 @@ HepPolyhedronHyperbolicMirror::HepPolyhedronHyperbolicMirror(G4double a,
HepPolyhedronHyperbolicMirror::~HepPolyhedronHyperbolicMirror() {}
G4ThreadLocal G4int HepPolyhedron::fNumberOfRotationSteps = DEFAULT_NUMBER_OF_STEPS;
HepPolyhedronTetMesh::
HepPolyhedronTetMesh(const std::vector<G4ThreeVector>& tetrahedra)
/***********************************************************************
* *
* Name: HepPolyhedronTetMesh Date: 26.03.2022 *
* Author: E.Tcherniaev (E.Chernyaev) Revised: *
* *
* Function: Create polyhedron for tetrahedron mesh *
* *
* Input: tetrahedra - array of tetrahedron vertices, four vertices *
* per tetrahedron *
* *
***********************************************************************/
{
// Check size of input vector
G4int nnodes = tetrahedra.size();
if (nnodes == 0)
{
std::cerr
<< "HepPolyhedronTetMesh: Empty tetrahedron mesh" << std::endl;
return;
}
G4int ntet = nnodes/4;
if (nnodes != ntet*4)
{
std::cerr << "HepPolyhedronTetMesh: Number of nodes = " << nnodes
<< " in tetrahedron mesh is NOT multiple of 4"
<< std::endl;
return;
}
// Find coincident vertices using hash table techniques.
// This could be done using std::unordered_map, but the code
// below runs faster.
std::vector<G4int> iheads(nnodes, -1);
std::vector<std::pair<G4int,G4int>> ipairs(nnodes,std::pair(-1,-1));
for (G4int i = 0; i < nnodes; ++i)
{
// Generate hash key
G4ThreeVector point = tetrahedra[i];
auto key = std::hash<G4double>()(point.x());
key ^= std::hash<G4double>()(point.y());
key ^= std::hash<G4double>()(point.z());
key %= nnodes;
// Check head of the list
if (iheads[key] < 0)
{
iheads[key] = i;
ipairs[i].first = i;
continue;
}
// Loop along the list
for (G4int icur = iheads[key], iprev = 0;;)
{
G4int icheck = ipairs[icur].first;
if (tetrahedra[icheck] == point)
{
ipairs[i].first = icheck; // coincident vertex
break;
}
iprev = icur;
icur = ipairs[icur].second;
// Append vertex to the list
if (icur < 0)
{
ipairs[i].first = i;
ipairs[iprev].second = i;
break;
}
}
}
// Create vector of original facets
struct facet
{
G4int i1, i2, i3;
facet() : i1(0), i2(0), i3(0) {};
facet(G4int k1, G4int k2, G4int k3) : i1(k1), i2(k2), i3(k3) {};
};
G4int nfacets = nnodes;
std::vector<facet> ifacets(nfacets);
for (G4int i = 0; i < nfacets; i += 4)
{
G4int i0 = ipairs[i + 0].first;
G4int i1 = ipairs[i + 1].first;
G4int i2 = ipairs[i + 2].first;
G4int i3 = ipairs[i + 3].first;
if (i0 > i1) std::swap(i0, i1);
if (i0 > i2) std::swap(i0, i2);
if (i0 > i3) std::swap(i0, i3);
if (i1 > i2) std::swap(i1, i2);
if (i1 > i3) std::swap(i1, i3);
G4ThreeVector e1 = tetrahedra[i1] - tetrahedra[i0];
G4ThreeVector e2 = tetrahedra[i2] - tetrahedra[i0];
G4ThreeVector e3 = tetrahedra[i3] - tetrahedra[i0];
G4double volume = (e1.cross(e2)).dot(e3);
if (volume > 0.) std::swap(i2, i3);
ifacets[i + 0] = facet(i0, i1, i2);
ifacets[i + 1] = facet(i0, i2, i3);
ifacets[i + 2] = facet(i0, i3, i1);
ifacets[i + 3] = facet(i1, i3, i2);
}
// Find shared facets
std::fill(iheads.begin(), iheads.end(), -1);
std::fill(ipairs.begin(), ipairs.end(), std::pair(-1,-1));
for (G4int i = 0; i < nfacets; ++i)
{
// Check head of the list
G4int key = ifacets[i].i1;
if (iheads[key] < 0)
{
iheads[key] = i;
ipairs[i].first = i;
continue;
}
// Loop along the list
G4int i2 = ifacets[i].i2, i3 = ifacets[i].i3;
for (G4int icur = iheads[key], iprev = -1;;)
{
G4int icheck = ipairs[icur].first;
if (ifacets[icheck].i2 == i3 && ifacets[icheck].i3 == i2)
{
if (iprev < 0)
{
iheads[key] = ipairs[icur].second;
}
else
{
ipairs[iprev].second = ipairs[icur].second;
}
ipairs[icur].first = -1; // shared facet
ipairs[icur].second = -1;
break;
}
iprev = icur;
icur = ipairs[icur].second;
// Append facet to the list
if (icur < 0)
{
ipairs[i].first = i;
ipairs[iprev].second = i;
break;
}
}
}
// Count vertices and facets skipping shared facets
std::fill(iheads.begin(), iheads.end(), -1);
G4int nver = 0, nfac = 0;
for (G4int i = 0; i < nfacets; ++i)
{
if (ipairs[i].first < 0) continue;
G4int i1 = ifacets[i].i1;
G4int i2 = ifacets[i].i2;
G4int i3 = ifacets[i].i3;
if (iheads[i1] < 0) iheads[i1] = nver++;
if (iheads[i2] < 0) iheads[i2] = nver++;
if (iheads[i3] < 0) iheads[i3] = nver++;
nfac++;
}
// Construct polyhedron
AllocateMemory(nver, nfac);
for (G4int i = 0; i < nnodes; ++i)
{
G4int k = iheads[i];
if (k >= 0) SetVertex(k + 1, tetrahedra[i]);
}
for (G4int i = 0, k = 0; i < nfacets; ++i)
{
if (ipairs[i].first < 0) continue;
G4int i1 = iheads[ifacets[i].i1] + 1;
G4int i2 = iheads[ifacets[i].i2] + 1;
G4int i3 = iheads[ifacets[i].i3] + 1;
SetFacet(++k, i1, i2, i3);
}
SetReferences();
}
HepPolyhedronTetMesh::~HepPolyhedronTetMesh() {}
HepPolyhedronBoxMesh::
HepPolyhedronBoxMesh(G4double sizeX, G4double sizeY, G4double sizeZ,
const std::vector<G4ThreeVector>& positions)
/***********************************************************************
* *
* Name: HepPolyhedronBoxMesh Date: 07.04.2022 *
* Author: E.Tcherniaev (E.Chernyaev) Revised: *
* *
* Function: Create polyhedron for box mesh *
* *
* Input: sizeX, sizeY, sizeZ - dimensions of the mesh cell *
* positions - vector of cell centres *
* *
***********************************************************************/
{
G4int nbox = positions.size();
if (nbox == 0)
{
std::cerr << "HepPolyhedronBoxMesh: Empty box mesh" << std::endl;
return;
}
// compute inverse dimensions
G4double invx = 1./sizeX, invy = 1./sizeY, invz = 1./sizeZ;
// find mesh bounding box
G4ThreeVector pmin = positions[0], pmax = positions[0];
for (const auto& p: positions)
{
if (pmin.x() > p.x()) pmin.setX(p.x());
if (pmin.y() > p.y()) pmin.setY(p.y());
if (pmin.z() > p.z()) pmin.setZ(p.z());
if (pmax.x() < p.x()) pmax.setX(p.x());
if (pmax.y() < p.y()) pmax.setY(p.y());
if (pmax.z() < p.z()) pmax.setZ(p.z());
}
// find number of voxels
G4int nx = (pmax.x() - pmin.x())*invx + 1.5;
G4int ny = (pmax.y() - pmin.y())*invy + 1.5;
G4int nz = (pmax.z() - pmin.z())*invz + 1.5;
// create structures for voxels and node indices
std::vector<char> voxels(nx*ny*nz, 0);
std::vector<G4int> indices((nx+1)*(ny+1)*(nz+1), 0);
// mark voxels listed in positions
G4int kx = ny*nz, ky = nz;
for (const auto& p: positions)
{
G4int ix = (p.x() - pmin.x())*invx + 0.5;
G4int iy = (p.y() - pmin.y())*invy + 0.5;
G4int iz = (p.z() - pmin.z())*invz + 0.5;
G4int i = ix*kx + iy*ky + iz;
voxels[i] = 1;
}
// count number of vertices and facets
// set indices
G4int kvx = (ny + 1)*(nz + 1), kvy = nz + 1;
G4int nver = 0, nfac = 0;
for (const auto& p: positions)
{
G4int ix = (p.x() - pmin.x())*invx + 0.5;
G4int iy = (p.y() - pmin.y())*invy + 0.5;
G4int iz = (p.z() - pmin.z())*invz + 0.5;
//
// 011 111
// +------+
// | 001 | 101
// | +------+
// | | | |
// +---|---+ |
// 010 | 110 |
// +-------+
// 000 100
//
G4int vcheck = 0;
// check (ix - 1) side
vcheck = (ix == 0) ? 0 : voxels[(ix-1)*kx + iy*ky + iz];
if (vcheck == 0)
{
nfac++;
G4int i1 = (ix+0)*kvx + (iy+0)*kvy + (iz+0); // 000
G4int i2 = (ix+0)*kvx + (iy+0)*kvy + (iz+1); // 001
G4int i3 = (ix+0)*kvx + (iy+1)*kvy + (iz+1); // 011
G4int i4 = (ix+0)*kvx + (iy+1)*kvy + (iz+0); // 010
if (indices[i1] == 0) indices[i1] = ++nver;
if (indices[i2] == 0) indices[i2] = ++nver;
if (indices[i3] == 0) indices[i3] = ++nver;
if (indices[i4] == 0) indices[i4] = ++nver;
}
// check (ix + 1) side
vcheck = (ix == nx - 1) ? 0 : voxels[(ix+1)*kx + iy*ky + iz];
if (vcheck == 0)
{
nfac++;
G4int i1 = (ix+1)*kvx + (iy+1)*kvy + (iz+0); // 110
G4int i2 = (ix+1)*kvx + (iy+1)*kvy + (iz+1); // 111
G4int i3 = (ix+1)*kvx + (iy+0)*kvy + (iz+1); // 101
G4int i4 = (ix+1)*kvx + (iy+0)*kvy + (iz+0); // 100
if (indices[i1] == 0) indices[i1] = ++nver;
if (indices[i2] == 0) indices[i2] = ++nver;
if (indices[i3] == 0) indices[i3] = ++nver;
if (indices[i4] == 0) indices[i4] = ++nver;
}
// check (iy - 1) side
vcheck = (iy == 0) ? 0 : voxels[ix*kx + (iy-1)*ky + iz];
if (vcheck == 0)
{
nfac++;
G4int i1 = (ix+0)*kvx + (iy+0)*kvy + (iz+0); // 000
G4int i2 = (ix+1)*kvx + (iy+0)*kvy + (iz+0); // 100
G4int i3 = (ix+1)*kvx + (iy+0)*kvy + (iz+1); // 101
G4int i4 = (ix+0)*kvx + (iy+0)*kvy + (iz+1); // 001
if (indices[i1] == 0) indices[i1] = ++nver;
if (indices[i2] == 0) indices[i2] = ++nver;
if (indices[i3] == 0) indices[i3] = ++nver;
if (indices[i4] == 0) indices[i4] = ++nver;
}
// check (iy + 1) side
vcheck = (iy == ny - 1) ? 0 : voxels[ix*kx + (iy+1)*ky + iz];
if (vcheck == 0)
{
nfac++;
G4int i1 = (ix+0)*kvx + (iy+1)*kvy + (iz+0); // 010
G4int i2 = (ix+0)*kvx + (iy+1)*kvy + (iz+1); // 011
G4int i3 = (ix+1)*kvx + (iy+1)*kvy + (iz+1); // 111
G4int i4 = (ix+1)*kvx + (iy+1)*kvy + (iz+0); // 110
if (indices[i1] == 0) indices[i1] = ++nver;
if (indices[i2] == 0) indices[i2] = ++nver;
if (indices[i3] == 0) indices[i3] = ++nver;
if (indices[i4] == 0) indices[i4] = ++nver;
}
// check (iz - 1) side
vcheck = (iz == 0) ? 0 : voxels[ix*kx + iy*ky + (iz-1)];
if (vcheck == 0)
{
nfac++;
G4int i1 = (ix+0)*kvx + (iy+0)*kvy + (iz+0); // 000
G4int i2 = (ix+0)*kvx + (iy+1)*kvy + (iz+0); // 010
G4int i3 = (ix+1)*kvx + (iy+1)*kvy + (iz+0); // 110
G4int i4 = (ix+1)*kvx + (iy+0)*kvy + (iz+0); // 100
if (indices[i1] == 0) indices[i1] = ++nver;
if (indices[i2] == 0) indices[i2] = ++nver;
if (indices[i3] == 0) indices[i3] = ++nver;
if (indices[i4] == 0) indices[i4] = ++nver;
}
// check (iz + 1) side
vcheck = (iz == nz - 1) ? 0 : voxels[ix*kx + iy*ky + (iz+1)];
if (vcheck == 0)
{
nfac++;
G4int i1 = (ix+0)*kvx + (iy+0)*kvy + (iz+1); // 001
G4int i2 = (ix+1)*kvx + (iy+0)*kvy + (iz+1); // 101
G4int i3 = (ix+1)*kvx + (iy+1)*kvy + (iz+1); // 111
G4int i4 = (ix+0)*kvx + (iy+1)*kvy + (iz+1); // 011
if (indices[i1] == 0) indices[i1] = ++nver;
if (indices[i2] == 0) indices[i2] = ++nver;
if (indices[i3] == 0) indices[i3] = ++nver;
if (indices[i4] == 0) indices[i4] = ++nver;
}
}
// Construct polyhedron
AllocateMemory(nver, nfac);
G4ThreeVector p0(pmin.x() - 0.5*sizeX, pmin.y() - 0.5*sizeY, pmin.z() - 0.5*sizeZ);
for (G4int ix = 0; ix <= nx; ++ix)
{
for (G4int iy = 0; iy <= ny; ++iy)
{
for (G4int iz = 0; iz <= nz; ++iz)
{
G4int i = ix*kvx + iy*kvy + iz;
if (indices[i] == 0) continue;
SetVertex(indices[i], p0 + G4ThreeVector(ix*sizeX, iy*sizeY, iz*sizeZ));
}
}
}
nfac = 0;
for (const auto& p: positions)
{
G4int ix = (p.x() - pmin.x())*invx + 0.5;
G4int iy = (p.y() - pmin.y())*invy + 0.5;
G4int iz = (p.z() - pmin.z())*invz + 0.5;
G4int vcheck = 0;
// check (ix - 1) side
vcheck = (ix == 0) ? 0 : voxels[(ix-1)*kx + iy*ky + iz];
if (vcheck == 0)
{
G4int i1 = (ix+0)*kvx + (iy+0)*kvy + (iz+0); // 000
G4int i2 = (ix+0)*kvx + (iy+0)*kvy + (iz+1); // 001
G4int i3 = (ix+0)*kvx + (iy+1)*kvy + (iz+1); // 011
G4int i4 = (ix+0)*kvx + (iy+1)*kvy + (iz+0); // 010
SetFacet(++nfac, indices[i1], indices[i2], indices[i3], indices[i4]);
}
// check (ix + 1) side
vcheck = (ix == nx - 1) ? 0 : voxels[(ix+1)*kx + iy*ky + iz];
if (vcheck == 0)
{
G4int i1 = (ix+1)*kvx + (iy+1)*kvy + (iz+0); // 110
G4int i2 = (ix+1)*kvx + (iy+1)*kvy + (iz+1); // 111
G4int i3 = (ix+1)*kvx + (iy+0)*kvy + (iz+1); // 101
G4int i4 = (ix+1)*kvx + (iy+0)*kvy + (iz+0); // 100
SetFacet(++nfac, indices[i1], indices[i2], indices[i3], indices[i4]);
}
// check (iy - 1) side
vcheck = (iy == 0) ? 0 : voxels[ix*kx + (iy-1)*ky + iz];
if (vcheck == 0)
{
G4int i1 = (ix+0)*kvx + (iy+0)*kvy + (iz+0); // 000
G4int i2 = (ix+1)*kvx + (iy+0)*kvy + (iz+0); // 100
G4int i3 = (ix+1)*kvx + (iy+0)*kvy + (iz+1); // 101
G4int i4 = (ix+0)*kvx + (iy+0)*kvy + (iz+1); // 001
SetFacet(++nfac, indices[i1], indices[i2], indices[i3], indices[i4]);
}
// check (iy + 1) side
vcheck = (iy == ny - 1) ? 0 : voxels[ix*kx + (iy+1)*ky + iz];
if (vcheck == 0)
{
G4int i1 = (ix+0)*kvx + (iy+1)*kvy + (iz+0); // 010
G4int i2 = (ix+0)*kvx + (iy+1)*kvy + (iz+1); // 011
G4int i3 = (ix+1)*kvx + (iy+1)*kvy + (iz+1); // 111
G4int i4 = (ix+1)*kvx + (iy+1)*kvy + (iz+0); // 110
SetFacet(++nfac, indices[i1], indices[i2], indices[i3], indices[i4]);
}
// check (iz - 1) side
vcheck = (iz == 0) ? 0 : voxels[ix*kx + iy*ky + (iz-1)];
if (vcheck == 0)
{
G4int i1 = (ix+0)*kvx + (iy+0)*kvy + (iz+0); // 000
G4int i2 = (ix+0)*kvx + (iy+1)*kvy + (iz+0); // 010
G4int i3 = (ix+1)*kvx + (iy+1)*kvy + (iz+0); // 110
G4int i4 = (ix+1)*kvx + (iy+0)*kvy + (iz+0); // 100
SetFacet(++nfac, indices[i1], indices[i2], indices[i3], indices[i4]);
}
// check (iz + 1) side
vcheck = (iz == nz - 1) ? 0 : voxels[ix*kx + iy*ky + (iz+1)];
if (vcheck == 0)
{
G4int i1 = (ix+0)*kvx + (iy+0)*kvy + (iz+1); // 001
G4int i2 = (ix+1)*kvx + (iy+0)*kvy + (iz+1); // 101
G4int i3 = (ix+1)*kvx + (iy+1)*kvy + (iz+1); // 111
G4int i4 = (ix+0)*kvx + (iy+1)*kvy + (iz+1); // 011
SetFacet(++nfac, indices[i1], indices[i2], indices[i3], indices[i4]);
}
}
SetReferences();
}
HepPolyhedronBoxMesh::~HepPolyhedronBoxMesh() {}
G4ThreadLocal
G4int HepPolyhedron::fNumberOfRotationSteps = DEFAULT_NUMBER_OF_STEPS;
/***********************************************************************
* *
* Name: HepPolyhedron::fNumberOfRotationSteps Date: 24.06.97 *