Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
HepPolyhedron Class Reference

#include <HepPolyhedron.h>

+ Inheritance diagram for HepPolyhedron:

Public Member Functions

 HepPolyhedron ()
 
 HepPolyhedron (G4int Nvert, G4int Nface)
 
 HepPolyhedron (const HepPolyhedron &from)
 
 HepPolyhedron (HepPolyhedron &&from)
 
virtual ~HepPolyhedron ()
 
HepPolyhedronoperator= (const HepPolyhedron &from)
 
HepPolyhedronoperator= (HepPolyhedron &&from)
 
G4int GetNoVertices () const
 
G4int GetNoVerteces () const
 
G4int GetNoFacets () const
 
HepPolyhedronTransform (const G4Transform3D &t)
 
G4bool GetNextVertexIndex (G4int &index, G4int &edgeFlag) const
 
G4Point3D GetVertex (G4int index) const
 
G4bool GetNextVertex (G4Point3D &vertex, G4int &edgeFlag) const
 
G4bool GetNextVertex (G4Point3D &vertex, G4int &edgeFlag, G4Normal3D &normal) const
 
G4bool GetNextEdgeIndices (G4int &i1, G4int &i2, G4int &edgeFlag, G4int &iface1, G4int &iface2) const
 
G4bool GetNextEdgeIndeces (G4int &i1, G4int &i2, G4int &edgeFlag, G4int &iface1, G4int &iface2) const
 
G4bool GetNextEdgeIndices (G4int &i1, G4int &i2, G4int &edgeFlag) const
 
G4bool GetNextEdgeIndeces (G4int &i1, G4int &i2, G4int &edgeFlag) const
 
G4bool GetNextEdge (G4Point3D &p1, G4Point3D &p2, G4int &edgeFlag) const
 
G4bool GetNextEdge (G4Point3D &p1, G4Point3D &p2, G4int &edgeFlag, G4int &iface1, G4int &iface2) const
 
void GetFacet (G4int iFace, G4int &n, G4int *iNodes, G4int *edgeFlags=nullptr, G4int *iFaces=nullptr) const
 
void GetFacet (G4int iFace, G4int &n, G4Point3D *nodes, G4int *edgeFlags=nullptr, G4Normal3D *normals=nullptr) const
 
G4bool GetNextFacet (G4int &n, G4Point3D *nodes, G4int *edgeFlags=nullptr, G4Normal3D *normals=nullptr) const
 
G4Normal3D GetNormal (G4int iFace) const
 
G4Normal3D GetUnitNormal (G4int iFace) const
 
G4bool GetNextNormal (G4Normal3D &normal) const
 
G4bool GetNextUnitNormal (G4Normal3D &normal) const
 
HepPolyhedron add (const HepPolyhedron &p) const
 
HepPolyhedron subtract (const HepPolyhedron &p) const
 
HepPolyhedron intersect (const HepPolyhedron &p) const
 
G4double GetSurfaceArea () const
 
G4double GetVolume () const
 
void SetVertex (G4int index, const G4Point3D &v)
 
void SetFacet (G4int index, G4int iv1, G4int iv2, G4int iv3, G4int iv4=0)
 
void SetReferences ()
 
void JoinCoplanarFacets (G4double tolerance)
 
void InvertFacets ()
 
G4int createTwistedTrap (G4double Dz, const G4double xy1[][2], const G4double xy2[][2])
 
G4int createPolyhedron (G4int Nnodes, G4int Nfaces, const G4double xyz[][3], const G4int faces[][4])
 
G4Point3D vertexUnweightedMean () const
 

Static Public Member Functions

static G4int GetNumberOfRotationSteps ()
 
static void SetNumberOfRotationSteps (G4int n)
 
static void ResetNumberOfRotationSteps ()
 

Protected Member Functions

void AllocateMemory (G4int Nvert, G4int Nface)
 
G4int FindNeighbour (G4int iFace, G4int iNode, G4int iOrder) const
 
G4Normal3D FindNodeNormal (G4int iFace, G4int iNode) const
 
void CreatePrism ()
 
void RotateEdge (G4int k1, G4int k2, G4double r1, G4double r2, G4int v1, G4int v2, G4int vEdge, G4bool ifWholeCircle, G4int ns, G4int &kface)
 
void SetSideFacets (G4int ii[4], G4int vv[4], G4int *kk, G4double *r, G4double dphi, G4int ns, G4int &kface)
 
void RotateAroundZ (G4int nstep, G4double phi, G4double dphi, G4int np1, G4int np2, const G4double *z, G4double *r, G4int nodeVis, G4int edgeVis)
 
void RotateContourAroundZ (G4int nstep, G4double phi, G4double dphi, const std::vector< G4TwoVector > &rz, G4int nodeVis, G4int edgeVis)
 
G4bool TriangulatePolygon (const std::vector< G4TwoVector > &polygon, std::vector< G4int > &result)
 
G4bool CheckSnip (const std::vector< G4TwoVector > &contour, G4int a, G4int b, G4int c, G4int n, const G4int *V)
 

Protected Attributes

G4int nvert
 
G4int nface
 
G4Point3DpV
 
G4FacetpF
 

Static Protected Attributes

static G4ThreadLocal G4int fNumberOfRotationSteps = DEFAULT_NUMBER_OF_STEPS
 

Friends

std::ostream & operator<< (std::ostream &ostr, const HepPolyhedron &ph)
 

Detailed Description

Definition at line 231 of file HepPolyhedron.h.

Constructor & Destructor Documentation

◆ HepPolyhedron() [1/4]

HepPolyhedron::HepPolyhedron ( )
inline

Definition at line 284 of file HepPolyhedron.h.

284: nvert(0), nface(0), pV(nullptr), pF(nullptr) {}
G4Point3D * pV

◆ HepPolyhedron() [2/4]

HepPolyhedron::HepPolyhedron ( G4int Nvert,
G4int Nface )

Definition at line 120 of file HepPolyhedron.cc.

128: nvert(0), nface(0), pV(nullptr), pF(nullptr)
129{
130 AllocateMemory(Nvert, Nface);
131}
void AllocateMemory(G4int Nvert, G4int Nface)

◆ HepPolyhedron() [3/4]

HepPolyhedron::HepPolyhedron ( const HepPolyhedron & from)

Definition at line 133 of file HepPolyhedron.cc.

140: nvert(0), nface(0), pV(nullptr), pF(nullptr)
141{
142 AllocateMemory(from.nvert, from.nface);
143 for (G4int i=1; i<=nvert; i++) pV[i] = from.pV[i];
144 for (G4int k=1; k<=nface; k++) pF[k] = from.pF[k];
145}
int G4int
Definition G4Types.hh:85

◆ HepPolyhedron() [4/4]

HepPolyhedron::HepPolyhedron ( HepPolyhedron && from)

Definition at line 147 of file HepPolyhedron.cc.

154: nvert(0), nface(0), pV(nullptr), pF(nullptr)
155{
156 nvert = from.nvert;
157 nface = from.nface;
158 pV = from.pV;
159 pF = from.pF;
160
161 // Release the data from the source object
162 from.nvert = 0;
163 from.nface = 0;
164 from.pV = nullptr;
165 from.pF = nullptr;
166}

◆ ~HepPolyhedron()

virtual HepPolyhedron::~HepPolyhedron ( )
inlinevirtual

Definition at line 296 of file HepPolyhedron.h.

296{ delete [] pV; delete [] pF; }

Member Function Documentation

◆ add()

HepPolyhedron HepPolyhedron::add ( const HepPolyhedron & p) const

Definition at line 3361 of file HepPolyhedron.cc.

3370{
3371 G4int ierr;
3372 BooleanProcessor processor;
3373 return processor.execute(OP_UNION, *this, p,ierr);
3374}

◆ AllocateMemory()

void HepPolyhedron::AllocateMemory ( G4int Nvert,
G4int Nface )
protected

◆ CheckSnip()

G4bool HepPolyhedron::CheckSnip ( const std::vector< G4TwoVector > & contour,
G4int a,
G4int b,
G4int c,
G4int n,
const G4int * V )
protected

Definition at line 1063 of file HepPolyhedron.cc.

1075{
1076 static const G4double kCarTolerance = 1.e-9;
1077
1078 // check orientation of Triangle
1079 G4double Ax = contour[V[a]].x(), Ay = contour[V[a]].y();
1080 G4double Bx = contour[V[b]].x(), By = contour[V[b]].y();
1081 G4double Cx = contour[V[c]].x(), Cy = contour[V[c]].y();
1082 if ((Bx-Ax)*(Cy-Ay) - (By-Ay)*(Cx-Ax) < kCarTolerance) return false;
1083
1084 // check that there is no point inside Triangle
1085 G4double xmin = std::min(std::min(Ax,Bx),Cx);
1086 G4double xmax = std::max(std::max(Ax,Bx),Cx);
1087 G4double ymin = std::min(std::min(Ay,By),Cy);
1088 G4double ymax = std::max(std::max(Ay,By),Cy);
1089
1090 for (G4int i=0; i<n; ++i)
1091 {
1092 if((i == a) || (i == b) || (i == c)) continue;
1093 G4double Px = contour[V[i]].x();
1094 if (Px < xmin || Px > xmax) continue;
1095 G4double Py = contour[V[i]].y();
1096 if (Py < ymin || Py > ymax) continue;
1097 // if (PointInTriangle(Ax,Ay,Bx,By,Cx,Cy,Px,Py)) return false;
1098 if ((Bx-Ax)*(Cy-Ay) - (By-Ay)*(Cx-Ax) > 0.)
1099 {
1100 if ((Ax-Cx)*(Py-Cy) - (Ay-Cy)*(Px-Cx) < 0.) continue;
1101 if ((Bx-Ax)*(Py-Ay) - (By-Ay)*(Px-Ax) < 0.) continue;
1102 if ((Cx-Bx)*(Py-By) - (Cy-By)*(Px-Bx) < 0.) continue;
1103 }
1104 else
1105 {
1106 if ((Ax-Cx)*(Py-Cy) - (Ay-Cy)*(Px-Cx) > 0.) continue;
1107 if ((Bx-Ax)*(Py-Ay) - (By-Ay)*(Px-Ax) > 0.) continue;
1108 if ((Cx-Bx)*(Py-By) - (Cy-By)*(Px-Bx) > 0.) continue;
1109 }
1110 return false;
1111 }
1112 return true;
1113}
const G4double kCarTolerance
double G4double
Definition G4Types.hh:83

