Import Geant4 11.1.0.beta source tree
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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: "
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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 *
|
||||
|
||||
Reference in New Issue
Block a user