109 fSeg(0), fIz(0), fXc(0), fYc(0), fPoly(0)
136 std::lock_guard<std::mutex> guard(
fMutex);
137 std::vector<ThreadData_t*>::iterator i =
fThreadData.begin();
152 std::lock_guard<std::mutex> guard(
fMutex);
155 for (
Int_t tid=0; tid<nthreads; tid++) {
167 Error(
"DefinePolygon",
"Shape %s of type XTRU has an illegal polygon.",
GetName());
227 Error(
"ctor",
"Cannot create TGeoXtru %s with less than 2 Z planes",
GetName());
270 if (
fX) {
delete[]
fX;
fX = 0;}
271 if (
fY) {
delete[]
fY;
fY = 0;}
272 if (
fZ) {
delete[]
fZ;
fZ = 0;}
291 for (iz=0; iz<
fNz-1; iz++) {
292 dz =
fZ[iz+1]-
fZ[iz];
296 capacity += (area*dz/3.)*(sc1*sc1+sc1*sc2+sc2*sc2);
308 Error(
"ComputeBBox",
"In shape %s polygon not defined",
GetName());
332 fDZ = 0.5*(zmax-zmin);
343 norm[2] = (dir[2]>0)?1:-1;
349 Double_t ndotd = norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2];
420 snext = (
fZ[iz]-point[2])/dir[2];
432 Double_t ndotd = norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2];
435 safe = (vert[0]-point[0])*norm[0]+
436 (vert[1]-point[1])*norm[1]+
437 (vert[2]-point[2])*norm[2];
442 safe = (point[0]-vert[0])*norm[0]+
443 (point[1]-vert[1])*norm[1]+
444 (point[2]-vert[2])*norm[2];
449 if (
fZ[iz]<
fZ[iz+1]) {
450 znew = point[2] +
snext*dir[2];
468 if (iact<3 && safe) {
502 Int_t iv, ipl, inext;
505 for (iv=0; iv<
fNvert; iv++) {
511 if (convex)
return snext;
519 Int_t incseg = (dir[2]>0)?1:-1;
522 while (iz>=0 && iz<
fNz-1) {
524 ipl = iz+((incseg+1)>>1);
526 sz = (
fZ[ipl]-point[2])/dir[2];
530 pt[0] = point[0]+sz*dir[0];
531 pt[1] = point[1]+sz*dir[1];
535 if (ipl==0 || ipl==
fNz-1) {
537 if (convex)
return sz;
547 if (convex)
return sz;
559 for (iv=0; iv<
fNvert; iv++) {
565 if (convex)
return snext;
569 if (zexit)
return snext;
582 if (iact<3 && safe) {
602 snext = (
fZ[0] - point[2])/dir[2];
604 for (i=0; i<3; i++)
pt[i] = point[i] +
snext*dir[i];
618 for (i=0; i<3; i++)
pt[i] = point[i] +
snext*dir[i];
632 if (dist>1E-6) dist-=1E-6;
634 for (i=0; i<3; i++)
pt[i] += dist*dir[i];
637 else if (iz==
fNz-1) iz =
fNz-2;
649 for (iv=0; iv<
fNvert; iv++) {
653 if (convex)
return (
snext+dist);
658 if (hit)
return (
snext+stepmax);
662 Int_t incseg = (dir[2]>0)?1:-1;
663 while (iz>=0 && iz<
fNz-1) {
667 for (iv=0; iv<
fNvert; iv++) {
672 if (convex)
return (
snext+dist);
677 if (hit)
return (
snext+stepmax);
694 Error(
"DefinePolygon",
"In shape %s cannot create polygon with less than 3 vertices",
GetName());
698 for (
Int_t i=0; i<nvert-1; i++) {
699 for (
Int_t j=i+1; j<nvert; j++) {
702 Error(
"DefinePolygon",
"In shape %s 2 vertices cannot be identical",
GetName());
709 if (
fX)
delete []
fX;
711 if (
fY)
delete []
fY;
726 if ((snum<0) || (snum>=
fNz))
return;
732 if (
fZ[snum]<
fZ[snum-1]) {
733 Warning(
"DefineSection",
"In shape: %s, Z position of section "
734 "%i, z=%e, not in increasing order, %i, z=%e",
750 if (ipl<0 || ipl>(
fNz-1)) {
751 Error(
"GetZ",
"In shape %s, ipl=%i out of range (0,%i)",
GetName(),ipl,
fNz-1);
764 v1[0] = vert[9]-vert[0];
765 v1[1] = vert[10]-vert[1];
766 v1[2] = vert[11]-vert[2];
767 v2[0] = vert[3]-vert[0];
768 v2[1] = vert[4]-vert[1];
769 v2[2] = vert[5]-vert[2];
771 cross += norm[0]*norm[0];
773 cross += norm[1]*norm[1];
775 cross += norm[2]*norm[2];
778 for (
Int_t i=0; i<3; i++) norm[i] *= cross;
845 for (
Int_t i=0; i<4; i++) {
848 v1[0] = point[0]-vert[j];
849 v1[1] = point[1]-vert[j+1];
850 v1[2] = point[2]-vert[j+2];
851 v2[0] = vert[k]-vert[j];
852 v2[1] = vert[k+1]-vert[j+1];
853 v2[2] = vert[k+2]-vert[j+2];
854 cross = (
v1[1]*
v2[2]-
v1[2]*
v2[1])*norm[0]+
857 if (cross<0)
return kFALSE;
867 printf(
"*** Shape %s: TGeoXtru ***\n",
GetName());
868 printf(
" Nz = %i\n",
fNz);
869 printf(
" List of (x,y) of polygon vertices:\n");
871 printf(
" x = %11.5f y = %11.5f\n",
fX[ivert],
fY[ivert]);
873 printf(
" plane %i: z=%11.5f x0=%11.5f y0=%11.5f scale=%11.5f\n", ipl,
fZ[ipl],
fX0[ipl],
fY0[ipl],
fScale[ipl]);
874 printf(
" Bounding box:\n");
886 Int_t nbPnts = nz*nvert;
887 Int_t nbSegs = nvert*(2*nz-1);
888 Int_t nbPols = nvert*(nz-1)+2;
891 nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*(nbPols-2)+2*(2+nvert));
911 Int_t indx = 0, indx2, k;
912 for (i=0; i<nz; i++) {
916 for (j=0; j<nvert; j++) {
919 buff.
fSegs[indx++] = indx2+j;
920 buff.
fSegs[indx++] = indx2+k;
923 for (i=0; i<nz-1; i++) {
927 for (j=0; j<nvert; j++) {
930 buff.
fSegs[indx++] = indx2+j;
931 buff.
fSegs[indx++] = indx2+k;
938 for (i=0; i<nz-1; i++) {
940 for (j=0; j<nvert; j++) {
942 buff.
fPols[indx++] =
c+j%3;
943 buff.
fPols[indx++] = 4;
944 buff.
fPols[indx++] = indx2+j;
945 buff.
fPols[indx++] = nz*nvert+indx2+k;
946 buff.
fPols[indx++] = indx2+nvert+j;
947 buff.
fPols[indx++] = nz*nvert+indx2+j;
951 buff.
fPols[indx++] = nvert;
953 for (j = nvert - 1; j >= 0; --j) {
954 buff.
fPols[indx++] = indx2+j;
958 buff.
fPols[indx++] = nvert;
959 indx2 = (nz-1)*nvert;
961 for (j=0; j<nvert; j++) {
962 buff.
fPols[indx++] = indx2+j;
986 if ((in1&!in2)|(in2&!in1)) {
996 safz =
fZ[iz]-point[2];
999 saf1 = point[2]-
fZ[iz+1];
1013 for (iseg=0; iseg<
fNvert; iseg++) {
1016 saf1 = (point[0]-vert[0])*norm[0]+(point[1]-vert[1])*norm[1]+(point[2]-vert[2])*norm[2];
1017 if (in) saf1 = -saf1;
1019 if (saf1<-1.E-8)
continue;
1022 if (safe>safmin)
continue;
1026 if (found)
return safmin;
1044 for (iz=0; iz<
fNz-1; iz++) {
1046 if (safe<safmin) safmin = safe;
1055 safz =
fZ[0] - point[2];
1059 safz = point[2] -
fZ[
fNz-1];
1064 for (i=iz; i<
fNz-1; i++) {
1066 if (safe<safmin) safmin=safe;
1069 for (i=iz-1; i>=0; i--) {
1071 if (safe<safmin) safmin=safe;
1083 out <<
" // Shape: " <<
GetName() <<
" type: " <<
ClassName() << std::endl;
1084 out <<
" nz = " <<
fNz <<
";" << std::endl;
1085 out <<
" nvert = " <<
fNvert <<
";" << std::endl;
1086 out <<
" TGeoXtru *xtru = new TGeoXtru(nz);" << std::endl;
1087 out <<
" xtru->SetName(\"" <<
GetName() <<
"\");" << std::endl;
1089 for (i=0; i<
fNvert; i++) {
1090 out <<
" xvert[" << i <<
"] = " <<
fX[i] <<
"; yvert[" << i <<
"] = " <<
fY[i] <<
";" << std::endl;
1092 out <<
" xtru->DefinePolygon(nvert,xvert,yvert);" << std::endl;
1093 for (i=0; i<
fNz; i++) {
1094 out <<
" zsect = " <<
fZ[i] <<
";" << std::endl;
1095 out <<
" x0 = " <<
fX0[i] <<
";" << std::endl;
1096 out <<
" y0 = " <<
fY0[i] <<
";" << std::endl;
1097 out <<
" scale0 = " <<
fScale[i] <<
";" << std::endl;
1098 out <<
" xtru->DefineSection(" << i <<
",zsect,x0,y0,scale0);" << std::endl;
1100 out <<
" TGeoShape *" <<
GetPointerName() <<
" = xtru;" << std::endl;
1114 a = (
fX0[ind1]*
fZ[ind2]-
fX0[ind2]*
fZ[ind1])*invdz;
1115 b = (
fX0[ind2]-
fX0[ind1])*invdz;
1117 a = (
fY0[ind1]*
fZ[ind2]-
fY0[ind2]*
fZ[ind1])*invdz;
1118 b = (
fY0[ind2]-
fY0[ind1])*invdz;
1133 td.
fXc[i] = scale*
fX[i] + x0;
1134 td.
fYc[i] = scale*
fY[i] + y0;
1155 Error(
"SetDimensions",
"Cannot create TGeoXtru %s with less than 2 Z planes",
GetName());
1159 if (
fZ)
delete []
fZ;
1169 DefineSection(i, param[1+4*i], param[2+4*i], param[3+4*i], param[4+4*i]);
1182 for (i = 0; i <
fNz; i++) {
1185 for (j = 0; j <
fNvert; j++) {
1191 for (j = 0; j <
fNvert; j++) {
1211 for (i = 0; i <
fNz; i++) {
1214 for (j = 0; j <
fNvert; j++) {
1220 for (j = 0; j <
fNvert; j++) {
1238 nsegs = nv*(2*nz-1);
1239 npols = nv*(nz-1)+2;
1270 Int_t nbPnts = nz*nvert;
1271 Int_t nbSegs = nvert*(2*nz-1);
1272 Int_t nbPols = nvert*(nz-1)+2;
1273 if (buffer.
SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*(nbPols-2)+2*(2+nvert))) {
Generic 3D primitive description class.
Bool_t SectionsValid(UInt_t mask) const
void SetSectionsValid(UInt_t mask)
Bool_t SetRawSizes(UInt_t reqPnts, UInt_t reqPntsCapacity, UInt_t reqSegs, UInt_t reqSegsCapacity, UInt_t reqPols, UInt_t reqPolsCapacity)
Set kRaw tessellation section of buffer with supplied sizes.
virtual Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const
Computes the closest distance from given point to this shape.
virtual Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=0) const
Compute distance from outside point to surface of the box.
virtual void InspectShape() const
Prints shape parameters.
virtual Bool_t Contains(const Double_t *point) const
Test if point is inside this shape.
virtual void FillBuffer3D(TBuffer3D &buffer, Int_t reqSections, Bool_t localFrame) const
Fills the supplied buffer, with sections in desired frame See TBuffer3D.h for explanation of sections...
static Int_t ThreadId()
Translates the current thread id to an ordinal number.
An arbitrary polygon defined by vertices.
Double_t Safety(const Double_t *point, Int_t &isegment) const
Compute minimum distance from POINT to any segment. Returns segment index.
void SetXY(Double_t *x, Double_t *y)
Set X/Y array pointer for the polygon and daughters.
Double_t Area() const
Computes area of the polygon in [length^2].
Bool_t Contains(const Double_t *point) const
Check if a point given by X = point[0], Y = point[1] is inside the polygon.
Bool_t IsIllegalCheck() const
Check for illegal crossings between non-consecutive segments.
virtual void Draw(Option_t *option="")
Draw the polygon.
Bool_t IsClockwise() const
void FinishPolygon()
Decompose polygon in a convex outscribed part and a list of daughter polygons that have to be subtrac...
Int_t GetBasicColor() const
Get the basic color (0-7).
void TransformPoints(Double_t *points, UInt_t NbPoints) const
Tranform a set of points (LocalToMaster)
void SetShapeBit(UInt_t f, Bool_t set)
Equivalent of TObject::SetBit.
static Bool_t IsSameWithinTolerance(Double_t a, Double_t b)
Check if two numbers differ with less than a tolerance.
const char * GetPointerName() const
Provide a pointer name containing uid.
Int_t ShapeDistancetoPrimitive(Int_t numpoints, Int_t px, Int_t py) const
Returns distance to shape primitive mesh.
virtual const char * GetName() const
Get the shape name.
static Double_t Tolerance()
Bool_t TestShapeBit(UInt_t f) const
A TGeoXtru shape is represented by the extrusion of an arbitrary polygon with fixed outline between s...
virtual Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=0) const
compute distance from outside point to surface of the tube Warning("DistFromOutside",...
virtual void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm)
Compute normal to closest surface from POINT.
virtual Bool_t Contains(const Double_t *point) const
test if point is inside this shape
ThreadData_t & GetThreadData() const
virtual void ComputeBBox()
compute bounding box of the pcon
Int_t fThreadSize
Navigation data per thread.
void SetCurrentVertices(Double_t x0, Double_t y0, Double_t scale)
Set current vertex coordinates according X0, Y0 and SCALE.
virtual Double_t Capacity() const
Compute capacity [length^3] of this shape.
virtual void ComputeNormal_v(const Double_t *points, const Double_t *dirs, Double_t *norms, Int_t vecsize)
Compute the normal for an array o points so that norm.dot.dir is positive Input: Arrays of point coor...
virtual void DistFromOutside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t *step) const
Compute distance from array of input points having directions specified by dirs. Store output in dist...
void GetPlaneVertices(Int_t iz, Int_t ivert, Double_t *vert) const
Returns (x,y,z) of 3 vertices of the surface defined by Z sections (iz, iz+1) and polygon vertices (i...
virtual void Sizeof3D() const
fill size of this 3-D object
Bool_t IsPointInsidePlane(const Double_t *point, Double_t *vert, Double_t *norm) const
Check if the quadrilateral defined by VERT contains a coplanar POINT.
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
virtual void SetPoints(Double_t *points) const
create polycone mesh points
Bool_t DefinePolygon(Int_t nvert, const Double_t *xv, const Double_t *yv)
Creates the polygon representing the blueprint of any Xtru section.
virtual void CreateThreadData(Int_t nthreads)
Create thread data for n threads max.
void SetCurrentZ(Double_t z, Int_t iz)
Recompute current section vertices for a given Z position within range of section iz.
virtual TBuffer3D * MakeBuffer3D() const
Creates a TBuffer3D describing this shape.
virtual void DefineSection(Int_t snum, Double_t z, Double_t x0=0., Double_t y0=0., Double_t scale=1.)
defines z position of a section plane, rmin and rmax at this z.
void DrawPolygon(Option_t *option="")
Draw the section polygon.
virtual const TBuffer3D & GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
Fills a static 3D buffer and returns a reference.
Double_t SafetyToSector(const Double_t *point, Int_t iz, Double_t safmin, Bool_t in)
Compute safety to sector iz, returning also the closest segment index.
virtual void Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const
Compute safe distance from each of the points in the input array.
virtual void SetSegsAndPols(TBuffer3D &buff) const
Fill TBuffer3D structure for segments and polygons.
virtual void GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
Returns numbers of vertices, segments and polygons composing the shape mesh.
virtual void DistFromInside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t *step) const
Compute distance from array of input points having directions specified by dirs. Store output in dist...
virtual void SetDimensions(Double_t *param)
virtual void ClearThreadData() const
virtual ~TGeoXtru()
destructor
Double_t DistToPlane(const Double_t *point, const Double_t *dir, Int_t iz, Int_t ivert, Double_t stepmax, Bool_t in) const
Compute distance to a Xtru lateral surface.
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
compute closest distance from point px,py to each corner
void SetSeg(Int_t iseg)
Set current segment.
std::mutex fMutex
size of thread-specific array
virtual void InspectShape() const
Print actual Xtru parameters.
virtual Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const
computes the closest distance from given point to this shape, according to option.
void GetPlaneNormal(const Double_t *vert, Double_t *norm) const
Returns normal vector to the planar quadrilateral defined by vector VERT.
virtual Int_t GetNmeshVertices() const
Return number of vertices of the mesh representation.
std::vector< ThreadData_t * > fThreadData
virtual void Contains_v(const Double_t *points, Bool_t *inside, Int_t vecsize) const
Check the inside status for each of the points in the array.
void SetIz(Int_t iz)
Set current z-plane.
virtual Double_t DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=0) const
compute distance from inside point to surface of the polycone locate Z segment
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
virtual const char * ClassName() const
Returns name of class to which the object belongs.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Short_t Max(Short_t a, Short_t b)
Double_t Sqrt(Double_t x)
Short_t Min(Short_t a, Short_t b)
Long64_t BinarySearch(Long64_t n, const T *array, T value)
~ThreadData_t()
Destructor.
ThreadData_t()
Constructor.
#define snext(osub1, osub2)