Referenced by TriangulatePolygon().

◆ createPolyhedron()

G4int HepPolyhedron::createPolyhedron ( G4int Nnodes,
G4int Nfaces,
const G4double xyz[][3],
const G4int faces[][4] )

Creates user defined polyhedron. This function allows to the user to define arbitrary polyhedron. The faces of the polyhedron should be either triangles or planar quadrilateral. Nodes of a face are defined by indexes pointing to the elements in the xyz array. Numeration of the elements in the array starts from 1 (like in fortran). The indexes can be positive or negative. Negative sign means that the corresponding edge is invisible. The normal of the face should be directed to exterior of the polyhedron.

Parameters
Nnodesnumber of nodes
Nfacesnumber of faces
xyznodes
facesfaces (quadrilaterals or triangles)
Returns
status of the operation - is non-zero in case of problem

Definition at line 1902 of file HepPolyhedron.cc.

1918{
1919 AllocateMemory(Nnodes, Nfaces);
1920 if (nvert == 0) return 1;
1921
1922 for (G4int i=0; i<Nnodes; i++) {
1923 pV[i+1] = G4Point3D(xyz[i][0], xyz[i][1], xyz[i][2]);
1924 }
1925 for (G4int k=0; k<Nfaces; k++) {
1926 pF[k+1] = G4Facet(faces[k][0],0,faces[k][1],0,faces[k][2],0,faces[k][3],0);
1927 }
1928 SetReferences();
1929 return 0;
1930}
HepGeom::Point3D< G4double > G4Point3D
Definition G4Point3D.hh:34

Referenced by G4Tet::CreatePolyhedron().

◆ CreatePrism()

void HepPolyhedron::CreatePrism ( )
protected

Definition at line 400 of file HepPolyhedron.cc.

409{
410 enum {DUMMY, BOTTOM, LEFT, BACK, RIGHT, FRONT, TOP};
411
412 pF[1] = G4Facet(1,LEFT, 4,BACK, 3,RIGHT, 2,FRONT);
413 pF[2] = G4Facet(5,TOP, 8,BACK, 4,BOTTOM, 1,FRONT);
414 pF[3] = G4Facet(8,TOP, 7,RIGHT, 3,BOTTOM, 4,LEFT);
415 pF[4] = G4Facet(7,TOP, 6,FRONT, 2,BOTTOM, 3,BACK);
416 pF[5] = G4Facet(6,TOP, 5,LEFT, 1,BOTTOM, 2,RIGHT);
417 pF[6] = G4Facet(5,FRONT, 6,RIGHT, 7,BACK, 8,LEFT);
418}

Referenced by HepPolyhedronTrap::HepPolyhedronTrap(), and HepPolyhedronTrd2::HepPolyhedronTrd2().

◆ createTwistedTrap()

G4int HepPolyhedron::createTwistedTrap ( G4double Dz,
const G4double xy1[][2],
const G4double xy2[][2] )

Creates polyhedron for twisted trapezoid. The trapezoid is given by two bases perpendicular to the z-axis.

Parameters
Dzhalf length in z
xy11st base (at z = -Dz)
xy22nd base (at z = +Dz)
Returns
status of the operation - is non-zero in case of problem

Definition at line 1833 of file HepPolyhedron.cc.

1849{
1850 AllocateMemory(12,18);
1851
1852 pV[ 1] = G4Point3D(xy1[0][0],xy1[0][1],-Dz);
1853 pV[ 2] = G4Point3D(xy1[1][0],xy1[1][1],-Dz);
1854 pV[ 3] = G4Point3D(xy1[2][0],xy1[2][1],-Dz);
1855 pV[ 4] = G4Point3D(xy1[3][0],xy1[3][1],-Dz);
1856
1857 pV[ 5] = G4Point3D(xy2[0][0],xy2[0][1], Dz);
1858 pV[ 6] = G4Point3D(xy2[1][0],xy2[1][1], Dz);
1859 pV[ 7] = G4Point3D(xy2[2][0],xy2[2][1], Dz);
1860 pV[ 8] = G4Point3D(xy2[3][0],xy2[3][1], Dz);
1861
1862 pV[ 9] = (pV[1]+pV[2]+pV[5]+pV[6])/4.;
1863 pV[10] = (pV[2]+pV[3]+pV[6]+pV[7])/4.;
1864 pV[11] = (pV[3]+pV[4]+pV[7]+pV[8])/4.;
1865 pV[12] = (pV[4]+pV[1]+pV[8]+pV[5])/4.;
1866
1867 enum {DUMMY, BOTTOM,
1868 LEFT_BOTTOM, LEFT_FRONT, LEFT_TOP, LEFT_BACK,
1869 BACK_BOTTOM, BACK_LEFT, BACK_TOP, BACK_RIGHT,
1870 RIGHT_BOTTOM, RIGHT_BACK, RIGHT_TOP, RIGHT_FRONT,
1871 FRONT_BOTTOM, FRONT_RIGHT, FRONT_TOP, FRONT_LEFT,
1872 TOP};
1873
1874 pF[ 1]=G4Facet(1,LEFT_BOTTOM, 4,BACK_BOTTOM, 3,RIGHT_BOTTOM, 2,FRONT_BOTTOM);
1875
1876 pF[ 2]=G4Facet(4,BOTTOM, -1,LEFT_FRONT, -12,LEFT_BACK, 0,0);
1877 pF[ 3]=G4Facet(1,FRONT_LEFT, -5,LEFT_TOP, -12,LEFT_BOTTOM, 0,0);
1878 pF[ 4]=G4Facet(5,TOP, -8,LEFT_BACK, -12,LEFT_FRONT, 0,0);
1879 pF[ 5]=G4Facet(8,BACK_LEFT, -4,LEFT_BOTTOM, -12,LEFT_TOP, 0,0);
1880
1881 pF[ 6]=G4Facet(3,BOTTOM, -4,BACK_LEFT, -11,BACK_RIGHT, 0,0);
1882 pF[ 7]=G4Facet(4,LEFT_BACK, -8,BACK_TOP, -11,BACK_BOTTOM, 0,0);
1883 pF[ 8]=G4Facet(8,TOP, -7,BACK_RIGHT, -11,BACK_LEFT, 0,0);
1884 pF[ 9]=G4Facet(7,RIGHT_BACK, -3,BACK_BOTTOM, -11,BACK_TOP, 0,0);
1885
1886 pF[10]=G4Facet(2,BOTTOM, -3,RIGHT_BACK, -10,RIGHT_FRONT, 0,0);
1887 pF[11]=G4Facet(3,BACK_RIGHT, -7,RIGHT_TOP, -10,RIGHT_BOTTOM, 0,0);
1888 pF[12]=G4Facet(7,TOP, -6,RIGHT_FRONT, -10,RIGHT_BACK, 0,0);
1889 pF[13]=G4Facet(6,FRONT_RIGHT,-2,RIGHT_BOTTOM,-10,RIGHT_TOP, 0,0);
1890
1891 pF[14]=G4Facet(1,BOTTOM, -2,FRONT_RIGHT, -9,FRONT_LEFT, 0,0);
1892 pF[15]=G4Facet(2,RIGHT_FRONT,-6,FRONT_TOP, -9,FRONT_BOTTOM, 0,0);
1893 pF[16]=G4Facet(6,TOP, -5,FRONT_LEFT, -9,FRONT_RIGHT, 0,0);
1894 pF[17]=G4Facet(5,LEFT_FRONT, -1,FRONT_BOTTOM, -9,FRONT_TOP, 0,0);
1895
1896 pF[18]=G4Facet(5,FRONT_TOP, 6,RIGHT_TOP, 7,BACK_TOP, 8,LEFT_TOP);
1897
1898 return 0;
1899}

◆ FindNeighbour()

G4int HepPolyhedron::FindNeighbour ( G4int iFace,
G4int iNode,
G4int iOrder ) const
protected

Definition at line 214 of file HepPolyhedron.cc.

223{
224 G4int i;
225 for (i=0; i<4; i++) {
226 if (iNode == std::abs(pF[iFace].edge[i].v)) break;
227 }
228 if (i == 4) {
229 std::cerr
230 << "HepPolyhedron::FindNeighbour: face " << iFace
231 << " has no node " << iNode
232 << std::endl;
233 return 0;
234 }
235 if (iOrder < 0) {
236 if ( --i < 0) i = 3;
237 if (pF[iFace].edge[i].v == 0) i = 2;
238 }
239 return (pF[iFace].edge[i].v > 0) ? 0 : pF[iFace].edge[i].f;
240}

◆ FindNodeNormal()

G4Normal3D HepPolyhedron::FindNodeNormal ( G4int iFace,
G4int iNode ) const
protected

Definition at line 242 of file HepPolyhedron.cc.

251{
252 G4Normal3D normal = GetUnitNormal(iFace);
253 G4int k = iFace, iOrder = 1;
254
255 for(;;) {
256 k = FindNeighbour(k, iNode, iOrder);
257 if (k == iFace) break;
258 if (k > 0) {
259 normal += GetUnitNormal(k);
260 }else{
261 if (iOrder < 0) break;
262 k = iFace;
263 iOrder = -iOrder;
264 }
265 }
266 return normal.unit();
267}
BasicVector3D< T > unit() const
G4Normal3D GetUnitNormal(G4int iFace) const
G4int FindNeighbour(G4int iFace, G4int iNode, G4int iOrder) const

◆ GetFacet() [1/2]

void HepPolyhedron::GetFacet ( G4int iFace,
G4int & n,
G4int * iNodes,
G4int * edgeFlags = nullptr,
G4int * iFaces = nullptr ) const

Definition at line 1610 of file HepPolyhedron.cc.

