Import Geant4 10.3.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2016-06-30 14:12:05 +02:00
parent a654a7ab1f
commit 4ec577e5c4
2021 changed files with 100995 additions and 78277 deletions
+52 -1
View File
@@ -1,4 +1,4 @@
$Id: History 93287 2015-10-15 09:50:22Z gcosmo $
$Id: History 97689 2016-06-07 09:34:01Z gcosmo $
-------------------------------------------------------------------
=========================================================
@@ -17,6 +17,57 @@ committal in the CVS repository !
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
June 7, 2016 G.Cosmo geommng-V10-02-13
- Initialise 'emin' and 'emax' in G4BoundingEnvelope::CalculateExtent().
June 6, 2016 E.Tcherniaev geommng-V10-02-12
- Introduced G4BoundingEnvelope helper class to be used for the calculation
of the extent of a solid within the limits defined by the G4VoxelLimits
object.
- Re-implemented CalculateExtent() in G4ReflectedSolid to use new class
G4BoundingEnvelope.
June 6, 2016 E.Tcherniaev geommng-V10-02-11
- G4G4ScaleTransform: simplified signatures in TransformDistance() and
in InverseTransformDistance(); make use of accessors.
June 1, 2016 G.Cosmo geommng-V10-02-10
- Corrected treatment of polyhedron for G4ReflectedSolid to avoid thread
contention.
May 18, 2016 G.Cosmo geommng-V10-02-09, 08
- More simplified code for G4ReflectedSolid; also removed not used cached
inverse transformation.
May 17, 2016 E.Tcherniaev geommng-V10-02-07
- Use G4Normal3D with proper inverse transformation for calculation of
normals in G4ReflectedSolid.
May 13, 2016 G.Cosmo geommng-V10-02-06, 05
- Properly use 3D transformations in G4ReflectedSolid. Removed unused
affine-transformation data and related methods.
Corrected GetPolyhedron() for multi-threading.
- Updated unit test visualization macros and UI setup.
May 12, 2016 E.Tcherniaev geommng-V10-02-04
- Added transformations for normal vectors in G4ScaleTransform.
April 14, 2016 G.Cosmo geommng-V10-02-03
- Added flag for partial use of USolids/VecGeom types.
April 12, 2016 G.Cosmo geommng-V10-02-02
- Minor cosmetics to G4USolid.
March 31, 2016 G.Cosmo geommng-V10-02-01
- Throw exception in call to CreatePolyhedron() for base class G4USolid.
Method is now implemented in the concrete wrappers.
March 16, 2016 G.Cosmo geommng-V10-02-00
- Added G4ScaleTransform class for Cartesian scaling transformations.
- G4AffineTransform: added inline keywords and fixed formatting.
- In G4USolid, directly call GetEntityType() from wrapper classes for
CreatePolyhedron().
October 15, 2015 W.Pokorski geommng-V10-01-07
- Added shadow pointers to shared data structures in G4LogicalVolume
and G4VPhysicalVolume for exclusive use by object persistency.
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4AffineTransform.hh 93152 2015-10-08 11:53:57Z gcosmo $
// $Id: G4AffineTransform.hh 96126 2016-03-16 21:16:54Z gcosmo $
//
//
// class G4AffineTransform
@@ -71,93 +71,94 @@ class G4AffineTransform
public:
G4AffineTransform();
inline G4AffineTransform();
public: // with description
G4AffineTransform(const G4ThreeVector& tlate);
inline G4AffineTransform(const G4ThreeVector& tlate);
// Translation only: under t'form translate point at origin by tlate
G4AffineTransform(const G4RotationMatrix& rot);
inline G4AffineTransform(const G4RotationMatrix& rot);
// Rotation only: under t'form rotate by rot
G4AffineTransform(const G4RotationMatrix& rot,
const G4ThreeVector& tlate);
inline G4AffineTransform(const G4RotationMatrix& rot,
const G4ThreeVector& tlate);
// Under t'form: rotate by rot then translate by tlate
G4AffineTransform(const G4RotationMatrix* rot,
const G4ThreeVector& tlate);
inline G4AffineTransform(const G4RotationMatrix* rot,
const G4ThreeVector& tlate);
// Optionally rotate by *rot then translate by tlate - rot may be null
G4AffineTransform operator * (const G4AffineTransform& tf) const;
inline G4AffineTransform operator * (const G4AffineTransform& tf) const;
// Compound Transforms:
// tf2=tf2*tf1 equivalent to tf2*=tf1
// Returns compound transformation of self*tf
G4AffineTransform& operator *= (const G4AffineTransform& tf);
inline G4AffineTransform& operator *= (const G4AffineTransform& tf);
// (Modifying) Multiplies self by tf; Returns self reference
// ie. A=AB for a*=b
G4AffineTransform& Product(const G4AffineTransform& tf1,
const G4AffineTransform& tf2);
inline G4AffineTransform& Product(const G4AffineTransform& tf1,
const G4AffineTransform& tf2);
// 'Products' for avoiding (potential) temporaries:
// c.Product(a,b) equivalent to c=a*b
// c.InverseProduct(a*b,b ) equivalent to c=a
// (Modifying) Sets self=tf1*tf2; Returns self reference
G4AffineTransform& InverseProduct(const G4AffineTransform& tf1,
const G4AffineTransform& tf2);
inline G4AffineTransform& InverseProduct(const G4AffineTransform& tf1,
const G4AffineTransform& tf2);
// (Modifying) Sets self=tf1*(tf2^-1); Returns self reference
G4ThreeVector TransformPoint(const G4ThreeVector& vec) const;
inline G4ThreeVector TransformPoint(const G4ThreeVector& vec) const;
// Transform the specified point: returns vec*rot+tlate
G4ThreeVector TransformAxis(const G4ThreeVector& axis) const;
inline G4ThreeVector TransformAxis(const G4ThreeVector& axis) const;
// Transform the specified axis: returns
void ApplyPointTransform(G4ThreeVector& vec) const;
inline void ApplyPointTransform(G4ThreeVector& vec) const;
// Transform the specified point (in place): sets vec=vec*rot+tlate
void ApplyAxisTransform(G4ThreeVector& axis) const;
inline void ApplyAxisTransform(G4ThreeVector& axis) const;
// Transform the specified axis (in place): sets axis=axis*rot;
G4AffineTransform Inverse() const;
inline G4AffineTransform Inverse() const;
// Return inverse of current transform
G4AffineTransform& Invert();
inline G4AffineTransform& Invert();
// (Modifying) Sets self=inverse of self; Returns self reference
G4AffineTransform& operator +=(const G4ThreeVector& tlate);
G4AffineTransform& operator -=(const G4ThreeVector& tlate);
inline G4AffineTransform& operator +=(const G4ThreeVector& tlate);
inline G4AffineTransform& operator -=(const G4ThreeVector& tlate);
// (Modifying) Adjust net translation by given vector;
// Returns self reference
G4bool operator == (const G4AffineTransform& tf) const;
G4bool operator != (const G4AffineTransform& tf) const;
inline G4bool operator == (const G4AffineTransform& tf) const;
inline G4bool operator != (const G4AffineTransform& tf) const;
G4double operator [] (const G4int n) const;
inline G4double operator [] (const G4int n) const;
G4bool IsRotated() const;
inline G4bool IsRotated() const;
// True if transform includes rotation
G4bool IsTranslated() const;
inline G4bool IsTranslated() const;
// True if transform includes translation
G4RotationMatrix NetRotation() const;
inline G4RotationMatrix NetRotation() const;
G4ThreeVector NetTranslation() const;
inline G4ThreeVector NetTranslation() const;
void SetNetRotation(const G4RotationMatrix& rot);
inline void SetNetRotation(const G4RotationMatrix& rot);
void SetNetTranslation(const G4ThreeVector& tlate);
inline void SetNetTranslation(const G4ThreeVector& tlate);
private:
G4AffineTransform(const G4double prxx,const G4double prxy,const G4double prxz,
const G4double pryx,const G4double pryy,const G4double pryz,
const G4double przx,const G4double przy,const G4double przz,
const G4double ptx, const G4double pty, const G4double ptz);
inline G4AffineTransform(
const G4double prxx, const G4double prxy, const G4double prxz,
const G4double pryx, const G4double pryy, const G4double pryz,
const G4double przx, const G4double przy, const G4double przz,
const G4double ptx, const G4double pty, const G4double ptz);
G4double rxx,rxy,rxz;
G4double ryx,ryy,ryz;
@@ -0,0 +1,181 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// $Id:$
//
//
// class G4BoundingEnvelope
//
// Class description:
//
// Helper class to facilitate calculation of the extent of a solid
// within the limits defined by the G4VoxelLimits object.
//
// The function CalculateExtent() of a particular solid can create
// a G4BoundingEnvelope object that bounds the solid and then call
// CalculateExtent() of the G4BoundingEnvelope object.
//
// Calculation of the extent by G4BoundingEnvelope takes into account
// special parameter "delta" - width of an imagery layer that envelops
// the object. This value, multiplied by max scale factor, is added
// to the voxel limits during calculation of the extent.
//
// Example of use.
// In case of G4Box, max possible distance of a point to the border
// of the box, where the point is still considered as belonging to
// the surface of the box, is sqrt(0.5)*kCarTolerance (see corner).
// So, it will be safe to set the extension = kCarTolerance.
//
// Alternative solution can be to define G4BoundingEnvelope wide
// enough to include the surface of the solid and set delta = 0.
//
// The class supports the following bouding envelopes:
// - axis aligned bounding box (AABB);
// - bounding prism given by two convex polygonal bases;
// - bounding pyramid given by apex and convex polygonal base;
// - set of bounding prisms, given by a sequence of convex
// polygonal bases;
// History:
//
// 2016.05.25 E.Tcherniaev - initial version
//
// --------------------------------------------------------------------
#ifndef G4BOUNDINGENVELOPE_HH
#define G4BOUNDINGENVELOPE_HH
#include <vector>
#include "geomdefs.hh"
#include "G4ThreeVector.hh"
#include "G4VoxelLimits.hh"
#include "G4Transform3D.hh"
#include "G4Point3D.hh"
#include "G4Plane3D.hh"
typedef std::vector<G4ThreeVector> G4ThreeVectorList;
typedef std::vector<G4Point3D> G4Polygon3D;
typedef std::pair<G4Point3D,G4Point3D> G4Segment3D;
class G4BoundingEnvelope
{
public:
G4BoundingEnvelope(const G4ThreeVector& pMin,
const G4ThreeVector& pMax, G4double delta);
// Constructor from an axis aligned bounding box (AABB)
G4BoundingEnvelope(const G4ThreeVectorList& baseA,
const G4ThreeVectorList& baseB, G4double delta);
// Constructor from a prism given by two bases, the bases
// should have equal number of vertices
G4BoundingEnvelope(const G4ThreeVector& apex,
const G4ThreeVectorList& base, G4double delta);
// Constructor from a pyramid given by apex and base
G4BoundingEnvelope(const std::vector<G4ThreeVectorList*>& polygons,
G4double delta);
// Constructor from a sequence of convex polygons, the polygons
// should have equal numbers of vertices except first and last
// polygons which may consist of a single vertex
G4BoundingEnvelope(const G4BoundingEnvelope& rhs);
// Copy constructor
G4BoundingEnvelope& operator=(const G4BoundingEnvelope& rhs);
// Assignment operator
~G4BoundingEnvelope();
// Destructor
G4bool CalculateExtent(const EAxis pAxis,
const G4VoxelLimits& pVoxelLimits,
const G4Transform3D& pTransform3D,
G4double& pMin, G4double& pMax) const;
// Calculate extent of the envelope
private:
void SetDelta(G4double delta);
// Set the extension
void SetBoundingBox(const G4ThreeVector& pMin,
const G4ThreeVector& pMax);
// Set AABB (axis aligned bounding box)
void SetBoundingPrism(const G4ThreeVectorList& baseA,
const G4ThreeVectorList& baseB);
// Set bounding prism
void SetBoundingPyramid(const G4ThreeVector& apex,
const G4ThreeVectorList& base);
// Set bounding pyramid
void SetBoundingPolygons(const std::vector<G4ThreeVectorList*>& polygons);
// Set bounding sequence of convex polygons
void CleanPolygons();
// Free allocated memory
G4VoxelLimits GetAdjustedVoxelLimits(const G4VoxelLimits& pVoxelLimits,
G4double pDelta) const;
// Extend voxel limits by scaled surface tolerance
void TransformVertices(const G4Transform3D& pTransform3D,
const G4Polygon3D& polyA,
G4Polygon3D& polyB,
G4Segment3D& pAABB) const;
// Transform vertices of a polygon and update AABB (bounding box)
void CreateListOfEdges(const G4Polygon3D& baseA,
const G4Polygon3D& baseB,
std::vector<G4Segment3D>& pEdges) const;
// Create list of edges of a prism
void CreateListOfPlanes(const G4Polygon3D& baseA,
const G4Polygon3D& baseB,
std::vector<G4Plane3D>& pPlanes) const;
// Create list of planes bounding a prism
G4bool ClipEdgesByVoxelLimits(const std::vector<G4Segment3D>& pEdges,
const G4VoxelLimits& pLimits,
G4Segment3D& pExtent) const;
// Clip set of edges by G4VoxelLimits
void ClipVoxelLimitsByPlanes(const G4VoxelLimits& pLimits,
const std::vector<G4Plane3D>& pPlanes,
const G4Segment3D& pAABB,
G4Segment3D& pExtent) const;
// Clip G4VoxelLimits by set of planes bounding a convex prism
private:
G4double fDelta; // extention
std::vector<G4Polygon3D*> fBases; // sequence of polygonal bases
};
#endif // G4BOUNDINGENVELOPE_HH
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4ReflectedSolid.hh 66356 2012-12-18 09:02:32Z gcosmo $
// $Id: G4ReflectedSolid.hh 96930 2016-05-18 08:56:58Z gcosmo $
//
//
// class G4ReflectedSolid
@@ -37,16 +37,13 @@
// History:
//
// 23.07.01 V.Grichine: created
// 15.02.02 V.Grichine: get/set methods for fPtr(Direct)Transform3D
// --------------------------------------------------------------------
#ifndef G4ReflectedSolid_HH
#define G4ReflectedSolid_HH
#include "G4VSolid.hh"
#include "G4RotationMatrix.hh"
#include "G4ThreeVector.hh"
#include "G4Transform3D.hh"
#include "G4AffineTransform.hh"
class G4ReflectedSolid : public G4VSolid
{
@@ -54,10 +51,10 @@ class G4ReflectedSolid : public G4VSolid
G4ReflectedSolid( const G4String& pName,
G4VSolid* pSolid ,
const G4Transform3D& transform ) ;
const G4Transform3D& transform ) ;
// For use in instantiating a transient instance.
virtual ~G4ReflectedSolid() ;
virtual ~G4ReflectedSolid();
// Virtual destructor.
public: // without description
@@ -74,7 +71,7 @@ class G4ReflectedSolid : public G4VSolid
G4ThreeVector SurfaceNormal( const G4ThreeVector& p ) const;
G4double DistanceToIn( const G4ThreeVector& p,
const G4ThreeVector& v ) const;
const G4ThreeVector& v ) const;
G4double DistanceToIn( const G4ThreeVector& p) const;
@@ -82,9 +79,9 @@ class G4ReflectedSolid : public G4VSolid
const G4ThreeVector& v,
const G4bool calcNorm=false,
G4bool *validNorm=0,
G4ThreeVector *n=0 ) const;
G4ThreeVector *n=0 ) const;
G4double DistanceToOut( const G4ThreeVector& p ) const ;
G4double DistanceToOut( const G4ThreeVector& p ) const;
void ComputeDimensions( G4VPVParameterisation* p,
const G4int n,
@@ -103,12 +100,11 @@ class G4ReflectedSolid : public G4VSolid
// If the Solid is a "G4ReflectedSolid",
// return a self pointer else return 0.
G4VSolid* GetConstituentMovedSolid() const;
G4VSolid* GetConstituentMovedSolid() const;
G4Transform3D GetTransform3D() const;
void SetTransform3D(G4Transform3D&);
G4Transform3D GetDirectTransform3D() const;
void SetDirectTransform3D(G4Transform3D&);
G4Transform3D GetTransform3D() const;
G4Transform3D GetDirectTransform3D() const;
void SetDirectTransform3D(G4Transform3D&);
// Accessors methods.
std::ostream& StreamInfo(std::ostream& os) const;
@@ -119,39 +115,18 @@ class G4ReflectedSolid : public G4VSolid
G4ReflectedSolid& operator=(const G4ReflectedSolid& rhs);
// Copy constructor and assignment operator.
void DescribeYourselfTo ( G4VGraphicsScene& scene ) const ;
G4Polyhedron* CreatePolyhedron () const ;
void DescribeYourselfTo ( G4VGraphicsScene& scene ) const;
G4Polyhedron* CreatePolyhedron () const;
G4Polyhedron* GetPolyhedron () const;
// For creating graphical representations (ie for visualisation).
// For creating graphical representations (i.e. for visualisation).
protected:
G4AffineTransform GetTransform() const;
void SetTransform(G4AffineTransform&);
G4AffineTransform GetDirectTransform() const;
void SetDirectTransform(G4AffineTransform&);
G4RotationMatrix GetFrameRotation() const;
void SetFrameRotation(const G4RotationMatrix&);
G4ThreeVector GetFrameTranslation() const;
void SetFrameTranslation(const G4ThreeVector&);
// Get/Set the rotation/translation, as applied to the
// frame of reference.
G4RotationMatrix GetObjectRotation() const;
void SetObjectRotation(const G4RotationMatrix&);
G4ThreeVector GetObjectTranslation() const;
void SetObjectTranslation(const G4ThreeVector&);
// Get/Set the rotation/translation, as applied to the object.
G4VSolid* fPtrSolid ;
G4AffineTransform* fPtrTransform ;
G4AffineTransform* fDirectTransform ;
G4Transform3D* fPtrTransform3D ;
G4Transform3D* fDirectTransform3D ;
G4VSolid* fPtrSolid;
G4Transform3D* fDirectTransform3D;
mutable G4bool fRebuildPolyhedron;
mutable G4Polyhedron* fpPolyhedron; // Caches reflected G4Polyhedron.
} ;
};
#endif
@@ -0,0 +1,148 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// $Id:$
//
//
// class G4ScaleTransform
//
// Class description:
//
// A class for geometric scaling transformations.
// Supports efficient arbitrary transformation of points, vectors and
// normals and the computation of compound & inverse transformations.
//
// Interfaces to the CLHEP class G4ThreeVector
//
// For member function descriptions, see comments by declarations. For
// additional clarification, also check the `const' declarations for
// functions & their parameters.
//
// Member data:
//
// G4ThreeVector fScale; // scale transformation
// G4ThreeVector fIScale; // inverse scale (avoid divisions)
// G4double flFactor; // factor for conversion to local frame
// G4double fgFactor; // factor for conversion to global frame
// History:
// E.Tcherniaev 11 Mar 2016 - added transformations for normal
// G.Cosmo 18 Feb 2016 - initial version
//
// --------------------------------------------------------------------
#ifndef G4SCALETRANSFORM_HH
#define G4SCALETRANSFORM_HH
#include "G4Types.hh"
#include "G4ThreeVector.hh"
#include "G4Transform3D.hh"
class G4ScaleTransform
{
public:
inline G4ScaleTransform();
// Default constructor
inline G4ScaleTransform(G4double sx, G4double sy, G4double sz);
// Constructor with scale parameters on each axis
inline G4ScaleTransform(const G4ThreeVector& scale);
// Constructor taking a 3-vector
inline G4ScaleTransform(const G4Scale3D& scale);
// Constructor taking a Scale3D
inline G4ScaleTransform(const G4ScaleTransform& right);
// Copy constructor
inline G4ScaleTransform& operator=(const G4ScaleTransform& right);
// Assignment operator
inline void Init();
// Update the backed-up inverse scale and special conversion factors
// based on the values of the scale. Needed at initialisation and
// whenever the scale has changed value
inline const G4ThreeVector& GetScale() const;
inline const G4ThreeVector& GetInvScale() const;
// Get reference to the inverse scale transformation
inline void SetScale(const G4ThreeVector& scale);
// Set scale based on vector
inline void SetScale(const G4Scale3D& scale);
// Set scale based on a G4Scale3D transformation
inline void SetScale(G4double sx, G4double sy, G4double sz);
// Set scale based on values
inline void Transform(const G4ThreeVector& global,
G4ThreeVector& local) const;
inline G4ThreeVector Transform(const G4ThreeVector& global) const;
// Transform point from global to local frame
inline void InverseTransform(const G4ThreeVector& local,
G4ThreeVector& global) const;
inline G4ThreeVector InverseTransform(const G4ThreeVector& local) const;
// Transform point from local to global frame
inline void TransformNormal(const G4ThreeVector& global,
G4ThreeVector& local) const;
inline G4ThreeVector TransformNormal(const G4ThreeVector& global) const;
// Transform normal from global to local frame
inline void InverseTransformNormal(const G4ThreeVector& local,
G4ThreeVector& global) const;
inline G4ThreeVector InverseTransformNormal(const G4ThreeVector& local) const;
// Transform normal from local to global frame
inline G4double TransformDistance(G4double dist,
const G4ThreeVector& dir) const;
// Transform distance along given direction from global to local frame
inline G4double TransformDistance(G4double safety) const;
// Transform distance from global to local frame (conservative)
inline G4double InverseTransformDistance(G4double dist,
const G4ThreeVector& dir) const;
// Transform distance along given direction from local to global frame
inline G4double InverseTransformDistance(G4double safety) const;
// Transform distance from local to global frame (conservative)
private:
G4ThreeVector fScale; // scale transformation
G4ThreeVector fIScale; // inverse scale (avoid divisions)
G4double flFactor, fgFactor; // conversion factors to local/global frames
}; // End class G4ScaleTransform
std::ostream& operator<<(std::ostream& os, const G4ScaleTransform& scale);
#include "G4ScaleTransform.icc"
#endif // G4SCALETRANSFORM_HH
@@ -0,0 +1,237 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// $Id: $
//
//
// G4ScaleTransform Inline implementation.
// Based on implementation provided in Root
//
// --------------------------------------------------------------------
inline G4ScaleTransform::G4ScaleTransform()
: fScale(1.,1.,1.), fIScale(1.,1.,1.), flFactor(1.), fgFactor(1.)
{
}
inline G4ScaleTransform::G4ScaleTransform(G4double sx, G4double sy, G4double sz)
: fScale(sx,sy,sz), fIScale(), flFactor(1.), fgFactor(1.)
{
Init();
}
inline G4ScaleTransform::G4ScaleTransform(const G4ThreeVector& scale)
: fScale(scale), fIScale(), flFactor(1.), fgFactor(1.)
{
Init();
}
inline G4ScaleTransform::G4ScaleTransform(const G4Scale3D& scale)
: fScale(scale.xx(), scale.yy(), scale.zz()), fIScale(),
flFactor(1.), fgFactor(1.)
{
Init();
}
inline G4ScaleTransform::G4ScaleTransform(const G4ScaleTransform& right)
: fScale(right.fScale), fIScale(right.fIScale),
flFactor(right.flFactor), fgFactor(right.fgFactor)
{
}
inline G4ScaleTransform&
G4ScaleTransform::operator=(const G4ScaleTransform& right)
{
fScale = right.fScale;
fIScale = right.fIScale;
flFactor = right.flFactor;
fgFactor = right.fgFactor;
return *this;
}
inline void G4ScaleTransform::Init()
{
if (!((fScale.x()>0) && (fScale.y()>0) && (fScale.z()>0)))
{
G4Exception("G4ScaleTransform::Init()", "GeomMgt0001",
FatalException, "Scale transformation must be positive!");
}
fIScale.set(1./fScale.x(), 1./fScale.y(), 1./fScale.z());
flFactor = std::min(std::min(fIScale.x(), fIScale.y()), fIScale.z());
fgFactor = std::min(std::min(fScale.x(), fScale.y()), fScale.z());
}
inline const G4ThreeVector& G4ScaleTransform::GetScale() const
{
return fScale;
}
inline const G4ThreeVector& G4ScaleTransform::GetInvScale() const
{
return fIScale;
}
inline void G4ScaleTransform::SetScale(const G4ThreeVector& scale)
{
fScale = scale;
Init();
}
inline void G4ScaleTransform::SetScale(const G4Scale3D& scale)
{
fScale.set(scale.xx(), scale.yy(), scale.zz());
Init();
}
inline void G4ScaleTransform::SetScale(G4double sx, G4double sy, G4double sz)
{
fScale.set(sx,sy,sz);
Init();
}
inline void G4ScaleTransform::Transform(const G4ThreeVector& global,
G4ThreeVector& local) const
{
local.set(global.x()*fIScale.x(),
global.y()*fIScale.y(),
global.z()*fIScale.z());
}
inline G4ThreeVector
G4ScaleTransform::Transform(const G4ThreeVector& global) const
{
G4ThreeVector local(global.x()*fIScale.x(),
global.y()*fIScale.y(),
global.z()*fIScale.z());
return local;
}
inline void
G4ScaleTransform::InverseTransform(const G4ThreeVector& local,
G4ThreeVector& global) const
{
global.set(local.x()*fScale.x(),
local.y()*fScale.y(),
local.z()*fScale.z());
}
inline G4ThreeVector
G4ScaleTransform::InverseTransform(const G4ThreeVector& local) const
{
G4ThreeVector global(local.x()*fScale.x(),
local.y()*fScale.y(),
local.z()*fScale.z());
return global;
}
inline void
G4ScaleTransform::TransformNormal(const G4ThreeVector& global,
G4ThreeVector& local) const
{
local.set(global.x()*fIScale.y()*fIScale.z(),
global.y()*fIScale.z()*fIScale.x(),
global.z()*fIScale.x()*fIScale.y());
}
inline G4ThreeVector
G4ScaleTransform::TransformNormal(const G4ThreeVector& global) const
{
G4ThreeVector local(global.x()*fIScale.y()*fIScale.z(),
global.y()*fIScale.z()*fIScale.x(),
global.z()*fIScale.x()*fIScale.y());
return local;
}
inline void
G4ScaleTransform::InverseTransformNormal(const G4ThreeVector& local,
G4ThreeVector& global) const
{
global.set(local.x()*fScale.y()*fScale.z(),
local.y()*fScale.z()*fScale.x(),
local.z()*fScale.x()*fScale.y());
}
inline G4ThreeVector
G4ScaleTransform::InverseTransformNormal(const G4ThreeVector& local) const
{
G4ThreeVector global(local.x()*fScale.y()*fScale.z(),
local.y()*fScale.z()*fScale.x(),
local.z()*fScale.x()*fScale.y());
return global;
}
inline G4double
G4ScaleTransform::TransformDistance(G4double dist,
const G4ThreeVector& dir) const
{
G4ThreeVector v(dir.x()*fIScale.x(),
dir.y()*fIScale.y(),
dir.z()*fIScale.z());
G4double scale = std::sqrt(v.dot(v));
return ( scale*dist );
}
inline G4double G4ScaleTransform::TransformDistance(G4double safety) const
{
return ( safety*flFactor );
}
inline G4double
G4ScaleTransform::InverseTransformDistance(G4double dist,
const G4ThreeVector& dir) const
{
G4ThreeVector v(dir.x()*fScale.x(),
dir.y()*fScale.y(),
dir.z()*fScale.z());
G4double scale = std::sqrt(v.dot(v));
return ( scale*dist );
}
inline G4double
G4ScaleTransform::InverseTransformDistance(G4double safety) const
{
return ( safety*fgFactor );
}
inline
std::ostream& operator << (std::ostream& os, const G4ScaleTransform& transf)
{
std::streamsize oldPrec = os.precision(6);
os << " Scale Transformation: " << G4endl
<< " x,y,z: "
<< transf.GetScale().x() << " "
<< transf.GetScale().y() << " "
<< transf.GetScale().z() << G4endl
<< " Inverse x,y,z: "
<< transf.GetInvScale().x() << " "
<< transf.GetInvScale().y() << " "
<< transf.GetInvScale().z() << G4endl;
os.precision(oldPrec);
return os;
}
@@ -40,7 +40,7 @@
#include "G4VSolid.hh"
#if defined(G4GEOM_USE_USOLIDS)
#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
#include "VUSolid.hh"
@@ -154,7 +154,7 @@ class G4USolid : public G4VSolid
virtual G4VisExtent GetExtent() const;
// Provide extent (bounding box) as possible hint to the graphics view.
G4Polyhedron* CreatePolyhedron() const;
virtual G4Polyhedron* CreatePolyhedron() const;
// Create Polyhedron used for Visualisation
virtual G4Polyhedron* GetPolyhedron() const;
// Smart access function - creates on request and stores for future
+5 -1
View File
@@ -11,7 +11,7 @@
#
# Generated on : 24/9/2010
#
# $Id: sources.cmake 85608 2014-10-31 11:23:30Z gcosmo $
# $Id: sources.cmake 97686 2016-06-07 09:27:32Z gcosmo $
#
#------------------------------------------------------------------------------
@@ -37,6 +37,7 @@ GEANT4_DEFINE_MODULE(NAME G4geometrymng
G4AffineTransform.icc
G4BlockingList.hh
G4BlockingList.icc
G4BoundingEnvelope.hh
G4ErrorCylSurfaceTarget.hh
G4ErrorPlaneSurfaceTarget.hh
G4ErrorSurfaceTarget.hh
@@ -55,6 +56,8 @@ GEANT4_DEFINE_MODULE(NAME G4geometrymng
G4Region.hh
G4Region.icc
G4RegionStore.hh
G4ScaleTransform.hh
G4ScaleTransform.icc
G4SmartVoxelHeader.hh
G4SmartVoxelHeader.icc
G4SmartVoxelNode.hh
@@ -85,6 +88,7 @@ GEANT4_DEFINE_MODULE(NAME G4geometrymng
voxeldefs.hh
SOURCES
G4BlockingList.cc
G4BoundingEnvelope.cc
G4ErrorCylSurfaceTarget.cc
G4ErrorPlaneSurfaceTarget.cc
G4ErrorSurfaceTarget.cc
@@ -0,0 +1,733 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// $Id:$
//
//
// Implementation of G4BoundingEnvelope
//
// Author: evgueni.tcherniaev@cern.ch
//
// 2016.05.25 E.Tcherniaev - initial version
//
// --------------------------------------------------------------------
#include <cmath>
#include "globals.hh"
#include "G4BoundingEnvelope.hh"
#include "G4GeometryTolerance.hh"
///////////////////////////////////////////////////////////////////////
//
// Constructor from an axis aligned bounding box
//
G4BoundingEnvelope::G4BoundingEnvelope(const G4ThreeVector& pMin,
const G4ThreeVector& pMax,
G4double delta)
{
SetDelta(delta);
SetBoundingBox(pMin,pMax);
}
///////////////////////////////////////////////////////////////////////
//
// Constructor from a prism
//
G4BoundingEnvelope::G4BoundingEnvelope(const G4ThreeVectorList& baseA,
const G4ThreeVectorList& baseB,
G4double delta)
{
SetDelta(delta);
SetBoundingPrism(baseA,baseB);
}
///////////////////////////////////////////////////////////////////////
//
// Constructor from a pyramid
//
G4BoundingEnvelope::G4BoundingEnvelope(const G4ThreeVector& apex,
const G4ThreeVectorList& base,
G4double delta)
{
SetDelta(delta);
SetBoundingPyramid(apex,base);
}
///////////////////////////////////////////////////////////////////////
//
// Constructor from a sequence of polygons
//
G4BoundingEnvelope::G4BoundingEnvelope(
const std::vector<G4ThreeVectorList*>& polygons,G4double delta)
{
SetDelta(delta);
SetBoundingPolygons(polygons);
}
///////////////////////////////////////////////////////////////////////
//
// Copy constructor
//
G4BoundingEnvelope::G4BoundingEnvelope(const G4BoundingEnvelope& rhs)
: fDelta(rhs.fDelta)
{
// Copy data
G4int nb = rhs.fBases.size();
fBases.resize(nb);
for (G4int i=0; i<nb; i++) {
fBases[i] = new G4Polygon3D(*rhs.fBases[i]);
}
}
///////////////////////////////////////////////////////////////////////
//
// Assignment operator
//
G4BoundingEnvelope&
G4BoundingEnvelope::operator=(const G4BoundingEnvelope& rhs)
{
// Check assignment to self
if (this == &rhs) { return *this; }
// Copy data
fDelta = rhs.fDelta;
CleanPolygons();
G4int nb = rhs.fBases.size();
fBases.resize(nb);
for (G4int i=0; i<nb; i++) {
fBases[i] = new G4Polygon3D(*rhs.fBases[i]);
}
return *this;
}
///////////////////////////////////////////////////////////////////////
//
// Destructor
//
G4BoundingEnvelope::~G4BoundingEnvelope()
{
CleanPolygons();
fBases.resize(0);
}
///////////////////////////////////////////////////////////////////////
//
// Set the extension
//
void G4BoundingEnvelope::SetDelta(G4double delta)
{
fDelta = std::abs(delta);
}
///////////////////////////////////////////////////////////////////////
//
// Set axis aligned bounding box
//
void
G4BoundingEnvelope::SetBoundingBox(const G4ThreeVector& pMin,
const G4ThreeVector& pMax)
{
// Check parameters
if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
{
std::ostringstream message;
message << "Badly defined bounding box (min >= max)!"
<< "\npMin = " << pMin
<< "\npMax = " << pMax;
G4Exception("G4BoundingEnvelope::SetBoundingBox()",
"GeomMgt0001", FatalException, message);
}
CleanPolygons();
fBases.resize(2);
// Set 1st base
fBases[0] = new G4Polygon3D(4);
(*fBases[0])[0] = G4Point3D(pMin.x(),pMin.y(),pMin.z());
(*fBases[0])[1] = G4Point3D(pMax.x(),pMin.y(),pMin.z());
(*fBases[0])[2] = G4Point3D(pMax.x(),pMax.y(),pMin.z());
(*fBases[0])[3] = G4Point3D(pMin.x(),pMax.y(),pMin.z());
// Set 2nd base
fBases[1] = new G4Polygon3D(4);
(*fBases[1])[0] = G4Point3D(pMin.x(),pMin.y(),pMax.z());
(*fBases[1])[1] = G4Point3D(pMax.x(),pMin.y(),pMax.z());
(*fBases[1])[2] = G4Point3D(pMax.x(),pMax.y(),pMax.z());
(*fBases[1])[3] = G4Point3D(pMin.x(),pMax.y(),pMax.z());
}
///////////////////////////////////////////////////////////////////////
//
// Set bounding prism
//
void
G4BoundingEnvelope::SetBoundingPrism(const G4ThreeVectorList& baseA,
const G4ThreeVectorList& baseB)
{
G4int na = baseA.size();
G4int nb = baseB.size();
if (na < 3 || nb < 3 || na != nb)
{
std::ostringstream message;
message << "Badly defined bases of the bounding prism!"
<< "\nNumber of vertices in 1st base: " << na
<< "\nNumber of vertices in 2nd base: " << nb;
G4Exception("G4BoundingEnvelope::SetBoundingPrism()",
"GeomMgt0001", FatalException, message);
}
CleanPolygons();
fBases.resize(2);
// Set 1st base
fBases[0] = new G4Polygon3D(na);
for (G4int i=0; i<na; i++) (*fBases[0])[i] = baseA[i];
// Set 2nd base
fBases[1] = new G4Polygon3D(nb);
for (G4int i=0; i<nb; i++) (*fBases[1])[i] = baseB[i];
}
///////////////////////////////////////////////////////////////////////
//
// Set bounding pyramid
//
void
G4BoundingEnvelope::SetBoundingPyramid(const G4ThreeVector& apex,
const G4ThreeVectorList& base)
{
// Check parameters
G4int np = base.size();
if (np < 3)
{
std::ostringstream message;
message << "Badly defined base of the bounding pyramid!"
<< "\nNumber of vertices in the base: " << np;
G4Exception("G4BoundingEnvelope::SetBoundingPyramid()",
"GeomMgt0001", FatalException, message);
}
CleanPolygons();
fBases.resize(2);
// Set apex
fBases[0] = new G4Polygon3D(1);
(*fBases[0])[0] = apex;
// Set base
fBases[1] = new G4Polygon3D(np);
for (G4int i=0; i<np; i++) (*fBases[1])[i] = base[i];
}
///////////////////////////////////////////////////////////////////////
//
// Set bounding sequence of polygons.
// Firsf and last polygons may consist of a single vertex
//
void G4BoundingEnvelope::SetBoundingPolygons(
const std::vector<G4ThreeVectorList*>& polygons)
{
// Check parameters
G4int nbases = polygons.size();
if (nbases < 2)
{
std::ostringstream message;
message << "Wrong number of polygons in the sequence: " << nbases
<< "\nShould be at least two!";
G4Exception("G4BoundingEnvelope::SetBoundingPolygons()",
"GeomMgt0001", FatalException, message);
return;
}
G4int nsize = std::max(polygons[0]->size(),polygons[1]->size());
if (nsize < 3) {
std::ostringstream message;
message << "Badly constructed polygons!"
<< "\nNumber of polygons: " << nbases
<< "\nPolygon #0 size: " << polygons[0]->size()
<< "\nPolygon #1 size: " << polygons[1]->size()
<< "\n...";
G4Exception("G4BoundingEnvelope::SetBoundingPolygons()",
"GeomMgt0001", FatalException, message);
return;
}
for (G4int k=0; k<nbases; k++) {
G4int np = polygons[k]->size();
if (np == nsize) continue;
if (np == 1 && k==0) continue;
if (np == 1 && k==nbases) continue;
std::ostringstream message;
message << "Badly constructed polygons!"
<< "\nNumber of polygons: " << nbases
<< "\nPolygon #" << k << " size: " << np
<< "\nexpected size: " << nsize;
G4Exception("G4BoundingEnvelope::SetBoundingPolygons()",
"GeomMgt0001", FatalException, message);
return;
}
// Copy polygons
CleanPolygons();
fBases.resize(nbases);
for (G4int k=0; k<nbases; k++) {
G4int np = polygons[k]->size();
fBases[k] = new G4Polygon3D(np);
for (G4int i=0; i<np; i++) (*fBases[k])[i] = (*polygons[k])[i];
}
}
///////////////////////////////////////////////////////////////////////
//
// Free memory allocated for polygons
//
void G4BoundingEnvelope::CleanPolygons()
{
G4int nb = fBases.size();
for (G4int i=0; i<nb; i++) {
delete fBases[i]; fBases[i] = 0;
}
}
///////////////////////////////////////////////////////////////////////
//
// Calculate extent of the specified bounding envelope
//
G4bool
G4BoundingEnvelope::CalculateExtent(const EAxis pAxis,
const G4VoxelLimits& pVoxelLimits,
const G4Transform3D& pTransform3D,
G4double& pMin, G4double& pMax) const
{
// Create adjusted G4VoxelLimits box. New limits are extended by
// fDelta multiplied by max scale factor of the transformation.
//
G4Scale3D scale3D; G4Rotate3D rotate3D; G4Translate3D translate3D;
pTransform3D.getDecomposition(scale3D, rotate3D, translate3D);
G4double scale = std::max(std::max(std::abs(scale3D.xx()),
std::abs(scale3D.yy())),
std::abs(scale3D.zz()));
G4double delta = (scale > 1.) ? fDelta*scale : fDelta;
G4VoxelLimits limits = GetAdjustedVoxelLimits(pVoxelLimits, delta);
// Main loop along the set of prisms
//
G4Segment3D extent(G4Point3D( kInfinity, kInfinity, kInfinity),
G4Point3D(-kInfinity,-kInfinity,-kInfinity));
G4int nbases = fBases.size();
for (G4int k=0; k<nbases-1; k++)
{
// Transform vertices of and find bounding box of current prism
G4Polygon3D baseA, baseB;
G4Segment3D prismAABB(G4Point3D( kInfinity, kInfinity, kInfinity),
G4Point3D(-kInfinity,-kInfinity,-kInfinity));
TransformVertices(pTransform3D, *fBases[k] , baseA, prismAABB);
TransformVertices(pTransform3D, *fBases[k+1], baseB, prismAABB);
// Check that bounding box of the prism intersect the voxel limits
if (prismAABB.first.x() > limits.GetMaxXExtent()) continue;
if (prismAABB.first.y() > limits.GetMaxYExtent()) continue;
if (prismAABB.first.z() > limits.GetMaxZExtent()) continue;
if (prismAABB.second.x() < limits.GetMinXExtent()) continue;
if (prismAABB.second.y() < limits.GetMinYExtent()) continue;
if (prismAABB.second.z() < limits.GetMinZExtent()) continue;
// Clip edges of the prism by adjusted G4VoxelLimits box
std::vector<G4Segment3D> vecEdges;
CreateListOfEdges(baseA, baseB, vecEdges);
if (ClipEdgesByVoxelLimits(vecEdges, limits, extent)) continue;
// Some edges of the prism are completely outside of the voxel
// limits, clip edges of adjusted G4VoxelLimits box by the prism
std::vector<G4Plane3D> vecPlanes;
CreateListOfPlanes(baseA, baseB, vecPlanes);
ClipVoxelLimitsByPlanes(limits, vecPlanes, prismAABB, extent);
}
// Final adjustment of the extent
//
G4double emin=kInfinity, emax=kInfinity;
if (pAxis == kXAxis) { emin = extent.first.x(); emax = extent.second.x(); }
if (pAxis == kYAxis) { emin = extent.first.y(); emax = extent.second.y(); }
if (pAxis == kZAxis) { emin = extent.first.z(); emax = extent.second.z(); }
G4bool exist = false;
if (emin <= emax) {
exist = true;
// Add the extension to the endpoints
if (emin > limits.GetMinExtent(pAxis)) emin -= delta;
if (emax < limits.GetMaxExtent(pAxis)) emax += delta;
G4double kCarTolerance =
G4GeometryTolerance::GetInstance()->GetSurfaceTolerance();
// Clip by original voxel limits, if required
if (emin <= pVoxelLimits.GetMinExtent(pAxis)) {
pMin = pVoxelLimits.GetMinExtent(pAxis) - kCarTolerance;
} else {
pMin = emin;
}
if (emax >= pVoxelLimits.GetMaxExtent(pAxis)) {
pMax = pVoxelLimits.GetMaxExtent(pAxis) + kCarTolerance;
} else {
pMax = emax;
}
exist = true;
} else {
exist = false;
pMin = kInfinity;
pMax = -kInfinity;
}
return exist;
}
///////////////////////////////////////////////////////////////////////
//
// Create adjusted voxel limits
//
G4VoxelLimits
G4BoundingEnvelope::GetAdjustedVoxelLimits(const G4VoxelLimits& pVoxelLimits,
G4double pDelta) const
{
EAxis axis[] = { kXAxis,kYAxis,kZAxis };
G4VoxelLimits limits; // default is unlimited
for (G4int i=0; i<3; i++) {
if (pVoxelLimits.IsLimited(axis[i])) {
G4double emin = pVoxelLimits.GetMinExtent(axis[i]) - pDelta;
G4double emax = pVoxelLimits.GetMaxExtent(axis[i]) + pDelta;
limits.AddLimit(axis[i], emin, emax);
}
}
return limits;
}
///////////////////////////////////////////////////////////////////////
//
// Transform vertices of a polygon and update the bounding box
//
void
G4BoundingEnvelope::TransformVertices(const G4Transform3D& pTransform3D,
const G4Polygon3D& polyA,
G4Polygon3D& polyB,
G4Segment3D& pAABB) const
{
G4double xmin = pAABB.first.x();
G4double ymin = pAABB.first.y();
G4double zmin = pAABB.first.z();
G4double xmax = pAABB.second.x();
G4double ymax = pAABB.second.y();
G4double zmax = pAABB.second.z();
G4int np = polyA.size();
polyB.resize(np);
for (G4int i=0; i<np; i++) {
polyB[i] = pTransform3D*polyA[i];
xmin = std::min(xmin,polyB[i].x());
ymin = std::min(ymin,polyB[i].y());
zmin = std::min(zmin,polyB[i].z());
xmax = std::max(xmax,polyB[i].x());
ymax = std::max(ymax,polyB[i].y());
zmax = std::max(zmax,polyB[i].z());
}
pAABB.first.set( xmin,ymin,zmin);
pAABB.second.set(xmax,ymax,zmax);
}
///////////////////////////////////////////////////////////////////////
//
// Create list of edges of a prism
//
void
G4BoundingEnvelope::CreateListOfEdges(const G4Polygon3D& baseA,
const G4Polygon3D& baseB,
std::vector<G4Segment3D>& pEdges) const
{
G4int na = baseA.size();
G4int nb = baseB.size();
pEdges.resize(0);
if (na == nb) {
G4int k = na - 1;
for (G4int i=0; i<na; i++) {
pEdges.push_back(G4Segment3D(baseA[i],baseB[i]));
pEdges.push_back(G4Segment3D(baseA[i],baseA[k]));
pEdges.push_back(G4Segment3D(baseB[i],baseB[k]));
k = i;
}
} else if (nb == 1) {
G4int k = na - 1;
for (G4int i=0; i<na; i++) {
pEdges.push_back(G4Segment3D(baseA[i],baseA[k]));
pEdges.push_back(G4Segment3D(baseA[i],baseB[0]));
k = i;
}
} else if (na == 1) {
G4int k = nb - 1;
for (G4int i=0; i<nb; i++) {
pEdges.push_back(G4Segment3D(baseB[i],baseB[k]));
pEdges.push_back(G4Segment3D(baseB[i],baseA[0]));
k = i;
}
}
}
///////////////////////////////////////////////////////////////////////
//
// Create list of planes bounding a prism
//
void
G4BoundingEnvelope::CreateListOfPlanes(const G4Polygon3D& baseA,
const G4Polygon3D& baseB,
std::vector<G4Plane3D>& pPlanes) const
{
// Find centers of the bases and internal point of the prism
//
G4int na = baseA.size();
G4int nb = baseB.size();
G4Point3D pa(0.,0.,0.), pb(0.,0.,0.), p0;
for (G4int i=0; i<na; i++) pa += baseA[i];
for (G4int i=0; i<nb; i++) pb += baseB[i];
pa /= na; pb /= nb; p0 = (pa+pb)/2.;
// Create list of planes
//
pPlanes.resize(0);
if (na == nb) {
G4int k = na - 1;
for (G4int i=0; i<na; i++) {
pPlanes.push_back(G4Plane3D(baseA[i],baseA[k],baseB[k]));
k = i;
}
pPlanes.push_back(G4Plane3D(baseA[1],baseA[0],pa));
pPlanes.push_back(G4Plane3D(baseB[0],baseB[1],pb));
} else if (nb == 1) {
G4int k = na - 1;
for (G4int i=0; i<na; i++) {
pPlanes.push_back(G4Plane3D(baseA[i],baseA[k],baseB[0]));
k = i;
}
pPlanes.push_back(G4Plane3D(baseA[2],baseA[1],baseA[0]));
} else if (na == 1) {
G4int k = nb - 1;
for (G4int i=0; i<nb; i++) {
pPlanes.push_back(G4Plane3D(baseB[k],baseB[i],baseA[0]));
k = i;
}
pPlanes.push_back(G4Plane3D(baseB[0],baseB[1],baseB[2]));
}
// Ensure that normals of the planes point to outside
//
G4int nplanes = pPlanes.size();
for (G4int i=0; i<nplanes; i++) {
pPlanes[i].normalize();
if (pPlanes[i].distance(p0) > 0) {
pPlanes[i] = G4Plane3D(-pPlanes[i].a(),-pPlanes[i].b(),
-pPlanes[i].c(),-pPlanes[i].d());
}
}
}
///////////////////////////////////////////////////////////////////////
//
// Clip edges of a prism by G4VoxelLimits box
//
G4bool
G4BoundingEnvelope::ClipEdgesByVoxelLimits(const std::vector<G4Segment3D>& pEdges,
const G4VoxelLimits& pBox,
G4Segment3D& pExtent) const
{
G4bool done = true;
G4Point3D emin = pExtent.first;
G4Point3D emax = pExtent.second;
G4int nedges = pEdges.size();
for (G4int k=0; k<nedges; k++)
{
G4double d1, d2;
G4Point3D p1 = pEdges[k].first;
G4Point3D p2 = pEdges[k].second;
// Clip current edge by X min
d1 = pBox.GetMinXExtent() - p1.x();
d2 = pBox.GetMinXExtent() - p2.x();
if (d1 > 0.0) {
if (d2 > 0.0) { done = false; continue; } // go to next edge
p1 = (p2*d1-p1*d2)/(d1-d2); // move p1
} else {
if (d2 > 0.0) { p2 = (p1*d2-p2*d1)/(d2-d1); } // move p2
}
// Clip current edge by X max
d1 = p1.x() - pBox.GetMaxXExtent();
d2 = p2.x() - pBox.GetMaxXExtent();
if (d1 > 0.) {
if (d2 > 0.) { done = false; continue; } // go to next edge
p1 = (p2*d1-p1*d2)/(d1-d2);
} else {
if (d2 > 0.) { p2 = (p1*d2-p2*d1)/(d2-d1); }
}
// Clip current edge by Y min
d1 = pBox.GetMinYExtent() - p1.y();
d2 = pBox.GetMinYExtent() - p2.y();
if (d1 > 0.) {
if (d2 > 0.) { done = false; continue; } // go to next edge
p1 = (p2*d1-p1*d2)/(d1-d2);
} else {
if (d2 > 0.) { p2 = (p1*d2-p2*d1)/(d2-d1); }
}
// Clip current edge by Y max
d1 = p1.y() - pBox.GetMaxYExtent();
d2 = p2.y() - pBox.GetMaxYExtent();
if (d1 > 0.) {
if (d2 > 0.) { done = false; continue; } // go to next edge
p1 = (p2*d1-p1*d2)/(d1-d2);
} else {
if (d2 > 0.) { p2 = (p1*d2-p2*d1)/(d2-d1); }
}
// Clip current edge by Z min
d1 = pBox.GetMinZExtent() - p1.z();
d2 = pBox.GetMinZExtent() - p2.z();
if (d1 > 0.) {
if (d2 > 0.) { done = false; continue; } // go to next edge
p1 = (p2*d1-p1*d2)/(d1-d2);
} else {
if (d2 > 0.) { p2 = (p1*d2-p2*d1)/(d2-d1); }
}
// Clip current edge by Z max
d1 = p1.z() - pBox.GetMaxZExtent();
d2 = p2.z() - pBox.GetMaxZExtent();
if (d1 > 0.) {
if (d2 > 0.) { done = false; continue; } // go to next edge
p1 = (p2*d1-p1*d2)/(d1-d2);
} else {
if (d2 > 0.) { p2 = (p1*d2-p2*d1)/(d2-d1); }
}
// Adjust current extent
emin.setX(std::min(std::min(p1.x(),p2.x()),emin.x()));
emin.setY(std::min(std::min(p1.y(),p2.y()),emin.y()));
emin.setZ(std::min(std::min(p1.z(),p2.z()),emin.z()));
emax.setX(std::max(std::max(p1.x(),p2.x()),emax.x()));
emax.setY(std::max(std::max(p1.y(),p2.y()),emax.y()));
emax.setZ(std::max(std::max(p1.z(),p2.z()),emax.z()));
}
// Return true if all edges (at least partially) are inside
// the voxel limits, otherwise return false
pExtent.first = emin;
pExtent.second = emax;
return done;
}
///////////////////////////////////////////////////////////////////////
//
// Clip G4VoxelLimits by set of planes bounding a convex prism
//
void
G4BoundingEnvelope::ClipVoxelLimitsByPlanes(const G4VoxelLimits& pBox,
const std::vector<G4Plane3D>& pPlanes,
const G4Segment3D& pAABB,
G4Segment3D& pExtent) const
{
G4Point3D emin = pExtent.first;
G4Point3D emax = pExtent.second;
// Create 12 edges of the voxel limits box, reduce them where
// appropriate to avoid calculations with big numbers (kInfinity)
//
G4double xmin = pBox.GetMinXExtent(), xmax = pBox.GetMaxXExtent();
G4double ymin = pBox.GetMinYExtent(), ymax = pBox.GetMaxYExtent();
G4double zmin = pBox.GetMinZExtent(), zmax = pBox.GetMaxZExtent();
if( xmin < 2.*pAABB.first.x() && xmax > 2.*pAABB.second.x())
{ xmin = 2.*pAABB.first.x(); xmax = 2.*pAABB.second.x(); }
if( ymin < 2.*pAABB.first.y() && ymax > 2.*pAABB.second.y())
{ ymin = 2.*pAABB.first.y(); ymax = 2.*pAABB.second.y(); }
if( zmin < 2.*pAABB.first.z() && zmax > 2.*pAABB.second.z())
{ zmin = 2.*pAABB.first.z(); zmax = 2.*pAABB.second.z(); }
std::vector<G4Segment3D> edges(12);
edges[0].first.set(xmin,ymin,zmin); edges[0].second.set(xmax,ymin,zmin);
edges[1].first = edges[0].second; edges[1].second.set(xmax,ymax,zmin);
edges[2].first = edges[1].second; edges[2].second.set(xmin,ymax,zmin);
edges[3].first = edges[2].second; edges[3].second = edges[0].first;
edges[4].first.set(xmin,ymin,zmax); edges[4].second.set(xmax,ymin,zmax);
edges[5].first = edges[4].second; edges[5].second.set(xmax,ymax,zmax);
edges[6].first = edges[5].second; edges[6].second.set(xmin,ymax,zmax);
edges[7].first = edges[6].second; edges[7].second = edges[4].first;
edges[ 8].first = edges[0].first; edges[ 8].second = edges[4].first;
edges[ 9].first = edges[1].first; edges[ 9].second = edges[5].first;
edges[10].first = edges[2].first; edges[10].second = edges[6].first;
edges[11].first = edges[3].first; edges[11].second = edges[7].first;
// Clip the edges by the planes
//
G4int nedges = edges.size();
G4int nplanes = pPlanes.size();
for (G4int k=0; k<nedges; k++)
{
G4Point3D p1 = edges[k].first;
G4Point3D p2 = edges[k].second;
G4bool exist = true;
for (G4int i=0; i<nplanes; i++) {
// Clip current edge
G4double d1 = pPlanes[i].distance(p1);
G4double d2 = pPlanes[i].distance(p2);
if (d1 > 0.0) {
if (d2 > 0.0) { exist = false; break; } // go to next edge
p1 = (p2*d1-p1*d2)/(d1-d2); // move p1
} else {
if (d2 > 0.0) { p2 = (p1*d2-p2*d1)/(d2-d1); } // move p2
}
}
// Adjust the extent
if (exist) {
emin.setX(std::min(std::min(p1.x(),p2.x()),emin.x()));
emin.setY(std::min(std::min(p1.y(),p2.y()),emin.y()));
emin.setZ(std::min(std::min(p1.z(),p2.z()),emin.z()));
emax.setX(std::max(std::max(p1.x(),p2.x()),emax.x()));
emax.setY(std::max(std::max(p1.y(),p2.y()),emax.y()));
emax.setZ(std::max(std::max(p1.z(),p2.z()),emax.z()));
}
}
// Copy the extent back
pExtent.first = emin;
pExtent.second = emax;
}
@@ -24,23 +24,24 @@
// ********************************************************************
//
//
// $Id: G4ReflectedSolid.cc 66356 2012-12-18 09:02:32Z gcosmo $
// $Id: G4ReflectedSolid.cc 97686 2016-06-07 09:27:32Z gcosmo $
//
//
// Implementation for G4ReflectedSolid class for boolean
// operations between other solids
// Implementation for G4ReflectedSolid class
//
// Author: Vladimir Grichine, 23.07.01 (Vladimir.Grichine@cern.ch)
//
// --------------------------------------------------------------------
#include "G4ReflectedSolid.hh"
#include "G4BoundingEnvelope.hh"
#include <sstream>
#include "G4Point3D.hh"
#include "G4Normal3D.hh"
#include "G4Vector3D.hh"
#include "G4AffineTransform.hh"
#include "G4VoxelLimits.hh"
#include "G4VPVParameterisation.hh"
@@ -48,27 +49,17 @@
#include "G4VGraphicsScene.hh"
#include "G4Polyhedron.hh"
/////////////////////////////////////////////////////////////////
//
// Constructor using HepTransform3D, in fact HepReflect3D
G4ReflectedSolid::G4ReflectedSolid( const G4String& pName,
G4VSolid* pSolid ,
const G4Transform3D& transform )
: G4VSolid(pName), fpPolyhedron(0)
const G4Transform3D& transform )
: G4VSolid(pName), fRebuildPolyhedron(false), fpPolyhedron(0)
{
fPtrSolid = pSolid ;
G4RotationMatrix rotMatrix ;
fDirectTransform =
new G4AffineTransform(rotMatrix, transform.getTranslation()) ;
fPtrTransform =
new G4AffineTransform(rotMatrix, transform.getTranslation()) ;
fPtrTransform->Invert() ;
fDirectTransform3D = new G4Transform3D(transform) ;
fPtrTransform3D = new G4Transform3D(transform.inverse()) ;
fPtrSolid = pSolid;
fDirectTransform3D = new G4Transform3D(transform);
}
///////////////////////////////////////////////////////////////////
@@ -76,28 +67,17 @@ G4ReflectedSolid::G4ReflectedSolid( const G4String& pName,
G4ReflectedSolid::~G4ReflectedSolid()
{
if(fPtrTransform)
{
delete fPtrTransform; fPtrTransform=0;
delete fDirectTransform; fDirectTransform=0;
}
if(fPtrTransform3D)
{
delete fPtrTransform3D; fPtrTransform3D=0;
delete fDirectTransform3D; fDirectTransform3D=0;
}
delete fpPolyhedron;
delete fDirectTransform3D; fDirectTransform3D=0;
delete fpPolyhedron; fpPolyhedron = 0;
}
///////////////////////////////////////////////////////////////////
//
G4ReflectedSolid::G4ReflectedSolid(const G4ReflectedSolid& rhs)
: G4VSolid(rhs), fPtrSolid(rhs.fPtrSolid), fpPolyhedron(0)
: G4VSolid(rhs), fPtrSolid(rhs.fPtrSolid),
fRebuildPolyhedron(false), fpPolyhedron(0)
{
fPtrTransform = new G4AffineTransform(*rhs.fPtrTransform);
fDirectTransform = new G4AffineTransform(*rhs.fDirectTransform);
fPtrTransform3D = new G4Transform3D(*rhs.fPtrTransform3D);
fDirectTransform3D = new G4Transform3D(*rhs.fDirectTransform3D);
}
@@ -116,15 +96,11 @@ G4ReflectedSolid& G4ReflectedSolid::operator=(const G4ReflectedSolid& rhs)
// Copy data
//
fPtrSolid= rhs.fPtrSolid; fpPolyhedron= 0;
delete fPtrTransform;
fPtrTransform= new G4AffineTransform(*rhs.fPtrTransform);
delete fDirectTransform;
fDirectTransform= new G4AffineTransform(*rhs.fDirectTransform);
delete fPtrTransform3D;
fPtrTransform3D= new G4Transform3D(*rhs.fPtrTransform3D);
fPtrSolid= rhs.fPtrSolid;
delete fDirectTransform3D;
fDirectTransform3D= new G4Transform3D(*rhs.fDirectTransform3D);
fRebuildPolyhedron = false;
delete fpPolyhedron; fpPolyhedron= 0;
return *this;
}
@@ -154,48 +130,11 @@ G4VSolid* G4ReflectedSolid::GetConstituentMovedSolid() const
/////////////////////////////////////////////////////////////////////////////
G4AffineTransform G4ReflectedSolid::GetTransform() const
{
G4AffineTransform aTransform = *fPtrTransform;
return aTransform;
}
void G4ReflectedSolid::SetTransform(G4AffineTransform& transform)
{
fPtrTransform = &transform ;
fpPolyhedron = 0;
}
//////////////////////////////////////////////////////////////////////////////
G4AffineTransform G4ReflectedSolid::GetDirectTransform() const
{
G4AffineTransform aTransform= *fDirectTransform;
return aTransform;
}
void G4ReflectedSolid::SetDirectTransform(G4AffineTransform& transform)
{
fDirectTransform = &transform ;
fpPolyhedron = 0;
}
/////////////////////////////////////////////////////////////////////////////
G4Transform3D G4ReflectedSolid::GetTransform3D() const
{
G4Transform3D aTransform = *fPtrTransform3D;
return aTransform;
return fDirectTransform3D->inverse();
}
void G4ReflectedSolid::SetTransform3D(G4Transform3D& transform)
{
fPtrTransform3D = &transform ;
fpPolyhedron = 0;
}
//////////////////////////////////////////////////////////////////////////////
G4Transform3D G4ReflectedSolid::GetDirectTransform3D() const
{
G4Transform3D aTransform= *fDirectTransform3D;
@@ -204,58 +143,8 @@ G4Transform3D G4ReflectedSolid::GetDirectTransform3D() const
void G4ReflectedSolid::SetDirectTransform3D(G4Transform3D& transform)
{
fDirectTransform3D = &transform ;
fpPolyhedron = 0;
}
/////////////////////////////////////////////////////////////////////////////
G4RotationMatrix G4ReflectedSolid::GetFrameRotation() const
{
G4RotationMatrix InvRotation= fDirectTransform->NetRotation();
return InvRotation;
}
void G4ReflectedSolid::SetFrameRotation(const G4RotationMatrix& matrix)
{
fDirectTransform->SetNetRotation(matrix);
}
/////////////////////////////////////////////////////////////////////////////
G4ThreeVector G4ReflectedSolid::GetFrameTranslation() const
{
return fPtrTransform->NetTranslation();
}
void G4ReflectedSolid::SetFrameTranslation(const G4ThreeVector& vector)
{
fPtrTransform->SetNetTranslation(vector);
}
///////////////////////////////////////////////////////////////
G4RotationMatrix G4ReflectedSolid::GetObjectRotation() const
{
G4RotationMatrix Rotation= fPtrTransform->NetRotation();
return Rotation;
}
void G4ReflectedSolid::SetObjectRotation(const G4RotationMatrix& matrix)
{
fPtrTransform->SetNetRotation(matrix);
}
///////////////////////////////////////////////////////////////////////
G4ThreeVector G4ReflectedSolid::GetObjectTranslation() const
{
return fDirectTransform->NetTranslation();
}
void G4ReflectedSolid::SetObjectTranslation(const G4ThreeVector& vector)
{
fDirectTransform->SetNetTranslation(vector);
fDirectTransform3D = &transform;
fRebuildPolyhedron = true;
}
///////////////////////////////////////////////////////////////
@@ -267,171 +156,36 @@ G4ReflectedSolid::CalculateExtent( const EAxis pAxis,
const G4VoxelLimits& pVoxelLimit,
const G4AffineTransform& pTransform,
G4double& pMin,
G4double& pMax ) const
G4double& pMax ) const
{
G4VoxelLimits unLimit;
G4AffineTransform unTransform;
G4double x1 = -kInfinity, x2 = kInfinity,
y1 = -kInfinity, y2 = kInfinity,
z1 = -kInfinity, z2 = kInfinity;
// Find bounding box
G4double x1,x2,y1,y2,z1,z2;
fPtrSolid->CalculateExtent(kXAxis,unLimit,unTransform,x1,x2);
fPtrSolid->CalculateExtent(kYAxis,unLimit,unTransform,y1,y2);
fPtrSolid->CalculateExtent(kZAxis,unLimit,unTransform,z1,z2);
G4BoundingEnvelope bbox(G4Point3D(x1,y1,z1),
G4Point3D(x2,y2,z2),kCarTolerance);
G4bool existsAfterClip = false ;
existsAfterClip =
fPtrSolid->CalculateExtent(kXAxis,unLimit,unTransform,x1,x2);
existsAfterClip =
fPtrSolid->CalculateExtent(kYAxis,unLimit,unTransform,y1,y2);
existsAfterClip =
fPtrSolid->CalculateExtent(kZAxis,unLimit,unTransform,z1,z2);
// Set combined transformation
G4Transform3D transform3D =
G4Transform3D(pTransform.NetRotation().inverse(),
pTransform.NetTranslation())*(*fDirectTransform3D);
existsAfterClip = false;
pMin = +kInfinity ;
pMax = -kInfinity ;
G4Transform3D pTransform3D = G4Transform3D(pTransform.NetRotation().inverse(),
pTransform.NetTranslation());
G4Transform3D transform3D = pTransform3D*(*fDirectTransform3D);
G4Point3D tmpPoint;
// Calculate rotated vertex coordinates
G4ThreeVectorList* vertices = new G4ThreeVectorList();
if (vertices)
{
vertices->reserve(8);
G4ThreeVector vertex0(x1,y1,z1) ;
tmpPoint = transform3D*G4Point3D(vertex0);
vertex0 = G4ThreeVector(tmpPoint.x(),tmpPoint.y(),tmpPoint.z());
vertices->push_back(vertex0);
G4ThreeVector vertex1(x2,y1,z1) ;
tmpPoint = transform3D*G4Point3D(vertex1);
vertex1 = G4ThreeVector(tmpPoint.x(),tmpPoint.y(),tmpPoint.z());
vertices->push_back(vertex1);
G4ThreeVector vertex2(x2,y2,z1) ;
tmpPoint = transform3D*G4Point3D(vertex2);
vertex2 = G4ThreeVector(tmpPoint.x(),tmpPoint.y(),tmpPoint.z());
vertices->push_back(vertex2);
G4ThreeVector vertex3(x1,y2,z1) ;
tmpPoint = transform3D*G4Point3D(vertex3);
vertex3 = G4ThreeVector(tmpPoint.x(),tmpPoint.y(),tmpPoint.z());
vertices->push_back(vertex3);
G4ThreeVector vertex4(x1,y1,z2) ;
tmpPoint = transform3D*G4Point3D(vertex4);
vertex4 = G4ThreeVector(tmpPoint.x(),tmpPoint.y(),tmpPoint.z());
vertices->push_back(vertex4);
G4ThreeVector vertex5(x2,y1,z2) ;
tmpPoint = transform3D*G4Point3D(vertex5);
vertex5 = G4ThreeVector(tmpPoint.x(),tmpPoint.y(),tmpPoint.z());
vertices->push_back(vertex5);
G4ThreeVector vertex6(x2,y2,z2) ;
tmpPoint = transform3D*G4Point3D(vertex6);
vertex6 = G4ThreeVector(tmpPoint.x(),tmpPoint.y(),tmpPoint.z());
vertices->push_back(vertex6);
G4ThreeVector vertex7(x1,y2,z2) ;
tmpPoint = transform3D*G4Point3D(vertex7);
vertex7 = G4ThreeVector(tmpPoint.x(),tmpPoint.y(),tmpPoint.z());
vertices->push_back(vertex7);
}
else
{
DumpInfo();
G4Exception("G4ReflectedSolid::CalculateExtent()",
"GeomMgt0003", FatalException,
"Error in allocation of vertices. Out of memory !");
}
ClipCrossSection(vertices,0,pVoxelLimit,pAxis,pMin,pMax) ;
ClipCrossSection(vertices,4,pVoxelLimit,pAxis,pMin,pMax) ;
ClipBetweenSections(vertices,0,pVoxelLimit,pAxis,pMin,pMax) ;
if (pVoxelLimit.IsLimited(pAxis) == false)
{
if ( pMin != kInfinity || pMax != -kInfinity )
{
existsAfterClip = true ;
// Add 2*tolerance to avoid precision troubles
pMin -= kCarTolerance;
pMax += kCarTolerance;
}
}
else
{
G4ThreeVector clipCentre(
( pVoxelLimit.GetMinXExtent()+pVoxelLimit.GetMaxXExtent())*0.5,
( pVoxelLimit.GetMinYExtent()+pVoxelLimit.GetMaxYExtent())*0.5,
( pVoxelLimit.GetMinZExtent()+pVoxelLimit.GetMaxZExtent())*0.5);
if ( pMin != kInfinity || pMax != -kInfinity )
{
existsAfterClip = true ;
// Check to see if endpoints are in the solid
clipCentre(pAxis) = pVoxelLimit.GetMinExtent(pAxis);
if (Inside(transform3D.inverse()*G4Point3D(clipCentre)) != kOutside)
{
pMin = pVoxelLimit.GetMinExtent(pAxis);
}
else
{
pMin -= kCarTolerance;
}
clipCentre(pAxis) = pVoxelLimit.GetMaxExtent(pAxis);
if (Inside(transform3D.inverse()*G4Point3D(clipCentre)) != kOutside)
{
pMax = pVoxelLimit.GetMaxExtent(pAxis);
}
else
{
pMax += kCarTolerance;
}
}
// Check for case where completely enveloping clipping volume
// If point inside then we are confident that the solid completely
// envelopes the clipping volume. Hence set min/max extents according
// to clipping volume extents along the specified axis.
else if (Inside(transform3D.inverse()*G4Point3D(clipCentre)) != kOutside)
{
existsAfterClip = true ;
pMin = pVoxelLimit.GetMinExtent(pAxis) ;
pMax = pVoxelLimit.GetMaxExtent(pAxis) ;
}
}
delete vertices;
return existsAfterClip;
// Find extent
return bbox.CalculateExtent(pAxis,pVoxelLimit,transform3D,pMin,pMax);
}
/////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
//
//
EInside G4ReflectedSolid::Inside(const G4ThreeVector& p) const
EInside G4ReflectedSolid::Inside(const G4ThreeVector& p ) const
{
G4Point3D newPoint = (*fDirectTransform3D)*G4Point3D(p) ;
// G4Point3D newPoint = (*fPtrTransform3D)*G4Point3D(p) ;
return fPtrSolid->Inside(G4ThreeVector(newPoint.x(),
newPoint.y(),
newPoint.z())) ;
G4ThreeVector newPoint = (*fDirectTransform3D)*G4Point3D(p);
return fPtrSolid->Inside(newPoint);
}
//////////////////////////////////////////////////////////////
@@ -441,15 +195,9 @@ EInside G4ReflectedSolid::Inside(const G4ThreeVector& p) const
G4ThreeVector
G4ReflectedSolid::SurfaceNormal( const G4ThreeVector& p ) const
{
G4Point3D newPoint = (*fDirectTransform3D)*G4Point3D(p) ;
G4ThreeVector normal =
fPtrSolid->SurfaceNormal(G4ThreeVector(newPoint.x(),
newPoint.y(),
newPoint.z() ) ) ;
G4Point3D newN = (*fDirectTransform3D)*G4Point3D(normal) ;
newN.unit() ;
return G4ThreeVector(newN.x(),newN.y(),newN.z()) ;
G4ThreeVector newPoint = (*fDirectTransform3D)*G4Point3D(p);
G4Vector3D normal = fPtrSolid->SurfaceNormal(newPoint);
return (*fDirectTransform3D)*normal;
}
/////////////////////////////////////////////////////////////
@@ -458,14 +206,11 @@ G4ReflectedSolid::SurfaceNormal( const G4ThreeVector& p ) const
G4double
G4ReflectedSolid::DistanceToIn( const G4ThreeVector& p,
const G4ThreeVector& v ) const
const G4ThreeVector& v ) const
{
G4Point3D newPoint = (*fDirectTransform3D)*G4Point3D(p) ;
G4Point3D newDirection = (*fDirectTransform3D)*G4Point3D(v) ;
newDirection.unit() ;
return fPtrSolid->DistanceToIn(
G4ThreeVector(newPoint.x(),newPoint.y(),newPoint.z()),
G4ThreeVector(newDirection.x(),newDirection.y(),newDirection.z())) ;
G4ThreeVector newPoint = (*fDirectTransform3D)*G4Point3D(p);
G4ThreeVector newDirection = (*fDirectTransform3D)*G4Vector3D(v);
return fPtrSolid->DistanceToIn(newPoint,newDirection);
}
////////////////////////////////////////////////////////
@@ -474,11 +219,10 @@ G4ReflectedSolid::DistanceToIn( const G4ThreeVector& p,
// two solids
G4double
G4ReflectedSolid::DistanceToIn( const G4ThreeVector& p) const
G4ReflectedSolid::DistanceToIn( const G4ThreeVector& p ) const
{
G4Point3D newPoint = (*fDirectTransform3D)*G4Point3D(p) ;
return fPtrSolid->DistanceToIn(
G4ThreeVector(newPoint.x(),newPoint.y(),newPoint.z())) ;
G4ThreeVector newPoint = (*fDirectTransform3D)*G4Point3D(p);
return fPtrSolid->DistanceToIn(newPoint);
}
//////////////////////////////////////////////////////////
@@ -490,26 +234,20 @@ G4ReflectedSolid::DistanceToOut( const G4ThreeVector& p,
const G4ThreeVector& v,
const G4bool calcNorm,
G4bool *validNorm,
G4ThreeVector *n ) const
G4ThreeVector *n ) const
{
G4ThreeVector solNorm ;
G4ThreeVector solNorm;
G4Point3D newPoint = (*fDirectTransform3D)*G4Point3D(p) ;
G4Point3D newDirection = (*fDirectTransform3D)*G4Point3D(v);
newDirection.unit() ;
G4ThreeVector newPoint = (*fDirectTransform3D)*G4Point3D(p);
G4ThreeVector newDirection = (*fDirectTransform3D)*G4Vector3D(v);
G4double dist =
fPtrSolid->DistanceToOut(
G4ThreeVector(newPoint.x(),newPoint.y(),newPoint.z()),
G4ThreeVector(newDirection.x(),newDirection.y(),newDirection.z()),
calcNorm, validNorm, &solNorm) ;
G4double dist = fPtrSolid->DistanceToOut(newPoint, newDirection,
calcNorm, validNorm, &solNorm);
if(calcNorm)
{
G4Point3D newN = (*fDirectTransform3D)*G4Point3D(solNorm);
newN.unit() ;
*n = G4ThreeVector(newN.x(),newN.y(),newN.z());
*n = (*fDirectTransform3D)*G4Vector3D(solNorm);
}
return dist ;
return dist;
}
//////////////////////////////////////////////////////////////
@@ -519,9 +257,8 @@ G4ReflectedSolid::DistanceToOut( const G4ThreeVector& p,
G4double
G4ReflectedSolid::DistanceToOut( const G4ThreeVector& p ) const
{
G4Point3D newPoint = (*fDirectTransform3D)*G4Point3D(p);
return fPtrSolid->DistanceToOut(
G4ThreeVector(newPoint.x(),newPoint.y(),newPoint.z()));
G4ThreeVector newPoint = (*fDirectTransform3D)*G4Point3D(p);
return fPtrSolid->DistanceToOut(newPoint);
}
//////////////////////////////////////////////////////////////
@@ -546,10 +283,8 @@ G4ReflectedSolid::ComputeDimensions( G4VPVParameterisation*,
G4ThreeVector G4ReflectedSolid::GetPointOnSurface() const
{
G4ThreeVector p = fPtrSolid->GetPointOnSurface();
G4Point3D newPoint = (*fDirectTransform3D)*G4Point3D(p);
return G4ThreeVector(newPoint.x(),newPoint.y(),newPoint.z());
G4ThreeVector p = fPtrSolid->GetPointOnSurface();
return (*fDirectTransform3D)*G4Point3D(p);
}
//////////////////////////////////////////////////////////////////////////
@@ -578,10 +313,10 @@ std::ostream& G4ReflectedSolid::StreamInfo(std::ostream& os) const
os << "===========================================================\n"
<< " Transformations: \n"
<< " Direct transformation - translation : \n"
<< " " << fDirectTransform->NetTranslation() << "\n"
<< " " << fDirectTransform3D->getTranslation() << "\n"
<< " - rotation : \n"
<< " ";
fDirectTransform->NetRotation().print(os);
fDirectTransform3D->getRotation().print(os);
os << "\n"
<< "===========================================================\n";
@@ -631,11 +366,12 @@ G4Polyhedron*
G4ReflectedSolid::GetPolyhedron () const
{
if (!fpPolyhedron ||
fRebuildPolyhedron ||
fpPolyhedron->GetNumberOfRotationStepsAtTimeOfCreation() !=
fpPolyhedron->GetNumberOfRotationSteps())
{
delete fpPolyhedron;
fpPolyhedron = CreatePolyhedron ();
fpPolyhedron = CreatePolyhedron();
fRebuildPolyhedron = false;
}
return fpPolyhedron;
}
+28 -122
View File
@@ -34,15 +34,15 @@
#include "G4USolid.hh"
#if defined(G4GEOM_USE_USOLIDS)
#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
#include "G4AffineTransform.hh"
#include "G4VoxelLimits.hh"
#include "G4VGraphicsScene.hh"
#include "G4Polyhedron.hh"
#include "G4PolyhedronArbitrary.hh"
#include "G4VisExtent.hh"
#include "G4PhysicalConstants.hh"
#include "G4GeometryTolerance.hh"
#include "G4AutoLock.hh"
@@ -82,13 +82,8 @@ EInside G4USolid::Inside(const G4ThreeVector& p) const
in_temp = fShape->Inside(pt);
#ifndef G4USE_STD11
if (in_temp == VUSolid::eSurface)return kSurface;
if (in_temp == VUSolid::eInside)return kInside;
#else
if (in_temp == VUSolid::EnumInside::eSurface)return kSurface;
if (in_temp == VUSolid::EnumInside::eInside)return kInside;
#endif
if (in_temp == VUSolid::EnumInside::eSurface) return kSurface;
if (in_temp == VUSolid::EnumInside::eInside) return kInside;
return in;
}
@@ -105,7 +100,7 @@ G4ThreeVector G4USolid::SurfaceNormal(const G4ThreeVector& pt) const
}
G4double G4USolid::DistanceToIn(const G4ThreeVector& pt,
const G4ThreeVector& d)const
const G4ThreeVector& d) const
{
UVector3 p;
p.x() = pt.x();
@@ -116,7 +111,8 @@ G4double G4USolid::DistanceToIn(const G4ThreeVector& pt,
v.y() = d.y();
v.z() = d.z(); // better assign at construction
G4double dist = fShape->DistanceToIn(p, v);
if (dist > kInfinity) dist = kInfinity;
if (dist > kInfinity) return kInfinity;
// return (dist > halfTolerance) ? dist : 0.0;
return dist;
}
@@ -127,7 +123,8 @@ G4double G4USolid::DistanceToIn(const G4ThreeVector& pt) const
p.y() = pt.y();
p.z() = pt.z(); // better assign at construction
G4double dist = fShape->SafetyFromOutside(p); // true?
if (dist > kInfinity) dist = kInfinity;
if (dist > kInfinity) return kInfinity;
// return (dist > halfTolerance) ? dist : 0.0;
return dist;
}
@@ -146,19 +143,21 @@ G4double G4USolid::DistanceToOut(const G4ThreeVector& pt,
v.y() = d.y();
v.z() = d.z(); // better assign at construction
UVector3 n;
bool valid;
G4double dist = fShape->DistanceToOut(p, v, n,valid); // should use local variable
G4bool valid;
G4double dist = fShape->DistanceToOut(p, v, n, valid); // should use local variable
if(calcNorm)
{
if(valid){ *validNorm = true;}
else {* validNorm =false;}
if(*validNorm)
{ norm->setX(n.x());
if(valid){ *validNorm = true; }
else { *validNorm = false; }
if(*validNorm) // *norm = n, but only after calcNorm check
{
norm->setX(n.x());
norm->setY(n.y());
norm->setZ(n.z());
} // *norm = n, but only after calcNorm check
}
}
if (dist > kInfinity) dist = kInfinity;
if (dist > kInfinity) return kInfinity;
// return (dist > halfTolerance) ? dist : 0.0;
return dist;
}
@@ -168,7 +167,9 @@ G4double G4USolid::DistanceToOut(const G4ThreeVector& pt) const
p.x() = pt.x();
p.y() = pt.y();
p.z() = pt.z(); // better assign at construction
return fShape->SafetyFromInside(p); // true?
G4double dist = fShape->SafetyFromInside(p); // true?
// return (dist > halfTolerance) ? dist : 0.0;
return dist;
}
G4double G4USolid::GetCubicVolume()
@@ -452,108 +453,13 @@ G4USolid::CreateRotatedVertices(const G4AffineTransform& pTransform) const
G4Polyhedron* G4USolid::CreatePolyhedron() const
{
G4int index = 0;
if (fShape->GetEntityType() == "Box")
{
double array[3];
fShape->GetParametersList(index, array);
return new G4PolyhedronBox(array[0], array[1], array[2]);
}
if (fShape->GetEntityType() == "Tubs")
{
double array[5];
fShape->GetParametersList(index, array);
return new G4PolyhedronTubs(array[0], array[1], array[2], array[3], array[4]);
}
if (fShape->GetEntityType() == "Cons")
{
double array[7];
fShape->GetParametersList(index, array);
return new G4PolyhedronCons(array[0], array[1], array[2], array[3], array[4], array[5], array[6]);
}
if (fShape->GetEntityType() == "Orb")
{
double array[1];
fShape->GetParametersList(index, array);
return new G4PolyhedronSphere(0., array[0], 0., 2 * pi, 0., pi);
}
if (fShape->GetEntityType() == "Sphere")
{
double array[6];
fShape->GetParametersList(index, array);
return new G4PolyhedronSphere(array[0], array[1], array[2], array[3], array[4], array[5]);
}
if (fShape->GetEntityType() == "Tet")
{
double array[12];
fShape->GetParametersList(index, array);
G4Polyhedron* ph = new G4Polyhedron;
double xyz[4][3];
static int faces[4][4] = {{1, 3, 2, 0}, {1, 4, 3, 0}, {1, 2, 4, 0}, {2, 3, 4, 0}};
xyz[0][0] = array[0];
xyz[0][1] = array[1];
xyz[0][2] = array[2];
xyz[1][0] = array[3];
xyz[1][1] = array[4];
xyz[1][2] = array[5];
xyz[2][0] = array[6];
xyz[2][1] = array[7];
xyz[2][2] = array[8];
xyz[3][0] = array[9];
xyz[3][1] = array[10];
xyz[3][2] = array[11];
ph->createPolyhedron(4, 4, xyz, faces);
return ph;
}
if (fShape->GetEntityType() == "Trd")
{
double array[5];
fShape->GetParametersList(index, array);
return new G4PolyhedronTrd2(array[0], array[1], array[2], array[3], array[4]);
}
if (fShape->GetEntityType() == "Trap")
{
double array[12];
fShape->GetParametersList(index, array);
double phi = (array[11] != 1.0) ? (std::atan(array[10] / array[9])) : (0.0);
double alpha1 = std::atan(array[4]);
double alpha2 = std::atan(array[8]);
double theta = std::acos(array[11]);
return new G4PolyhedronTrap(array[0], theta, phi,
array[1], array[2], array[3], alpha1,
array[5], array[6], array[7], alpha2);
}
/*
if(fShape->GetEntityType()=="TessellatedSolid"){
G4Polyhedron *uPolyhedron=fShape->GetPolyhedron();
std::size_t nVertices = (*uPolyhedron).vertices.size();
std::size_t nFacets = (*uPolyhedron).facets.size();
G4PolyhedronArbitrary *polyhedron =
new G4PolyhedronArbitrary (nVertices, nFacets);
for (std::vector<UVector3>::const_iterator v = (*uPolyhedron).vertices.begin();
v!=(*uPolyhedron).vertices.end(); v++)
{
UVector3 p=(*v);
G4ThreeVector pt(p.x(),p.y(),p.z());
polyhedron->AddVertex(pt);
}
for (std::vector<UFacet>::const_iterator f=(*uPolyhedron).facets.begin();
f != (*uPolyhedron).facets.end(); f++)
{
polyhedron->AddFacet((*f).f1,(*f).f2,(*f).f3,(*f).f4);
}
return (G4Polyhedron*) polyhedron;
}
*/
// Must be implemented in concrete wrappers...
std::ostringstream message;
message << "Visualization not supported for USolid shape "
<< GetEntityType() << "... Sorry!" << G4endl;
G4Exception("G4USolid::CreatePolyhedron()", "GeomSolids0003",
FatalException, message);
return 0;
}