49 #if !defined(G4GEOM_USE_UEXTRUDEDSOLID)
71 const std::vector<G4TwoVector>& polygon,
72 const std::vector<ZSection>& zsections)
75 fNz(zsections.size()),
80 fGeometryType(
"G4ExtrudedSolid")
89 std::ostringstream message;
90 message <<
"Number of vertices in polygon < 3 - " << pName;
91 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
97 std::ostringstream message;
98 message <<
"Number of z-sides < 2 - " << pName;
99 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
105 if ( zsections[i].fZ > zsections[i+1].fZ )
107 std::ostringstream message;
108 message <<
"Z-sections have to be ordered by z value (z0 < z1 < z2...) - "
110 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
115 std::ostringstream message;
116 message <<
"Z-sections with the same z position are not supported - "
118 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0001",
129 std::vector<G4int> removedVertices;
132 if (removedVertices.size() != 0)
134 G4int nremoved = removedVertices.size();
135 std::ostringstream message;
136 message <<
"The following "<< nremoved
137 <<
" vertices have been removed from polygon in " << pName
138 <<
"\nas collinear or coincident with other vertices: "
139 << removedVertices[0];
140 for (
G4int i=1; i<nremoved; ++i) message <<
", " << removedVertices[i];
141 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids1001",
148 std::ostringstream message;
149 message <<
"Number of vertices in polygon after removal < 3 - " << pName;
150 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
173 std::ostringstream message;
174 message <<
"Making facets failed - " << pName;
175 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0003",
186 const std::vector<G4TwoVector>& polygon,
197 fGeometryType(
"G4ExtrudedSolid")
206 std::ostringstream message;
207 message <<
"Number of vertices in polygon < 3 - " << pName;
208 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
218 std::vector<G4int> removedVertices;
221 if (removedVertices.size() != 0)
223 G4int nremoved = removedVertices.size();
224 std::ostringstream message;
225 message <<
"The following "<< nremoved
226 <<
" vertices have been removed from polygon in " << pName
227 <<
"\nas collinear or coincident with other vertices: "
228 << removedVertices[0];
229 for (
G4int i=1; i<nremoved; ++i) message <<
", " << removedVertices[i];
230 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids1001",
237 std::ostringstream message;
238 message <<
"Number of vertices in polygon after removal < 3 - " << pName;
239 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
263 std::ostringstream message;
264 message <<
"Making facets failed - " << pName;
265 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0003",
277 fTriangles(), fIsConvex(false), fGeometryType(
"G4ExtrudedSolid")
287 fPolygon(rhs.fPolygon), fZSections(rhs.fZSections),
288 fTriangles(rhs.fTriangles), fIsConvex(rhs.fIsConvex),
289 fGeometryType(rhs.fGeometryType), fKScales(rhs.fKScales),
290 fScale0s(rhs.fScale0s), fKOffsets(rhs.fKOffsets), fOffset0s(rhs.fOffset0s)
301 if (
this == &rhs) {
return *
this; }
347 G4double kscale = (scale2 - scale1)/(z2 - z1);
348 G4double scale0 = scale2 - kscale*(z2 - z1)/2.0;
386 while ( point.z() >
fZSections[iz+1].fZ && iz <
fNz-2 ) { ++iz; }
401 return (p2 - poffset)/pscale;
412 if ( l1.x() == l2.x() )
416 G4double slope= ((l2.y() - l1.y())/(l2.x() - l1.x()));
417 G4double predy= l1.y() + slope *(p.x() - l1.x());
427 G4bool squareComp = (dy*dy < (1+slope*slope)
463 return ( (p1.x() - l1.x()) * (l2.y() - l1.y())
464 - (l2.x() - l1.x()) * (p1.y() - l1.y()) )
465 * ( (p2.x() - l1.x()) * (l2.y() - l1.y())
466 - (l2.x() - l1.x()) * (p2.y() - l1.y()) ) > 0;
481 if ( ( p.x() < a.x() && p.x() < b.x() && p.x() < c.x() ) ||
482 ( p.x() > a.x() && p.x() > b.x() && p.x() > c.x() ) ||
483 ( p.y() < a.y() && p.y() < b.y() && p.y() < c.y() ) ||
484 ( p.y() > a.y() && p.y() > b.y() && p.y() > c.y() ) )
return false;
496 return inside || onEdge;
511 G4double result = (std::atan2(t1.y(), t1.x()) - std::atan2(t2.y(), t2.x()));
513 if ( result < 0 ) result += 2*
pi;
526 std::vector<G4ThreeVector> vertices;
534 = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[1]);
536 if ( cross.z() > 0.0 )
544 vertices[1] = vertices[2];
560 std::vector<G4ThreeVector> vertices;
568 = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[1]);
570 if ( cross.z() < 0.0 )
578 vertices[1] = vertices[2];
592 typedef std::pair < G4TwoVector, G4int > Vertex;
594 static const G4double kAngTolerance =
599 std::vector< Vertex > verticesToBeDone;
602 verticesToBeDone.push_back(Vertex(
fPolygon[i], i));
604 std::vector< Vertex > ears;
606 std::vector< Vertex >::iterator c1 = verticesToBeDone.begin();
607 std::vector< Vertex >::iterator
c2 = c1+1;
608 std::vector< Vertex >::iterator c3 = c1+2;
609 while ( verticesToBeDone.size()>2 )
626 while ( angle >= (
pi-kAngTolerance) )
635 if ( c3 == verticesToBeDone.end() ) { c3 = verticesToBeDone.begin(); }
641 angle =
GetAngle(c2->first, c3->first, c1->first);
646 if ( counter > fNv) {
647 G4Exception(
"G4ExtrudedSolid::AddGeneralPolygonFacets",
649 "Triangularisation has failed.");
655 std::vector< Vertex >::iterator it;
656 for ( it=verticesToBeDone.begin(); it != verticesToBeDone.end(); ++it )
660 if ( it == c1 || it == c2 || it == c3 ) {
continue; }
662 if (
IsPointInside(c1->first, c2->first, c3->first, it->first) )
672 if ( c3 == verticesToBeDone.end() ) { c3 = verticesToBeDone.begin(); }
688 if ( ! result ) {
return false; }
691 if ( ! result ) {
return false; }
693 std::vector<G4int> triangle(3);
694 triangle[0] = c1->second;
695 triangle[1] = c2->second;
696 triangle[2] = c3->second;
701 verticesToBeDone.erase(c2);
702 c1 = verticesToBeDone.begin();
724 if ( ! good ) {
return false; }
730 if ( ! good ) {
return false; }
732 std::vector<G4int> triangle(3);
744 if ( ! good ) {
return false; }
751 if ( ! good ) {
return false; }
753 std::vector<G4int> triangle1(3);
759 std::vector<G4int> triangle2(3);
768 if ( ! good ) {
return false; }
773 for (
G4int iz = 0; iz <
fNz-1; ++iz )
777 G4int j = (i+1) % fNv;
781 if ( ! good ) {
return false; }
835 G4int j = (i+1) % fNv;
847 std::vector< std::vector<G4int> >::const_iterator it =
fTriangles.begin();
852 fPolygon[(*it)[2]], pscaled) ) { inside =
true; }
854 }
while ( (inside ==
false) && (it !=
fTriangles.end()) );
892 if (validNorm) { *validNorm =
fIsConvex; }
919 if (x < xmin0) xmin0 = x;
920 if (x > xmax0) xmax0 = x;
922 if (y < ymin0) ymin0 = y;
923 if (y > ymax0) ymax0 = y;
930 for (
G4int i=0; i<nsect; ++i)
936 xmin =
std::min(xmin,xmin0*scale+dx);
937 xmax =
std::max(xmax,xmax0*scale+dx);
938 ymin =
std::min(ymin,ymin0*scale+dy);
939 ymax =
std::max(ymax,ymax0*scale+dy);
945 pMin.set(xmin,ymin,zmin);
946 pMax.set(xmax,ymax,zmax);
950 if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
952 std::ostringstream message;
953 message <<
"Bad bounding box (min >= max) for solid: "
955 <<
"\npMin = " << pMin
956 <<
"\npMax = " << pMax;
981 if (
true)
return bbox.
CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
985 return exist = (pMin < pMax) ?
true :
false;
999 std::ostringstream message;
1000 message <<
"Triangulation of the base polygon has failed for solid: "
1002 <<
"\nExtent has been calculated using boundary box";
1010 std::vector<const G4ThreeVectorList *> polygons;
1011 polygons.resize(nsect);
1017 G4int ntria = triangles.size()/3;
1018 for (
G4int i=0; i<ntria; ++i)
1021 for (
G4int k=0; k<nsect; ++k)
1030 G4ThreeVectorList::iterator iter = ptr->begin();
1031 G4double x0 = triangles[i3+0].x()*scale+dx;
1032 G4double y0 = triangles[i3+0].y()*scale+dy;
1035 G4double x1 = triangles[i3+1].x()*scale+dx;
1036 G4double y1 = triangles[i3+1].y()*scale+dy;
1039 G4double x2 = triangles[i3+2].x()*scale+dx;
1040 G4double y2 = triangles[i3+2].y()*scale+dy;
1047 if (!benv.
CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
1048 if (emin < pMin) pMin = emin;
1049 if (emax > pMax) pMax =
emax;
1050 if (eminlim > pMin && emaxlim < pMax)
break;
1053 for (
G4int k=0; k<nsect; ++k) {
delete polygons[k]; polygons[k]=0;}
1054 return (pMin < pMax);
1061 G4int oldprc = os.precision(16);
1062 os <<
"-----------------------------------------------------------\n"
1063 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
1064 <<
" ===================================================\n"
1068 { os <<
" Convex polygon; list of vertices:" <<
G4endl; }
1070 { os <<
" Concave polygon; list of vertices:" <<
G4endl; }
1074 os << std::setw(5) <<
"#" << i
1079 os <<
" Sections:" <<
G4endl;
1104 os.precision(oldprc);
static c2_factory< G4double > c2
G4GeometryType GetEntityType() const
void SetSolidClosed(const G4bool t)
void Extent(G4ThreeVector &pMin, G4ThreeVector &pMax) const
static constexpr double mm
static const G4double kInfinity
CLHEP::Hep3Vector G4ThreeVector
std::vector< G4TwoVector > fOffset0s
std::vector< G4double > fScale0s
std::vector< ExP01TrackerHit * > a
G4double GetMaxXExtent() const
std::vector< ZSection > fZSections
static G4double angle[DIM]
G4ExtrudedSolid(const G4String &pName, const std::vector< G4TwoVector > &polygon, const std::vector< ZSection > &zsections)
G4double GetMinXExtent() const
G4bool IsSameSide(const G4TwoVector &p1, const G4TwoVector &p2, const G4TwoVector &l1, const G4TwoVector &l2) const
virtual ~G4ExtrudedSolid()
EInside Inside(const G4ThreeVector &p) const
G4double GetMaxZExtent() const
G4TwoVector ProjectPoint(const G4ThreeVector &point) const
G4bool AddGeneralPolygonFacets()
G4TwoVector GetVertex(G4int index) const
G4double GetAngle(const G4TwoVector &p0, const G4TwoVector &pa, const G4TwoVector &pb) const
G4double kCarToleranceHalf
G4double GetMinZExtent() const
void ComputeProjectionParameters()
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const
virtual G4double DistanceToOut(const G4ThreeVector &p) const
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const
G4int GetNofVertices() const
G4bool AddFacet(G4VFacet *aFacet)
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4bool BoundingBoxVsVoxelLimits(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
std::vector< G4double > fKScales
std::vector< G4ThreeVector > G4ThreeVectorList
G4int GetNofZSections() const
std::ostream & StreamInfo(std::ostream &os) const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
static const G4double emax
T max(const T t1, const T t2)
brief Return the largest of the two arguments
std::vector< G4TwoVector > fKOffsets
ZSection GetZSection(G4int index) const
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
G4bool IsPointInside(const G4TwoVector &a, const G4TwoVector &b, const G4TwoVector &c, const G4TwoVector &p) const
CLHEP::Hep2Vector G4TwoVector
static constexpr double pi
G4bool IsSameLine(const G4TwoVector &p, const G4TwoVector &l1, const G4TwoVector &l2) const
G4double GetMaxExtent(const EAxis pAxis) const
G4VFacet * MakeUpFacet(G4int ind1, G4int ind2, G4int ind3) const
G4GeometryType fGeometryType
G4bool IsSameLineSegment(const G4TwoVector &p, const G4TwoVector &l1, const G4TwoVector &l2) const
G4double GetMaxYExtent() const
G4double GetAngularTolerance() const
G4ExtrudedSolid & operator=(const G4ExtrudedSolid &rhs)
G4double GetMinExtent(const EAxis pAxis) const
static G4GeometryTolerance * GetInstance()
G4VFacet * MakeDownFacet(G4int ind1, G4int ind2, G4int ind3) const
G4double GetMinYExtent() const
std::vector< std::vector< G4int > > fTriangles
G4TessellatedSolid & operator=(const G4TessellatedSolid &right)
std::vector< G4TwoVector > fPolygon