1620{
1621 if (iFace < 1 || iFace > nface) {
1622 std::cerr
1623 << "HepPolyhedron::GetFacet: irrelevant index " << iFace
1624 << std::endl;
1625 n = 0;
1626 }else{
1627 G4int i, k;
1628 for (i=0; i<4; i++) {
1629 k = pF[iFace].edge[i].v;
1630 if (k == 0) break;
1631 if (iFaces != nullptr) iFaces[i] = pF[iFace].edge[i].f;
1632 if (k > 0) {
1633 iNodes[i] = k;
1634 if (edgeFlags != nullptr) edgeFlags[i] = 1;
1635 }else{
1636 iNodes[i] = -k;
1637 if (edgeFlags != nullptr) edgeFlags[i] = -1;
1638 }
1639 }
1640 n = i;
1641 }
1642}

Referenced by G4CutTubs::CreatePolyhedron().

◆ GetFacet() [2/2]

void HepPolyhedron::GetFacet ( G4int iFace,
G4int & n,
G4Point3D * nodes,
G4int * edgeFlags = nullptr,
G4Normal3D * normals = nullptr ) const

Definition at line 1644 of file HepPolyhedron.cc.

1654{
1655 G4int iNodes[4];
1656 GetFacet(index, n, iNodes, edgeFlags);
1657 if (n != 0) {
1658 for (G4int i=0; i<n; i++) {
1659 nodes[i] = pV[iNodes[i]];
1660 if (normals != nullptr) normals[i] = FindNodeNormal(index,iNodes[i]);
1661 }
1662 }
1663}
G4Normal3D FindNodeNormal(G4int iFace, G4int iNode) const
void GetFacet(G4int iFace, G4int &n, G4int *iNodes, G4int *edgeFlags=nullptr, G4int *iFaces=nullptr) const

◆ GetNextEdge() [1/2]

G4bool HepPolyhedron::GetNextEdge ( G4Point3D & p1,
G4Point3D & p2,
G4int & edgeFlag ) const

Definition at line 1569 of file HepPolyhedron.cc.

1581{
1582 G4int i1,i2;
1583 G4bool rep = GetNextEdgeIndices(i1,i2,edgeFlag);
1584 p1 = pV[i1];
1585 p2 = pV[i2];
1586 return rep;
1587}
bool G4bool
Definition G4Types.hh:86
G4bool GetNextEdgeIndices(G4int &i1, G4int &i2, G4int &edgeFlag, G4int &iface1, G4int &iface2) const

Referenced by G4GMocrenFileSceneHandler::AddSolid().

◆ GetNextEdge() [2/2]

G4bool HepPolyhedron::GetNextEdge ( G4Point3D & p1,
G4Point3D & p2,
G4int & edgeFlag,
G4int & iface1,
G4int & iface2 ) const

Definition at line 1590 of file HepPolyhedron.cc.

1602{
1603 G4int i1,i2;
1604 G4bool rep = GetNextEdgeIndices(i1,i2,edgeFlag,iface1,iface2);
1605 p1 = pV[i1];
1606 p2 = pV[i2];
1607 return rep;
1608}

◆ GetNextEdgeIndeces() [1/2]

G4bool HepPolyhedron::GetNextEdgeIndeces ( G4int & i1,
G4int & i2,
G4int & edgeFlag ) const
inline

Definition at line 336 of file HepPolyhedron.h.

337 {return GetNextEdgeIndices(i1,i2,edgeFlag);} // Old spelling.

◆ GetNextEdgeIndeces() [2/2]

G4bool HepPolyhedron::GetNextEdgeIndeces ( G4int & i1,
G4int & i2,
G4int & edgeFlag,
G4int & iface1,
G4int & iface2 ) const
inline

Definition at line 330 of file HepPolyhedron.h.

332 {return GetNextEdgeIndices(i1,i2,edgeFlag,iface1,iface2);} // Old spelling

◆ GetNextEdgeIndices() [1/2]

G4bool HepPolyhedron::GetNextEdgeIndices ( G4int & i1,
G4int & i2,
G4int & edgeFlag ) const

Definition at line 1553 of file HepPolyhedron.cc.

1563{
1564 G4int kface1, kface2;
1565 return GetNextEdgeIndices(i1, i2, edgeFlag, kface1, kface2);
1566}

◆ GetNextEdgeIndices() [2/2]

G4bool HepPolyhedron::GetNextEdgeIndices ( G4int & i1,
G4int & i2,
G4int & edgeFlag,
G4int & iface1,
G4int & iface2 ) const

Definition at line 1500 of file HepPolyhedron.cc.

1512{
1513 static G4ThreadLocal G4int iFace = 1;
1514 static G4ThreadLocal G4int iQVertex = 0;
1515 static G4ThreadLocal G4int iOrder = 1;
1516 G4int k1, k2, kflag, kface1, kface2;
1517
1518 if (iFace == 1 && iQVertex == 0) {
1519 k2 = pF[nface].edge[0].v;
1520 k1 = pF[nface].edge[3].v;
1521 if (k1 == 0) k1 = pF[nface].edge[2].v;
1522 if (std::abs(k1) > std::abs(k2)) iOrder = -1;
1523 }
1524
1525 do {
1526 k1 = pF[iFace].edge[iQVertex].v;
1527 kflag = k1;
1528 k1 = std::abs(k1);
1529 kface1 = iFace;
1530 kface2 = pF[iFace].edge[iQVertex].f;
1531 if (iQVertex >= 3 || pF[iFace].edge[iQVertex+1].v == 0) {
1532 iQVertex = 0;
1533 k2 = std::abs(pF[iFace].edge[iQVertex].v);
1534 iFace++;
1535 }else{
1536 iQVertex++;
1537 k2 = std::abs(pF[iFace].edge[iQVertex].v);
1538 }
1539 } while (iOrder*k1 > iOrder*k2);
1540
1541 i1 = k1; i2 = k2; edgeFlag = (kflag > 0) ? 1 : 0;
1542 iface1 = kface1; iface2 = kface2;
1543
1544 if (iFace > nface) {
1545 iFace = 1; iOrder = 1;
1546 return false;
1547 }
1548
1549 return true;
1550}
#define G4ThreadLocal
Definition tls.hh:77

Referenced by GetNextEdgeIndeces(), and GetNextEdgeIndeces().

◆ GetNextFacet()

G4bool HepPolyhedron::GetNextFacet ( G4int & n,
G4Point3D * nodes,
G4int * edgeFlags = nullptr,
G4Normal3D * normals = nullptr ) const

Definition at line 1666 of file HepPolyhedron.cc.

1677{
1678 static G4ThreadLocal G4int iFace = 1;
1679
1680 if (edgeFlags == nullptr) {
1681 GetFacet(iFace, n, nodes);
1682 }else if (normals == nullptr) {
1683 GetFacet(iFace, n, nodes, edgeFlags);
1684 }else{
1685 GetFacet(iFace, n, nodes, edgeFlags, normals);
1686 }
1687
1688 if (++iFace > nface) {
1689 iFace = 1;
1690 return false;
1691 }
1692
1693 return true;
1694}

Referenced by G4VtkPolydataInstanceBakePipeline::addInstance(), G4OpenGLSceneHandler::AddPrimitive(), G4Qt3DSceneHandler::AddPrimitive(), G4ToolsSGSceneHandler::AddPrimitive(), std::hash< G4Polyhedron >::operator()(), and G4VtkPolydataPipeline::SetPolydata().

◆ GetNextNormal()

G4bool HepPolyhedron::GetNextNormal ( G4Normal3D & normal) const

Definition at line 1746 of file HepPolyhedron.cc.

1756{
1757 static G4ThreadLocal G4int iFace = 1;
1758 normal = GetNormal(iFace);
1759 if (++iFace > nface) {
1760 iFace = 1;
1761 return false;
1762 }
1763 return true;
1764}
G4Normal3D GetNormal(G4int iFace) const

Referenced by G4HepRepFileSceneHandler::AddPrimitive().

◆ GetNextUnitNormal()

G4bool HepPolyhedron::GetNextUnitNormal ( G4Normal3D & normal) const

Definition at line 1766 of file HepPolyhedron.cc.

1776{
1777 G4bool rep = GetNextNormal(normal);
1778 normal = normal.unit();
1779 return rep;
1780}
G4bool GetNextNormal(G4Normal3D &normal) const

Referenced by Geant4_SoPolyhedron::computeBBox(), Geant4_SoPolyhedron::generateAlternateRep(), and Geant4_SoPolyhedron::generatePrimitives().

◆ GetNextVertex() [1/2]

G4bool HepPolyhedron::GetNextVertex ( G4Point3D & vertex,
G4int & edgeFlag ) const

Definition at line 1451 of file HepPolyhedron.cc.

1462{
1463 G4int index;
1464 G4bool rep = GetNextVertexIndex(index, edgeFlag);
1465 vertex = pV[index];
1466 return rep;
1467}
G4bool GetNextVertexIndex(G4int &index, G4int &edgeFlag) const

Referenced by G4HepRepFileSceneHandler::AddPrimitive(), Geant4_SoPolyhedron::computeBBox(), Geant4_SoPolyhedron::generateAlternateRep(), and Geant4_SoPolyhedron::generatePrimitives().

◆ GetNextVertex() [2/2]

G4bool HepPolyhedron::GetNextVertex ( G4Point3D & vertex,
G4int & edgeFlag,
G4Normal3D & normal ) const

Definition at line 1469 of file HepPolyhedron.cc.

1481{
1482 static G4ThreadLocal G4int iFace = 1;
1483 static G4ThreadLocal G4int iNode = 0;
1484
1485 if (nface == 0) return false; // empty polyhedron
1486
1487 G4int k = pF[iFace].edge[iNode].v;
1488 if (k > 0) { edgeFlag = 1; } else { edgeFlag = -1; k = -k; }
1489 vertex = pV[k];
1490 normal = FindNodeNormal(iFace,k);
1491 if (iNode >= 3 || pF[iFace].edge[iNode+1].v == 0) {
1492 iNode = 0;
1493 if (++iFace > nface) iFace = 1;
1494 return false; // last node
1495 }
1496 ++iNode;
1497 return true; // not last node
1498}

◆ GetNextVertexIndex()

G4bool HepPolyhedron::GetNextVertexIndex ( G4int & index,
G4int & edgeFlag ) const

Definition at line 1404 of file HepPolyhedron.cc.

1413{
1414 static G4ThreadLocal G4int iFace = 1;
1415 static G4ThreadLocal G4int iQVertex = 0;
1416 G4int vIndex = pF[iFace].edge[iQVertex].v;
1417
1418 edgeFlag = (vIndex > 0) ? 1 : 0;
1419 index = std::abs(vIndex);
1420
1421 if (iQVertex >= 3 || pF[iFace].edge[iQVertex+1].v == 0) {
1422 iQVertex = 0;
1423 if (++iFace > nface) iFace = 1;
1424 return false; // Last Edge
1425 }
1426
1427 ++iQVertex;
1428 return true; // not Last Edge
1429}

Referenced by G4GMocrenFileSceneHandler::AddPrimitive().

◆ GetNoFacets()

◆ GetNormal()

G4Normal3D HepPolyhedron::GetNormal ( G4int iFace) const

Definition at line 1696 of file HepPolyhedron.cc.

1705{
1706 if (iFace < 1 || iFace > nface) {
1707 std::cerr
1708 << "HepPolyhedron::GetNormal: irrelevant index " << iFace
1709 << std::endl;
1710 return G4Normal3D();
1711 }
1712
1713 G4int i0 = std::abs(pF[iFace].edge[0].v);
1714 G4int i1 = std::abs(pF[iFace].edge[1].v);
1715 G4int i2 = std::abs(pF[iFace].edge[2].v);
1716 G4int i3 = std::abs(pF[iFace].edge[3].v);
1717 if (i3 == 0) i3 = i0;
1718 return (pV[i2] - pV[i0]).cross(pV[i3] - pV[i1]);
1719}
HepGeom::Normal3D< G4double > G4Normal3D
Definition G4Normal3D.hh:34

◆ GetNoVerteces()

G4int HepPolyhedron::GetNoVerteces ( ) const
inline

Definition at line 306 of file HepPolyhedron.h.

306{ return nvert; } // Old spelling.

◆ GetNoVertices()

G4int HepPolyhedron::GetNoVertices ( ) const
inline

◆ GetNumberOfRotationSteps()

◆ GetSurfaceArea()

G4double HepPolyhedron::GetSurfaceArea ( ) const

Definition at line 1782 of file HepPolyhedron.cc.

1791{
1792 G4double srf = 0.;
1793 for (G4int iFace=1; iFace<=nface; iFace++) {
1794 G4int i0 = std::abs(pF[iFace].edge[0].v);
1795 G4int i1 = std::abs(pF[iFace].edge[1].v);
1796 G4int i2 = std::abs(pF[iFace].edge[2].v);
1797 G4int i3 = std::abs(pF[iFace].edge[3].v);
1798 if (i3 == 0) i3 = i0;
1799 srf += ((pV[i2] - pV[i0]).cross(pV[i3] - pV[i1])).mag();
1800 }
1801 return srf/2.;
1802}

◆ GetUnitNormal()

G4Normal3D HepPolyhedron::GetUnitNormal ( G4int iFace) const

Definition at line 1721 of file HepPolyhedron.cc.

1730{
1731 if (iFace < 1 || iFace > nface) {
1732 std::cerr
1733 << "HepPolyhedron::GetUnitNormal: irrelevant index " << iFace
1734 << std::endl;
1735 return G4Normal3D();
1736 }
1737
1738 G4int i0 = std::abs(pF[iFace].edge[0].v);
1739 G4int i1 = std::abs(pF[iFace].edge[1].v);
1740 G4int i2 = std::abs(pF[iFace].edge[2].v);
1741 G4int i3 = std::abs(pF[iFace].edge[3].v);
1742 if (i3 == 0) i3 = i0;
1743 return ((pV[i2] - pV[i0]).cross(pV[i3] - pV[i1])).unit();
1744}

Referenced by JoinCoplanarFacets().

◆ GetVertex()

G4Point3D HepPolyhedron::GetVertex ( G4int index) const

Definition at line 1431 of file HepPolyhedron.cc.

1440{
1441 if (index <= 0 || index > nvert) {
1442 std::cerr
1443 << "HepPolyhedron::GetVertex: irrelevant index " << index
1444 << std::endl;
1445 return G4Point3D();
1446 }
1447 return pV[index];
1448}

Referenced by G4GMocrenFileSceneHandler::AddSolid(), and G4CutTubs::CreatePolyhedron().

◆ GetVolume()

G4double HepPolyhedron::GetVolume ( ) const

Definition at line 1804 of file HepPolyhedron.cc.

1813{
1814 G4double v = 0.;
1815 for (G4int iFace=1; iFace<=nface; iFace++) {
1816 G4int i0 = std::abs(pF[iFace].edge[0].v);
1817 G4int i1 = std::abs(pF[iFace].edge[1].v);
1818 G4int i2 = std::abs(pF[iFace].edge[2].v);
1819 G4int i3 = std::abs(pF[iFace].edge[3].v);
1820 G4Point3D pt;
1821 if (i3 == 0) {
1822 i3 = i0;
1823 pt = (pV[i0]+pV[i1]+pV[i2]) * (1./3.);
1824 }else{
1825 pt = (pV[i0]+pV[i1]+pV[i2]+pV[i3]) * 0.25;
1826 }
1827 v += ((pV[i2] - pV[i0]).cross(pV[i3] - pV[i1])).dot(pt);
1828 }
1829 return v/6.;
1830}
T dot(const BasicVector3D< T > &v) const

◆ intersect()

HepPolyhedron HepPolyhedron::intersect ( const HepPolyhedron & p) const

Definition at line 3376 of file HepPolyhedron.cc.

3385{
3386 G4int ierr;
3387 BooleanProcessor processor;
3388 return processor.execute(OP_INTERSECTION, *this, p,ierr);
3389}

◆ InvertFacets()

void HepPolyhedron::InvertFacets ( )

Definition at line 1353 of file HepPolyhedron.cc.

1362{
1363 if (nface <= 0) return;
1364 G4int i, k, nnode, v[4],f[4];
1365 for (i=1; i<=nface; i++) {
1366 nnode = (pF[i].edge[3].v == 0) ? 3 : 4;
1367 for (k=0; k<nnode; k++) {
1368 v[k] = (k+1 == nnode) ? pF[i].edge[0].v : pF[i].edge[k+1].v;
1369 if (v[k] * pF[i].edge[k].v < 0) v[k] = -v[k];
1370 f[k] = pF[i].edge[k].f;
1371 }
1372 for (k=0; k<nnode; k++) {
1373 pF[i].edge[nnode-1-k].v = v[k];
1374 pF[i].edge[nnode-1-k].f = f[k];
1375 }
1376 }
1377}

Referenced by G4GenericTrap::CreatePolyhedron(), G4PolyhedronArbitrary::InvertFacets(), and Transform().

◆ JoinCoplanarFacets()

void HepPolyhedron::JoinCoplanarFacets ( G4double tolerance)

Definition at line 1264 of file HepPolyhedron.cc.

1274{
1275 G4int njoin = 0;
1276 for (G4int icur = 1; icur <= nface; ++icur)
1277 {
1278 // skip if already joined or quadrangle
1279 if (pF[icur].edge[0].v == 0) continue;
1280 if (pF[icur].edge[3].v != 0) continue;
1281 // skip if all references point to already checked facets
1282 if (pF[icur].edge[0].f < icur &&
1283 pF[icur].edge[1].f < icur &&
1284 pF[icur].edge[2].f < icur) continue;
1285 // compute plane equation
1286 G4Normal3D norm = GetUnitNormal(icur);
1287 G4double dd = norm.dot(pV[pF[icur].edge[0].v]);
1288 G4int vcur0 = std::abs(pF[icur].edge[0].v);
1289 G4int vcur1 = std::abs(pF[icur].edge[1].v);
1290 G4int vcur2 = std::abs(pF[icur].edge[2].v);
1291 // select neighbouring facet
1292 G4int kcheck = 0, icheck = 0, vcheck = 0;
1293 G4double dist = DBL_MAX;
1294 for (G4int k = 0; k < 3; ++k)
1295 {
1296 G4int itmp = pF[icur].edge[k].f;
1297 // skip if already checked, joined or quadrangle
1298 if (itmp < icur) continue;
1299 if (pF[itmp].edge[0].v == 0 ||
1300 pF[itmp].edge[3].v != 0) continue;
1301 // get candidate vertex
1302 G4int vtmp = 0;
1303 for (G4int j = 0; j < 3; ++j)
1304 {
1305 vtmp = std::abs(pF[itmp].edge[j].v);
1306 if (vtmp != vcur0 && vtmp != vcur1 && vtmp != vcur2) break;
1307 }
1308 // check distance to the plane
1309 G4double dtmp = std::abs(norm.dot(pV[vtmp]) - dd);
1310 if (dtmp > tolerance || dtmp >= dist) continue;
1311 dist = dtmp;
1312 kcheck = k;
1313 icheck = itmp;
1314 vcheck = vtmp;
1315 }
1316 if (icheck == 0) continue; // no facet selected
1317 // join facets
1318 njoin++;
1319 pF[icheck].edge[0].v = 0; // mark facet as joined
1320 if (kcheck == 0)
1321 {
1322 pF[icur].edge[3].v = pF[icur].edge[2].v;
1323 pF[icur].edge[2].v = pF[icur].edge[1].v;
1324 pF[icur].edge[1].v = vcheck;
1325 }
1326 else if (kcheck == 1)
1327 {
1328 pF[icur].edge[3].v = pF[icur].edge[2].v;
1329 pF[icur].edge[2].v = vcheck;
1330 }
1331 else
1332 {
1333 pF[icur].edge[3].v = vcheck;
1334 }
1335 }
1336 if (njoin == 0) return; // no joined facets
1337
1338 // restructure facets
1339 G4int nnew = 0;
1340 for (G4int icur = 1; icur <= nface; ++icur)
1341 {
1342 if (pF[icur].edge[0].v == 0) continue;
1343 nnew++;
1344 pF[nnew].edge[0].v = pF[icur].edge[0].v;
1345 pF[nnew].edge[1].v = pF[icur].edge[1].v;
1346 pF[nnew].edge[2].v = pF[icur].edge[2].v;
1347 pF[nnew].edge[3].v = pF[icur].edge[3].v;
1348 }
1349 nface = nnew;
1350 SetReferences();
1351}
#define DBL_MAX
Definition templates.hh:62

◆ operator=() [1/2]

HepPolyhedron & HepPolyhedron::operator= ( const HepPolyhedron & from)

Definition at line 168 of file HepPolyhedron.cc.

177{
178 if (this != &from) {
179 AllocateMemory(from.nvert, from.nface);
180 for (G4int i=1; i<=nvert; i++) pV[i] = from.pV[i];
181 for (G4int k=1; k<=nface; k++) pF[k] = from.pF[k];
182 }
183 return *this;
184}

◆ operator=() [2/2]

HepPolyhedron & HepPolyhedron::operator= ( HepPolyhedron && from)

Definition at line 186 of file HepPolyhedron.cc.

195{
196 if (this != &from) {
197 delete [] pV;
198 delete [] pF;
199 nvert = from.nvert;
200 nface = from.nface;
201 pV = from.pV;
202 pF = from.pF;
203
204 // Release the data from the source object
205 from.nvert = 0;
206 from.nface = 0;
207 from.pV = nullptr;
208 from.pF = nullptr;
209 }
210 return *this;
211}

◆ ResetNumberOfRotationSteps()

void HepPolyhedron::ResetNumberOfRotationSteps ( )
static

Definition at line 361 of file HepPolyhedron.cc.

370{
372}
#define DEFAULT_NUMBER_OF_STEPS

Referenced by G4VSceneHandler::RequestPrimitives().

◆ RotateAroundZ()

void HepPolyhedron::RotateAroundZ ( G4int nstep,
G4double phi,
G4double dphi,
G4int np1,
G4int np2,
const G4double * z,
G4double * r,
G4int nodeVis,
G4int edgeVis )
protected

Definition at line 553 of file HepPolyhedron.cc.

578{
579 static const G4double wholeCircle = twopi;
580
581 // S E T R O T A T I O N P A R A M E T E R S
582
583 G4bool ifWholeCircle = std::abs(dphi-wholeCircle) < perMillion;
584 G4double delPhi = ifWholeCircle ? wholeCircle : dphi;
585 G4int nSphi = nstep;
586 if (nSphi <= 0) nSphi = GetNumberOfRotationSteps()*delPhi/wholeCircle + 0.5;
587 if (nSphi == 0) nSphi = 1;
588 G4int nVphi = ifWholeCircle ? nSphi : nSphi + 1;
589 G4bool ifClosed = np1 <= 0; // true if external polyline is closed
590
591 // C O U N T V E R T I C E S
592
593 G4int absNp1 = std::abs(np1);
594 G4int absNp2 = std::abs(np2);
595 G4int i1beg = 0;
596 G4int i1end = absNp1-1;
597 G4int i2beg = absNp1;
598 G4int i2end = absNp1+absNp2-1;
599 G4int i, j, k;
600
601 for(i=i1beg; i<=i2end; i++) {
602 if (std::abs(r[i]) < spatialTolerance) r[i] = 0.;
603 }
604
605 // external polyline - check position of nodes relative to Z
606 //
607 G4int Nverts = 0;
608 for (i=i1beg; i<=i1end; i++) {
609 Nverts += (r[i] == 0.) ? 1 : nVphi;
610 }
611
612 // internal polyline
613 //
614 G4bool ifSide1 = false; // whether to create bottom faces
615 G4bool ifSide2 = false; // whether to create top faces
616
617 if (r[i2beg] != r[i1beg] || z[i2beg] != z[i1beg]) { // first node
618 Nverts += (r[i2beg] == 0.) ? 1 : nVphi;
619 ifSide1 = true;
620 }
621
622 for(i=i2beg+1; i<i2end; i++) { // intermediate nodes
623 Nverts += (r[i] == 0.) ? 1 : nVphi;
624 }
625
626 if (r[i2end] != r[i1end] || z[i2end] != z[i1end]) { // last node
627 if (absNp2 > 1) Nverts += (r[i2end] == 0.) ? 1 : nVphi;
628 ifSide2 = true;
629 }
630
631 // C O U N T F A C E S
632
633 // external lateral faces
634 //
635 G4int Nfaces = ifClosed ? absNp1*nSphi : (absNp1-1)*nSphi;
636
637 // internal lateral faces
638 //
639 if (absNp2 > 1) {
640 for(i=i2beg; i<i2end; i++) {
641 if (r[i] > 0. || r[i+1] > 0.) Nfaces += nSphi;
642 }
643
644 if (ifClosed) {
645 if (r[i2end] > 0. || r[i2beg] > 0.) Nfaces += nSphi;
646 }
647 }
648
649 // bottom and top faces
650 //
651 if (!ifClosed) {
652 if (ifSide1 && (r[i1beg] > 0. || r[i2beg] > 0.)) Nfaces += nSphi;
653 if (ifSide2 && (r[i1end] > 0. || r[i2end] > 0.)) Nfaces += nSphi;
654 }
655
656 // phi_wedge faces
657 //
658 if (!ifWholeCircle) {
659 Nfaces += ifClosed ? 2*absNp1 : 2*(absNp1-1);
660 }
661
662 // A L L O C A T E M E M O R Y
663
664 AllocateMemory(Nverts, Nfaces);
665 if (pV == nullptr || pF == nullptr) return;
666
667 // G E N E R A T E V E R T I C E S
668
669 G4int *kk; // array of start indices along polylines
670 kk = new G4int[absNp1+absNp2];
671
672 // external polyline
673 //
674 k = 1; // free position in array of vertices pV
675 for(i=i1beg; i<=i1end; i++) {
676 kk[i] = k;
677 if (r[i] == 0.)
678 { pV[k++] = G4Point3D(0, 0, z[i]); } else { k += nVphi; }
679 }
680
681 // first point of internal polyline
682 //
683 i = i2beg;
684 if (ifSide1) {
685 kk[i] = k;
686 if (r[i] == 0.)
687 { pV[k++] = G4Point3D(0, 0, z[i]); } else { k += nVphi; }
688 }else{
689 kk[i] = kk[i1beg];
690 }
691
692 // intermediate points of internal polyline
693 //
694 for(i=i2beg+1; i<i2end; i++) {
695 kk[i] = k;
696 if (r[i] == 0.)
697 { pV[k++] = G4Point3D(0, 0, z[i]); } else { k += nVphi; }
698 }
699
700 // last point of internal polyline
701 //
702 if (absNp2 > 1) {
703 i = i2end;
704 if (ifSide2) {
705 kk[i] = k;
706 if (r[i] == 0.) pV[k] = G4Point3D(0, 0, z[i]);
707 }else{
708 kk[i] = kk[i1end];
709 }
710 }
711
712 // set vertices
713 //
714 G4double cosPhi, sinPhi;
715
716 for(j=0; j<nVphi; j++) {
717 cosPhi = std::cos(phi+j*delPhi/nSphi);
718 sinPhi = std::sin(phi+j*delPhi/nSphi);
719 for(i=i1beg; i<=i2end; i++) {
720 if (r[i] != 0.)
721 pV[kk[i]+j] = G4Point3D(r[i]*cosPhi,r[i]*sinPhi,z[i]);
722 }
723 }
724
725 // G E N E R A T E F A C E S
726
727 // external faces
728 //
729 G4int v1,v2;
730
731 k = 1; // free position in array of faces pF
732 v2 = ifClosed ? nodeVis : 1;
733 for(i=i1beg; i<i1end; i++) {
734 v1 = v2;
735 if (!ifClosed && i == i1end-1) {
736 v2 = 1;
737 }else{
738 v2 = (r[i] == r[i+1] && r[i+1] == r[i+2]) ? -1 : nodeVis;
739 }
740 RotateEdge(kk[i], kk[i+1], r[i], r[i+1], v1, v2,
741 edgeVis, ifWholeCircle, nSphi, k);
742 }
743 if (ifClosed) {
744 RotateEdge(kk[i1end], kk[i1beg], r[i1end],r[i1beg], nodeVis, nodeVis,
745 edgeVis, ifWholeCircle, nSphi, k);
746 }
747
748 // internal faces
749 //
750 if (absNp2 > 1) {
751 v2 = ifClosed ? nodeVis : 1;
752 for(i=i2beg; i<i2end; i++) {
753 v1 = v2;
754 if (!ifClosed && i==i2end-1) {
755 v2 = 1;
756 }else{
757 v2 = (r[i] == r[i+1] && r[i+1] == r[i+2]) ? -1 : nodeVis;
758 }
759 RotateEdge(kk[i+1], kk[i], r[i+1], r[i], v2, v1,
760 edgeVis, ifWholeCircle, nSphi, k);
761 }
762 if (ifClosed) {
763 RotateEdge(kk[i2beg], kk[i2end], r[i2beg], r[i2end], nodeVis, nodeVis,
764 edgeVis, ifWholeCircle, nSphi, k);
765 }
766 }
767
768 // bottom and top faces
769 //
770 if (!ifClosed) {
771 if (ifSide1) {
772 RotateEdge(kk[i2beg], kk[i1beg], r[i2beg], r[i1beg], 1, 1,
773 -1, ifWholeCircle, nSphi, k);
774 }
775 if (ifSide2) {
776 RotateEdge(kk[i1end], kk[i2end], r[i1end], r[i2end], 1, 1,
777 -1, ifWholeCircle, nSphi, k);
778 }
779 }
780
781 // phi_wedge faces in case of incomplete circle
782 //
783 if (!ifWholeCircle) {
784
785 G4int ii[4], vv[4];
786
787 if (ifClosed) {
788 for (i=i1beg; i<=i1end; i++) {
789 ii[0] = i;
790 ii[3] = (i == i1end) ? i1beg : i+1;
791 ii[1] = (absNp2 == 1) ? i2beg : ii[0]+absNp1;
792 ii[2] = (absNp2 == 1) ? i2beg : ii[3]+absNp1;
793 vv[0] = -1;
794 vv[1] = 1;
795 vv[2] = -1;
796 vv[3] = 1;
797 SetSideFacets(ii, vv, kk, r, delPhi, nSphi, k);
798 }
799 }else{
800 for (i=i1beg; i<i1end; i++) {
801 ii[0] = i;
802 ii[3] = i+1;
803 ii[1] = (absNp2 == 1) ? i2beg : ii[0]+absNp1;
804 ii[2] = (absNp2 == 1) ? i2beg : ii[3]+absNp1;
805 vv[0] = (i == i1beg) ? 1 : -1;
806 vv[1] = 1;
807 vv[2] = (i == i1end-1) ? 1 : -1;
808 vv[3] = 1;
809 SetSideFacets(ii, vv, kk, r, delPhi, nSphi, k);
810 }
811 }
812 }
813
814 delete [] kk; // free memory
815
816 // final check
817 //
818 if (k-1 != nface) {
819 std::cerr
820 << "HepPolyhedron::RotateAroundZ: number of generated faces ("
821 << k-1 << ") is not equal to the number of allocated faces ("
822 << nface << ")"
823 << std::endl;
824 }
825}
const G4double spatialTolerance
static G4int GetNumberOfRotationSteps()
void RotateEdge(G4int k1, G4int k2, G4double r1, G4double r2, G4int v1, G4int v2, G4int vEdge, G4bool ifWholeCircle, G4int ns, G4int &kface)
void SetSideFacets(G4int ii[4], G4int vv[4], G4int *kk, G4double *r, G4double dphi, G4int ns, G4int &kface)

Referenced by HepPolyhedronCons::HepPolyhedronCons(), HepPolyhedronEllipsoid::HepPolyhedronEllipsoid(), HepPolyhedronEllipticalCone::HepPolyhedronEllipticalCone(), HepPolyhedronHype::HepPolyhedronHype(), HepPolyhedronHyperbolicMirror::HepPolyhedronHyperbolicMirror(), HepPolyhedronParaboloid::HepPolyhedronParaboloid(), HepPolyhedronPgon::HepPolyhedronPgon(), HepPolyhedronSphere::HepPolyhedronSphere(), and HepPolyhedronTorus::HepPolyhedronTorus().

◆ RotateContourAroundZ()

void HepPolyhedron::RotateContourAroundZ ( G4int nstep,
G4double phi,
G4double dphi,
const std::vector< G4TwoVector > & rz,
G4int nodeVis,
G4int edgeVis )
protected

Definition at line 828 of file HepPolyhedron.cc.

851{
852 // S E T R O T A T I O N P A R A M E T E R S
853
854 G4bool ifWholeCircle = std::abs(dphi - twopi) < perMillion;
855 G4double delPhi = (ifWholeCircle) ? twopi : dphi;
856 G4int nSphi = nstep;
857 if (nSphi <= 0) nSphi = GetNumberOfRotationSteps()*delPhi/twopi + 0.5;
858 if (nSphi == 0) nSphi = 1;
859 G4int nVphi = (ifWholeCircle) ? nSphi : nSphi + 1;
860
861 // C A L C U L A T E A R E A
862
863 G4int Nrz = (G4int)rz.size();
864 G4double area = 0;
865 for (G4int i = 0; i < Nrz; ++i)
866 {
867 G4int k = (i == 0) ? Nrz - 1 : i - 1;
868 area += rz[k].x()*rz[i].y() - rz[i].x()*rz[k].y();
869 }
870
871 // P R E P A R E P O L Y L I N E
872
873 auto r = new G4double[Nrz];
874 auto z = new G4double[Nrz];
875 for (G4int i = 0; i < Nrz; ++i)
876 {
877 r[i] = rz[i].x();
878 z[i] = rz[i].y();
879 if (std::abs(r[i]) < spatialTolerance) r[i] = 0.;
880 }
881
882 // C O U N T V E R T I C E S A N D F A C E S
883
884 G4int Nverts = 0;
885 for(G4int i = 0; i < Nrz; ++i) Nverts += (r[i] == 0.) ? 1 : nVphi;
886
887 G4int Nedges = Nrz;
888 for (G4int i = 0; i < Nrz; ++i)
889 {
890 G4int k = (i == 0) ? Nrz - 1 : i - 1;
891 Nedges -= static_cast<int>(r[k] == 0 && r[i] == 0);
892 }
893
894 G4int Nfaces = Nedges*nSphi; // lateral faces
895 if (!ifWholeCircle) Nfaces += 2*(Nrz - 2); // phi_wedge faces
896
897 // A L L O C A T E M E M O R Y
898
899 AllocateMemory(Nverts, Nfaces);
900 if (pV == nullptr || pF == nullptr)
901 {
902 delete [] r;
903 delete [] z;
904 return;
905 }
906
907 // S E T V E R T I C E S
908
909 auto kk = new G4int[Nrz]; // start indices along contour
910 G4int kfree = 1; // current free position in array of vertices pV
911
912 // set start indices, set vertices for nodes with r == 0
913 for(G4int i = 0; i < Nrz; ++i)
914 {
915 kk[i] = kfree;
916 if (r[i] == 0.) pV[kfree++] = G4Point3D(0, 0, z[i]);
917 if (r[i] != 0.) kfree += nVphi;
918 }
919
920 // set vertices by rotating r
921 for(G4int j = 0; j < nVphi; ++j)
922 {
923 G4double cosPhi = std::cos(phi + j*delPhi/nSphi);
924 G4double sinPhi = std::sin(phi + j*delPhi/nSphi);
925 for(G4int i = 0; i < Nrz; ++i)
926 {
927 if (r[i] != 0.)
928 pV[kk[i] + j] = G4Point3D(r[i]*cosPhi, r[i]*sinPhi, z[i]);
929 }
930 }
931
932 // S E T F A C E S
933
934 kfree = 1; // current free position in array of faces pF
935 for(G4int i = 0; i < Nrz; ++i)
936 {
937 G4int i1 = (i < Nrz - 1) ? i + 1 : 0; // inverse order if area > 0
938 G4int i2 = i;
939 if (area < 0.) std::swap(i1, i2);
940 RotateEdge(kk[i1], kk[i2], r[i1], r[i2], nodeVis, nodeVis,
941 edgeVis, ifWholeCircle, nSphi, kfree);
942 }
943
944 // S E T P H I _ W E D G E F A C E S
945
946 if (!ifWholeCircle)
947 {
948 std::vector<G4int> triangles;
949 TriangulatePolygon(rz, triangles);
950
951 G4int ii[4], vv[4];
952 G4int ntria = G4int(triangles.size()/3);
953 for (G4int i = 0; i < ntria; ++i)
954 {
955 G4int i1 = triangles[0 + i*3];
956 G4int i2 = triangles[1 + i*3];
957 G4int i3 = triangles[2 + i*3];
958 if (area < 0.) std::swap(i1, i3);
959 G4int v1 = (std::abs(i2-i1) == 1 || std::abs(i2-i1) == Nrz-1) ? 1 : -1;
960 G4int v2 = (std::abs(i3-i2) == 1 || std::abs(i3-i2) == Nrz-1) ? 1 : -1;
961 G4int v3 = (std::abs(i1-i3) == 1 || std::abs(i1-i3) == Nrz-1) ? 1 : -1;
962 ii[0] = i1; ii[1] = i2; ii[2] = i2; ii[3] = i3;
963 vv[0] = v1; vv[1] = -1; vv[2] = v2; vv[3] = v3;
964 SetSideFacets(ii, vv, kk, r, delPhi, nSphi, kfree);
965 }
966 }
967
968 // free memory
969 delete [] r;
970 delete [] z;
971 delete [] kk;
972
973 // final check
974 if (kfree - 1 != nface)
975 {
976 std::cerr
977 << "HepPolyhedron::RotateContourAroundZ: number of generated faces ("
978 << kfree-1 << ") is not equal to the number of allocated faces ("
979 << nface << ")"
980 << std::endl;
981 }
982}
G4bool TriangulatePolygon(const std::vector< G4TwoVector > &polygon, std::vector< G4int > &result)

Referenced by HepPolyhedronPgon::HepPolyhedronPgon().

◆ RotateEdge()

void HepPolyhedron::RotateEdge ( G4int k1,
G4int k2,
G4double r1,
G4double r2,
G4int v1,
G4int v2,
G4int vEdge,
G4bool ifWholeCircle,
G4int ns,
G4int & kface )
protected

Definition at line 420 of file HepPolyhedron.cc.

441{
442 if (r1 == 0. && r2 == 0.) return;
443
444 G4int i;
445 G4int i1 = k1;
446 G4int i2 = k2;
447 G4int ii1 = ifWholeCircle ? i1 : i1+nds;
448 G4int ii2 = ifWholeCircle ? i2 : i2+nds;
449 G4int vv = ifWholeCircle ? vEdge : 1;
450
451 if (nds == 1) {
452 if (r1 == 0.) {
453 pF[kface++] = G4Facet(i1,0, v2*i2,0, (i2+1),0);
454 }else if (r2 == 0.) {
455 pF[kface++] = G4Facet(i1,0, i2,0, v1*(i1+1),0);
456 }else{
457 pF[kface++] = G4Facet(i1,0, v2*i2,0, (i2+1),0, v1*(i1+1),0);
458 }
459 }else{
460 if (r1 == 0.) {
461 pF[kface++] = G4Facet(vv*i1,0, v2*i2,0, vEdge*(i2+1),0);
462 for (i2++,i=1; i<nds-1; i2++,i++) {
463 pF[kface++] = G4Facet(vEdge*i1,0, v2*i2,0, vEdge*(i2+1),0);
464 }
465 pF[kface++] = G4Facet(vEdge*i1,0, v2*i2,0, vv*ii2,0);
466 }else if (r2 == 0.) {
467 pF[kface++] = G4Facet(vv*i1,0, vEdge*i2,0, v1*(i1+1),0);
468 for (i1++,i=1; i<nds-1; i1++,i++) {
469 pF[kface++] = G4Facet(vEdge*i1,0, vEdge*i2,0, v1*(i1+1),0);
470 }
471 pF[kface++] = G4Facet(vEdge*i1,0, vv*i2,0, v1*ii1,0);
472 }else{
473 pF[kface++] = G4Facet(vv*i1,0, v2*i2,0, vEdge*(i2+1),0,v1*(i1+1),0);
474 for (i1++,i2++,i=1; i<nds-1; i1++,i2++,i++) {
475 pF[kface++] = G4Facet(vEdge*i1,0, v2*i2,0, vEdge*(i2+1),0,v1*(i1+1),0);
476 }
477 pF[kface++] = G4Facet(vEdge*i1,0, v2*i2,0, vv*ii2,0, v1*ii1,0);
478 }
479 }
480}

Referenced by RotateAroundZ(), and RotateContourAroundZ().

◆ SetFacet()

void HepPolyhedron::SetFacet ( G4int index,
G4int iv1,
G4int iv2,
G4int iv3,
G4int iv4 = 0 )

Definition at line 305 of file HepPolyhedron.cc.

314{
315 if (index < 1 || index > nface)
316 {
317 std::cerr
318 << "HepPolyhedron::SetFacet: facet index = " << index
319 << " is out of range\n"
320 << " N. of vertices = " << nvert << "\n"
321 << " N. of facets = " << nface << std::endl;
322 return;
323 }
324 if (iv1 < 1 || iv1 > nvert ||
325 iv2 < 1 || iv2 > nvert ||
326 iv3 < 1 || iv3 > nvert ||
327 iv4 < 0 || iv4 > nvert)
328 {
329 std::cerr
330 << "HepPolyhedron::SetFacet: incorrectly specified facet"
331 << " (" << iv1 << ", " << iv2 << ", " << iv3 << ", " << iv4 << ")\n"
332 << " N. of vertices = " << nvert << "\n"
333 << " N. of facets = " << nface << std::endl;
334 return;
335 }
336 pF[index] = G4Facet(iv1, 0, iv2, 0, iv3, 0, iv4, 0);
337}

Referenced by G4GenericTrap::CreatePolyhedron(), HepPolyhedronBoxMesh::HepPolyhedronBoxMesh(), and HepPolyhedronTetMesh::HepPolyhedronTetMesh().

◆ SetNumberOfRotationSteps()

void HepPolyhedron::SetNumberOfRotationSteps ( G4int n)
static

Definition at line 339 of file HepPolyhedron.cc.

348{
349 const G4int nMin = 3;
350 if (n < nMin) {
351 std::cerr
352 << "HepPolyhedron::SetNumberOfRotationSteps: attempt to set the\n"
353 << "number of steps per circle < " << nMin << "; forced to " << nMin
354 << std::endl;
356 }else{
358 }
359}

Referenced by G4ArrowModel::G4ArrowModel(), and G4VSceneHandler::RequestPrimitives().

◆ SetReferences()

void HepPolyhedron::SetReferences ( )

Definition at line 1115 of file HepPolyhedron.cc.

1124{
1125 if (nface <= 0) return;
1126
1127 struct edgeListMember {
1128 edgeListMember *next;
1129 G4int v2;
1130 G4int iface;
1131 G4int iedge;
1132 } *edgeList, *freeList, **headList;
1133
1134
1135 // A L L O C A T E A N D I N I T I A T E L I S T S
1136
1137 edgeList = new edgeListMember[2*nface];
1138 headList = new edgeListMember*[nvert];
1139
1140 G4int i;
1141 for (i=0; i<nvert; i++) {
1142 headList[i] = nullptr;
1143 }
1144 freeList = edgeList;
1145 for (i=0; i<2*nface-1; i++) {
1146 edgeList[i].next = &edgeList[i+1];
1147 }
1148 edgeList[2*nface-1].next = nullptr;
1149
1150 // L O O P A L O N G E D G E S
1151
1152 G4int iface, iedge, nedge, i1, i2, k1, k2;
1153 edgeListMember *prev, *cur;
1154
1155 for(iface=1; iface<=nface; iface++) {
1156 nedge = (pF[iface].edge[3].v == 0) ? 3 : 4;
1157 for (iedge=0; iedge<nedge; iedge++) {
1158 i1 = iedge;
1159 i2 = (iedge < nedge-1) ? iedge+1 : 0;
1160 i1 = std::abs(pF[iface].edge[i1].v);
1161 i2 = std::abs(pF[iface].edge[i2].v);
1162 k1 = (i1 < i2) ? i1 : i2; // k1 = ::min(i1,i2);
1163 k2 = (i1 > i2) ? i1 : i2; // k2 = ::max(i1,i2);
1164
1165 // check head of the List corresponding to k1
1166 cur = headList[k1];
1167 if (cur == nullptr) {
1168 headList[k1] = freeList;
1169 if (freeList == nullptr) {
1170 std::cerr
1171 << "Polyhedron::SetReferences: bad link "
1172 << std::endl;
1173 break;
1174 }
1175 freeList = freeList->next;
1176 cur = headList[k1];
1177 cur->next = nullptr;
1178 cur->v2 = k2;
1179 cur->iface = iface;
1180 cur->iedge = iedge;
1181 continue;
1182 }
1183
1184 if (cur->v2 == k2) {
1185 headList[k1] = cur->next;
1186 cur->next = freeList;
1187 freeList = cur;
1188 pF[iface].edge[iedge].f = cur->iface;
1189 pF[cur->iface].edge[cur->iedge].f = iface;
1190 i1 = (pF[iface].edge[iedge].v < 0) ? -1 : 1;
1191 i2 = (pF[cur->iface].edge[cur->iedge].v < 0) ? -1 : 1;
1192 if (i1 != i2) {
1193 std::cerr
1194 << "Polyhedron::SetReferences: different edge visibility "
1195 << iface << "/" << iedge << "/"
1196 << pF[iface].edge[iedge].v << " and "
1197 << cur->iface << "/" << cur->iedge << "/"
1198 << pF[cur->iface].edge[cur->iedge].v
1199 << std::endl;
1200 }
1201 continue;
1202 }
1203
1204 // check List itself
1205 for (;;) {
1206 prev = cur;
1207 cur = prev->next;
1208 if (cur == nullptr) {
1209 prev->next = freeList;
1210 if (freeList == nullptr) {
1211 std::cerr
1212 << "Polyhedron::SetReferences: bad link "
1213 << std::endl;
1214 break;
1215 }
1216 freeList = freeList->next;
1217 cur = prev->next;
1218 cur->next = nullptr;
1219 cur->v2 = k2;
1220 cur->iface = iface;
1221 cur->iedge = iedge;
1222 break;
1223 }
1224
1225 if (cur->v2 == k2) {
1226 prev->next = cur->next;
1227 cur->next = freeList;
1228 freeList = cur;
1229 pF[iface].edge[iedge].f = cur->iface;
1230 pF[cur->iface].edge[cur->iedge].f = iface;
1231 i1 = (pF[iface].edge[iedge].v < 0) ? -1 : 1;
1232 i2 = (pF[cur->iface].edge[cur->iedge].v < 0) ? -1 : 1;
1233 if (i1 != i2) {
1234 std::cerr
1235 << "Polyhedron::SetReferences: different edge visibility "
1236 << iface << "/" << iedge << "/"
1237 << pF[iface].edge[iedge].v << " and "
1238 << cur->iface << "/" << cur->iedge << "/"
1239 << pF[cur->iface].edge[cur->iedge].v
1240 << std::endl;
1241 }
1242 break;
1243 }
1244 }
1245 }
1246 }
1247
1248 // C H E C K T H A T A L L L I S T S A R E E M P T Y
1249
1250 for (i=0; i<nvert; i++) {
1251 if (headList[i] != nullptr) {
1252 std::cerr
1253 << "Polyhedron::SetReferences: List " << i << " is not empty"
1254 << std::endl;
1255 }
1256 }
1257
1258 // F R E E M E M O R Y
1259
1260 delete [] edgeList;
1261 delete [] headList;
1262}

Referenced by G4GenericTrap::CreatePolyhedron(), createPolyhedron(), HepPolyhedronBoxMesh::HepPolyhedronBoxMesh(), HepPolyhedronCons::HepPolyhedronCons(), HepPolyhedronEllipsoid::HepPolyhedronEllipsoid(), HepPolyhedronEllipticalCone::HepPolyhedronEllipticalCone(), HepPolyhedronHype::HepPolyhedronHype(), HepPolyhedronHyperbolicMirror::HepPolyhedronHyperbolicMirror(), HepPolyhedronParaboloid::HepPolyhedronParaboloid(), HepPolyhedronPgon::HepPolyhedronPgon(), HepPolyhedronPgon::HepPolyhedronPgon(), HepPolyhedronSphere::HepPolyhedronSphere(), HepPolyhedronTetMesh::HepPolyhedronTetMesh(), HepPolyhedronTorus::HepPolyhedronTorus(), JoinCoplanarFacets(), and G4PolyhedronArbitrary::SetReferences().

◆ SetSideFacets()

void HepPolyhedron::SetSideFacets ( G4int ii[4],
G4int vv[4],
G4int * kk,
G4double * r,
G4double dphi,
G4int ns,
G4int & kface )
protected

Definition at line 482 of file HepPolyhedron.cc.

501{
502 G4int k1, k2, k3, k4;
503
504 if (std::abs(dphi-pi) < perMillion) { // half a circle
505 for (G4int i=0; i<4; i++) {
506 k1 = ii[i];
507 k2 = ii[(i+1)%4];
508 if (r[k1] == 0. && r[k2] == 0.) vv[i] = -1;
509 }
510 }
511
512 if (ii[1] == ii[2]) {
513 k1 = kk[ii[0]];
514 k2 = kk[ii[2]];
515 k3 = kk[ii[3]];
516 pF[kface++] = G4Facet(vv[0]*k1,0, vv[2]*k2,0, vv[3]*k3,0);
517 if (r[ii[0]] != 0.) k1 += nds;
518 if (r[ii[2]] != 0.) k2 += nds;
519 if (r[ii[3]] != 0.) k3 += nds;
520 pF[kface++] = G4Facet(vv[2]*k3,0, vv[0]*k2,0, vv[3]*k1,0);
521 }else if (kk[ii[0]] == kk[ii[1]]) {
522 k1 = kk[ii[0]];
523 k2 = kk[ii[2]];
524 k3 = kk[ii[3]];
525 pF[kface++] = G4Facet(vv[1]*k1,0, vv[2]*k2,0, vv[3]*k3,0);
526 if (r[ii[0]] != 0.) k1 += nds;
527 if (r[ii[2]] != 0.) k2 += nds;
528 if (r[ii[3]] != 0.) k3 += nds;
529 pF[kface++] = G4Facet(vv[2]*k3,0, vv[1]*k2,0, vv[3]*k1,0);
530 }else if (kk[ii[2]] == kk[ii[3]]) {
531 k1 = kk[ii[0]];
532 k2 = kk[ii[1]];
533 k3 = kk[ii[2]];
534 pF[kface++] = G4Facet(vv[0]*k1,0, vv[1]*k2,0, vv[3]*k3,0);
535 if (r[ii[0]] != 0.) k1 += nds;
536 if (r[ii[1]] != 0.) k2 += nds;
537 if (r[ii[2]] != 0.) k3 += nds;
538 pF[kface++] = G4Facet(vv[1]*k3,0, vv[0]*k2,0, vv[3]*k1,0);
539 }else{
540 k1 = kk[ii[0]];
541 k2 = kk[ii[1]];
542 k3 = kk[ii[2]];
543 k4 = kk[ii[3]];
544 pF[kface++] = G4Facet(vv[0]*k1,0, vv[1]*k2,0, vv[2]*k3,0, vv[3]*k4,0);
545 if (r[ii[0]] != 0.) k1 += nds;
546 if (r[ii[1]] != 0.) k2 += nds;
547 if (r[ii[2]] != 0.) k3 += nds;
548 if (r[ii[3]] != 0.) k4 += nds;
549 pF[kface++] = G4Facet(vv[2]*k4,0, vv[1]*k3,0, vv[0]*k2,0, vv[3]*k1,0);
550 }
551}

Referenced by RotateAroundZ(), and RotateContourAroundZ().

◆ SetVertex()

void HepPolyhedron::SetVertex ( G4int index,
const G4Point3D & v )

Definition at line 282 of file HepPolyhedron.cc.

291{
292 if (index < 1 || index > nvert)
293 {
294 std::cerr
295 << "HepPolyhedron::SetVertex: vertex index = " << index
296 << " is out of range\n"
297 << " N. of vertices = " << nvert << "\n"
298 << " N. of facets = " << nface << std::endl;
299 return;
300 }
301 pV[index] = v;
302}

Referenced by G4GenericTrap::CreatePolyhedron(), HepPolyhedronBoxMesh::HepPolyhedronBoxMesh(), and HepPolyhedronTetMesh::HepPolyhedronTetMesh().

◆ subtract()

HepPolyhedron HepPolyhedron::subtract ( const HepPolyhedron & p) const

Definition at line 3391 of file HepPolyhedron.cc.

3400{
3401 G4int ierr;
3402 BooleanProcessor processor;
3403 return processor.execute(OP_SUBTRACTION, *this, p,ierr);
3404}

◆ Transform()

HepPolyhedron & HepPolyhedron::Transform ( const G4Transform3D & t)

Definition at line 1379 of file HepPolyhedron.cc.

1388{
1389 if (nvert > 0) {
1390 for (G4int i=1; i<=nvert; i++) { pV[i] = t * pV[i]; }
1391
1392 // C H E C K D E T E R M I N A N T A N D
1393 // I N V E R T F A C E T S I F I T I S N E G A T I V E
1394
1395 G4Vector3D d = t * G4Vector3D(0,0,0);
1396 G4Vector3D x = t * G4Vector3D(1,0,0) - d;
1397 G4Vector3D y = t * G4Vector3D(0,1,0) - d;
1398 G4Vector3D z = t * G4Vector3D(0,0,1) - d;
1399 if ((x.cross(y))*z < 0) InvertFacets();
1400 }
1401 return *this;
1402}
HepGeom::Vector3D< G4double > G4Vector3D
Definition G4Vector3D.hh:34
BasicVector3D< T > cross(const BasicVector3D< T > &v) const

Referenced by G4GMocrenFileSceneHandler::AddSolid(), G4DisplacedSolid::CreatePolyhedron(), G4EllipticalTube::CreatePolyhedron(), G4ReflectedSolid::CreatePolyhedron(), G4ScaledSolid::CreatePolyhedron(), G4ScoringBox::Draw(), G4ScoringCylinder::Draw(), G4ScoringBox::DrawColumn(), G4ScoringCylinder::DrawColumn(), G4ArrowModel::G4ArrowModel(), and G4ASCIITreeSceneHandler::RequestPrimitives().

◆ TriangulatePolygon()

G4bool HepPolyhedron::TriangulatePolygon ( const std::vector< G4TwoVector > & polygon,
std::vector< G4int > & result )
protected

Definition at line 985 of file HepPolyhedron.cc.

1002{
1003 result.resize(0);
1004 G4int n = (G4int)polygon.size();
1005 if (n < 3) return false;
1006
1007 // calculate area
1008 //
1009 G4double area = 0.;
1010 for(G4int i = 0; i < n; ++i)
1011 {
1012 G4int k = (i == 0) ? n - 1 : i - 1;
1013 area += polygon[k].x()*polygon[i].y() - polygon[i].x()*polygon[k].y();
1014 }
1015
1016 // allocate and initialize list of Vertices
1017 // we want a counter-clockwise polygon in V
1018 //
1019 auto V = new G4int[n];
1020 if (area > 0.)
1021 for (G4int i = 0; i < n; ++i) V[i] = i;
1022 else
1023 for (G4int i = 0; i < n; ++i) V[i] = (n - 1) - i;
1024
1025 // Triangulation: remove nv-2 Vertices, creating 1 triangle every time
1026 //
1027 G4int nv = n;
1028 G4int count = 2*nv; // error detection counter
1029 for(G4int b = nv - 1; nv > 2; )
1030 {
1031 // ERROR: if we loop, it is probably a non-simple polygon
1032 if ((count--) <= 0)
1033 {
1034 delete [] V;
1035 if (area < 0.) std::reverse(result.begin(),result.end());
1036 return false;
1037 }
1038
1039 // three consecutive vertices in current polygon, <a,b,c>
1040 G4int a = (b < nv) ? b : 0; // previous
1041 b = (a+1 < nv) ? a+1 : 0; // current
1042 G4int c = (b+1 < nv) ? b+1 : 0; // next
1043
1044 if (CheckSnip(polygon, a,b,c, nv,V))
1045 {
1046 // output Triangle
1047 result.push_back(V[a]);
1048 result.push_back(V[b]);
1049 result.push_back(V[c]);
1050
1051 // remove vertex b from remaining polygon
1052 nv--;
1053 for(G4int i = b; i < nv; ++i) V[i] = V[i+1];
1054
1055 count = 2*nv; // resest error detection counter
1056 }
1057 }
1058 delete [] V;
1059 if (area < 0.) std::reverse(result.begin(),result.end());
1060 return true;
1061}
G4bool CheckSnip(const std::vector< G4TwoVector > &contour, G4int a, G4int b, G4int c, G4int n, const G4int *V)

Referenced by RotateContourAroundZ().

◆ vertexUnweightedMean()

G4Point3D HepPolyhedron::vertexUnweightedMean ( ) const

Calculate the unweighted mean of all the vertices in the polyhedron. Not to be confused with the polyhedron centre or centre of mass

Returns
G4Point3D of the unweighted mean vertex position

Definition at line 1932 of file HepPolyhedron.cc.

1932 {
1933 /***********************************************************************
1934 * *
1935 * Name: vertexUnweightedMean Date: 23.10.23 *
1936 * Author: S. Boogert (Manchester) Revised: *
1937 * *
1938 * Function: Calculate the unweighted mean of all the vertices *
1939 * in the polyhedron. Not to be confused with the polyhedron centre or *
1940 * centre of mass *
1941 ***********************************************************************/
1942
1943 auto centre = G4Point3D();
1944 for(int i=1;i<=nvert;i++) {
1945 centre += pV[i];
1946 }
1947 centre = centre/nvert;
1948 return centre;
1949}

Referenced by G4VtkStore::AddPrimitiveAppend(), G4VtkStore::AddPrimitiveTensorGlyph(), and G4VtkStore::AddPrimitiveTransformBake().

Friends And Related Symbol Documentation

◆ operator<<

std::ostream & operator<< ( std::ostream & ostr,
const HepPolyhedron & ph )
friend

Definition at line 105 of file HepPolyhedron.cc.

105 {
106 ostr << std::endl;
107 ostr << "Nvertices=" << ph.nvert << ", Nfacets=" << ph.nface << std::endl;
108 G4int i;
109 for (i=1; i<=ph.nvert; i++) {
110 ostr << "xyz(" << i << ")="
111 << ph.pV[i].x() << ' ' << ph.pV[i].y() << ' ' << ph.pV[i].z()
112 << std::endl;
113 }
114 for (i=1; i<=ph.nface; i++) {
115 ostr << "face(" << i << ")=" << ph.pF[i] << std::endl;
116 }
117 return ostr;
118}

Member Data Documentation

◆ fNumberOfRotationSteps

G4ThreadLocal G4int HepPolyhedron::fNumberOfRotationSteps = DEFAULT_NUMBER_OF_STEPS
staticprotected

◆ nface

◆ nvert

◆ pF

◆ pV


The documentation for this class was generated from the following files: