75 fSeg(0), fIz(0), fXc(0), fYc(0), fPoly(0)
102 std::lock_guard<std::mutex> guard(
fMutex);
103 std::vector<ThreadData_t*>::iterator i =
fThreadData.begin();
118 std::lock_guard<std::mutex> guard(
fMutex);
121 for (
Int_t tid=0; tid<nthreads; tid++) {
133 Error(
"DefinePolygon",
"Shape %s of type XTRU has an illegal polygon.",
GetName());
193 Error(
"ctor",
"Cannot create TGeoXtru %s with less than 2 Z planes",
GetName());
276 if (
fX) {
delete[]
fX;
fX = 0;}
277 if (
fY) {
delete[]
fY;
fY = 0;}
278 if (
fZ) {
delete[]
fZ;
fZ = 0;}
297 for (iz=0; iz<
fNz-1; iz++) {
298 dz =
fZ[iz+1]-
fZ[iz];
302 capacity += (area*dz/3.)*(sc1*sc1+sc1*sc2+sc2*sc2);
314 Error(
"ComputeBBox",
"In shape %s polygon not defined",
GetName());
327 if (td.
fXc[j]<xmin) xmin=td.
fXc[j];
328 if (td.
fXc[j]>xmax) xmax=td.
fXc[j];
329 if (td.
fYc[j]<ymin) ymin=td.
fYc[j];
330 if (td.
fYc[j]>ymax) ymax=td.
fYc[j];
338 fDZ = 0.5*(zmax-zmin);
349 norm[2] = (dir[2]>0)?1:-1;
355 Double_t ndotd = norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2];
426 snext = (
fZ[iz]-point[2])/dir[2];
428 pt[0] = point[0]+snext*dir[0];
429 pt[1] = point[1]+snext*dir[1];
430 pt[2] = point[2]+snext*dir[2];
438 Double_t ndotd = norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2];
441 safe = (vert[0]-point[0])*norm[0]+
442 (vert[1]-point[1])*norm[1]+
443 (vert[2]-point[2])*norm[2];
448 safe = (point[0]-vert[0])*norm[0]+
449 (point[1]-vert[1])*norm[1]+
450 (point[2]-vert[2])*norm[2];
455 if (
fZ[iz]<
fZ[iz+1]) {
456 znew = point[2] + snext*dir[2];
460 pt[0] = point[0]+snext*dir[0];
461 pt[1] = point[1]+snext*dir[1];
462 pt[2] = point[2]+snext*dir[2];
474 if (iact<3 && safe) {
508 Int_t iv, ipl, inext;
511 for (iv=0; iv<
fNvert; iv++) {
517 if (convex)
return snext;
520 if (snext < 1.E10)
return snext;
525 Int_t incseg = (dir[2]>0)?1:-1;
528 while (iz>=0 && iz<
fNz-1) {
530 ipl = iz+((incseg+1)>>1);
532 sz = (
fZ[ipl]-point[2])/dir[2];
536 pt[0] = point[0]+sz*dir[0];
537 pt[1] = point[1]+sz*dir[1];
541 if (ipl==0 || ipl==
fNz-1) {
543 if (convex)
return sz;
553 if (convex)
return sz;
565 for (iv=0; iv<
fNvert; iv++) {
571 if (convex)
return snext;
575 if (zexit)
return snext;
588 if (iact<3 && safe) {
602 memcpy(pt,point,3*
sizeof(
Double_t));
609 snext = (
fZ[0] - point[2])/dir[2];
611 for (i=0; i<3; i++) pt[i] = point[i] + snext*dir[i];
623 snext = (
fZ[
fNz-1] - point[2])/dir[2];
625 for (i=0; i<3; i++) pt[i] = point[i] + snext*dir[i];
639 if (dist>1
E-6) dist-=1
E-6;
641 for (i=0; i<3; i++) pt[i] += dist*dir[i];
644 else if (iz==
fNz-1) iz =
fNz-2;
656 for (iv=0; iv<
fNvert; iv++) {
660 if (convex)
return (snext+dist);
665 if (hit)
return (snext+stepmax);
669 Int_t incseg = (dir[2]>0)?1:-1;
670 while (iz>=0 && iz<
fNz-1) {
674 for (iv=0; iv<
fNvert; iv++) {
679 if (convex)
return (snext+dist);
684 if (hit)
return (snext+stepmax);
701 Error(
"DefinePolygon",
"In shape %s cannot create polygon with less than 3 vertices",
GetName());
705 for (
Int_t i=0; i<nvert-1; i++) {
706 for (
Int_t j=i+1; j<nvert; j++) {
709 Error(
"DefinePolygon",
"In shape %s 2 vertices cannot be identical",
GetName());
716 if (
fX)
delete []
fX;
718 if (
fY)
delete []
fY;
733 if ((snum<0) || (snum>=
fNz))
return;
739 if (
fZ[snum]<
fZ[snum-1]) {
740 Warning(
"DefineSection",
"In shape: %s, Z position of section " 741 "%i, z=%e, not in increasing order, %i, z=%e",
757 if (ipl<0 || ipl>(
fNz-1)) {
758 Error(
"GetZ",
"In shape %s, ipl=%i out of range (0,%i)",
GetName(),ipl,
fNz-1);
771 v1[0] = vert[9]-vert[0];
772 v1[1] = vert[10]-vert[1];
773 v1[2] = vert[11]-vert[2];
774 v2[0] = vert[3]-vert[0];
775 v2[1] = vert[4]-vert[1];
776 v2[2] = vert[5]-vert[2];
777 norm[0] = v1[1]*v2[2]-v1[2]*v2[1];
778 cross += norm[0]*norm[0];
779 norm[1] = v1[2]*v2[0]-v1[0]*v2[2];
780 cross += norm[1]*norm[1];
781 norm[2] = v1[0]*v2[1]-v1[1]*v2[0];
782 cross += norm[2]*norm[2];
785 for (
Int_t i=0; i<3; i++) norm[i] *= cross;
816 x =
fX[ivert]*
fScale[iz+1]+fX0[iz+1];
817 y =
fY[ivert]*
fScale[iz+1]+fY0[iz+1];
832 x =
fX[ivert]*
fScale[iz+1]+fX0[iz+1];
833 y =
fY[ivert]*
fScale[iz+1]+fY0[iz+1];
852 for (
Int_t i=0; i<4; i++) {
855 v1[0] = point[0]-vert[j];
856 v1[1] = point[1]-vert[j+1];
857 v1[2] = point[2]-vert[j+2];
858 v2[0] = vert[k]-vert[j];
859 v2[1] = vert[k+1]-vert[j+1];
860 v2[2] = vert[k+2]-vert[j+2];
861 cross = (v1[1]*v2[2]-v1[2]*v2[1])*norm[0]+
862 (v1[2]*v2[0]-v1[0]*v2[2])*norm[1]+
863 (v1[0]*v2[1]-v1[1]*v2[0])*norm[2];
864 if (cross<0)
return kFALSE;
874 printf(
"*** Shape %s: TGeoXtru ***\n",
GetName());
875 printf(
" Nz = %i\n",
fNz);
876 printf(
" List of (x,y) of polygon vertices:\n");
878 printf(
" x = %11.5f y = %11.5f\n",
fX[ivert],
fY[ivert]);
880 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]);
881 printf(
" Bounding box:\n");
893 Int_t nbPnts = nz*nvert;
894 Int_t nbSegs = nvert*(2*nz-1);
895 Int_t nbPols = nvert*(nz-1)+2;
898 nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*(nbPols-2)+2*(2+nvert));
918 Int_t indx, indx2, k;
920 for (i=0; i<nz; i++) {
924 for (j=0; j<nvert; j++) {
926 buff.
fSegs[indx++] = c;
927 buff.
fSegs[indx++] = indx2+j;
928 buff.
fSegs[indx++] = indx2+k;
931 for (i=0; i<nz-1; i++) {
935 for (j=0; j<nvert; j++) {
937 buff.
fSegs[indx++] = c;
938 buff.
fSegs[indx++] = indx2+j;
939 buff.
fSegs[indx++] = indx2+k;
946 for (i=0; i<nz-1; i++) {
948 for (j=0; j<nvert; j++) {
950 buff.
fPols[indx++] = c+j%3;
951 buff.
fPols[indx++] = 4;
952 buff.
fPols[indx++] = indx2+j;
953 buff.
fPols[indx++] = nz*nvert+indx2+k;
954 buff.
fPols[indx++] = indx2+nvert+j;
955 buff.
fPols[indx++] = nz*nvert+indx2+j;
958 buff.
fPols[indx++] = c+2;
959 buff.
fPols[indx++] = nvert;
961 for (j = nvert - 1; j >= 0; --j) {
962 buff.
fPols[indx++] = indx2+j;
965 buff.
fPols[indx++] = c;
966 buff.
fPols[indx++] = nvert;
967 indx2 = (nz-1)*nvert;
969 for (j=0; j<nvert; j++) {
970 buff.
fPols[indx++] = indx2+j;
996 if ((in1&!in2)|(in2&!in1)) {
1006 safz =
fZ[iz]-point[2];
1009 saf1 = point[2]-
fZ[iz+1];
1023 for (iseg=0; iseg<
fNvert; iseg++) {
1026 saf1 = (point[0]-vert[0])*norm[0]+(point[1]-vert[1])*norm[1]+(point[2]-vert[2])*norm[2];
1027 if (in) saf1 = -saf1;
1029 if (saf1<-1.
E-8)
continue;
1032 if (safe>safmin)
continue;
1036 if (found)
return safmin;
1054 for (iz=0; iz<
fNz-1; iz++) {
1056 if (safe<safmin) safmin = safe;
1065 safz =
fZ[0] - point[2];
1069 safz = point[2] -
fZ[
fNz-1];
1074 for (i=iz; i<
fNz-1; i++) {
1076 if (safe<safmin) safmin=safe;
1079 for (i=iz-1; i>=0; i--) {
1081 if (safe<safmin) safmin=safe;
1093 out <<
" // Shape: " <<
GetName() <<
" type: " <<
ClassName() << std::endl;
1094 out <<
" nz = " <<
fNz <<
";" << std::endl;
1095 out <<
" nvert = " <<
fNvert <<
";" << std::endl;
1096 out <<
" TGeoXtru *xtru = new TGeoXtru(nz);" << std::endl;
1097 out <<
" xtru->SetName(\"" <<
GetName() <<
"\");" << std::endl;
1099 for (i=0; i<
fNvert; i++) {
1100 out <<
" xvert[" << i <<
"] = " <<
fX[i] <<
"; yvert[" << i <<
"] = " <<
fY[i] <<
";" << std::endl;
1102 out <<
" xtru->DefinePolygon(nvert,xvert,yvert);" << std::endl;
1103 for (i=0; i<
fNz; i++) {
1104 out <<
" zsect = " <<
fZ[i] <<
";" << std::endl;
1105 out <<
" x0 = " <<
fX0[i] <<
";" << std::endl;
1106 out <<
" y0 = " <<
fY0[i] <<
";" << std::endl;
1107 out <<
" scale0 = " <<
fScale[i] <<
";" << std::endl;
1108 out <<
" xtru->DefineSection(" << i <<
",zsect,x0,y0,scale0);" << std::endl;
1110 out <<
" TGeoShape *" <<
GetPointerName() <<
" = xtru;" << std::endl;
1124 a = (
fX0[ind1]*
fZ[ind2]-
fX0[ind2]*
fZ[ind1])*invdz;
1125 b = (
fX0[ind2]-
fX0[ind1])*invdz;
1127 a = (
fY0[ind1]*
fZ[ind2]-
fY0[ind2]*
fZ[ind1])*invdz;
1128 b = (
fY0[ind2]-
fY0[ind1])*invdz;
1143 td.
fXc[i] = scale*
fX[i] + x0;
1144 td.
fYc[i] = scale*
fY[i] + y0;
1165 Error(
"SetDimensions",
"Cannot create TGeoXtru %s with less than 2 Z planes",
GetName());
1169 if (
fZ)
delete []
fZ;
1179 DefineSection(i, param[1+4*i], param[2+4*i], param[3+4*i], param[4+4*i]);
1192 for (i = 0; i <
fNz; i++) {
1195 for (j = 0; j <
fNvert; j++) {
1196 points[indx++] = td.
fXc[j];
1197 points[indx++] = td.
fYc[j];
1198 points[indx++] =
fZ[i];
1201 for (j = 0; j <
fNvert; j++) {
1202 points[indx++] = td.
fXc[fNvert-1-j];
1203 points[indx++] = td.
fYc[fNvert-1-j];
1204 points[indx++] =
fZ[i];
1221 for (i = 0; i <
fNz; i++) {
1224 for (j = 0; j <
fNvert; j++) {
1225 points[indx++] = td.
fXc[j];
1226 points[indx++] = td.
fYc[j];
1227 points[indx++] =
fZ[i];
1230 for (j = 0; j <
fNvert; j++) {
1231 points[indx++] = td.
fXc[fNvert-1-j];
1232 points[indx++] = td.
fYc[fNvert-1-j];
1233 points[indx++] =
fZ[i];
1248 nsegs = nv*(2*nz-1);
1249 npols = nv*(nz-1)+2;
1280 Int_t nbPnts = nz*nvert;
1281 Int_t nbSegs = nvert*(2*nz-1);
1282 Int_t nbPols = nvert*(nz-1)+2;
1283 if (buffer.
SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*(nbPols-2)+2*(2+nvert))) {
1308 for (
Int_t i=0; i<vecsize; i++) inside[i] =
Contains(&points[3*i]);
1318 for (
Int_t i=0; i<vecsize; i++)
ComputeNormal(&points[3*i], &dirs[3*i], &norms[3*i]);
1326 for (
Int_t i=0; i<vecsize; i++) dists[i] =
DistFromInside(&points[3*i], &dirs[3*i], 3, step[i]);
1334 for (
Int_t i=0; i<vecsize; i++) dists[i] =
DistFromOutside(&points[3*i], &dirs[3*i], 3, step[i]);
1344 for (
Int_t i=0; i<vecsize; i++) safe[i] =
Safety(&points[3*i], inside[i]);
void SetSeg(Int_t iseg)
Set current segment.
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...
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 Draw(Option_t *option="")
Draw the polygon.
double dist(Rotation3D const &r1, Rotation3D const &r2)
virtual const TBuffer3D & GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
Fills a static 3D buffer and returns a reference.
#define snext(osub1, osub2)
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 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", "not implemented");
virtual TBuffer3D * MakeBuffer3D() const
Creates a TBuffer3D describing this shape.
ThreadData_t()
Constructor.
Bool_t TestBit(UInt_t f) const
Bool_t Contains(const Double_t *point) const
Check if a point given by X = point[0], Y = point[1] is inside the polygon.
virtual void ClearThreadData() const
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.
Double_t Safety(const Double_t *point, Int_t &isegment) const
Compute minimum distance from POINT to any segment. Returns segment index.
virtual void Sizeof3D() const
fill size of this 3-D object
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.
An arbitrary polygon defined by vertices.
virtual void SetDimensions(Double_t *param)
virtual void GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
Returns numbers of vertices, segments and polygons composing the shape mesh.
void GetPlaneNormal(const Double_t *vert, Double_t *norm) const
Returns normal vector to the planar quadrilateral defined by vector VERT.
Short_t Min(Short_t a, Short_t b)
virtual void CreateThreadData(Int_t nthreads)
Create thread data for n threads max.
virtual void InspectShape() const
Prints shape parameters.
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...
static Bool_t IsSameWithinTolerance(Double_t a, Double_t b)
Check if two numbers differ with less than a tolerance.
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
static Double_t Tolerance()
virtual void InspectShape() const
Print actual Xtru parameters.
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Bool_t IsIllegalCheck() const
Check for illegal crossings between non-consecutive segments.
void SetCurrentVertices(Double_t x0, Double_t y0, Double_t scale)
Set current vertex coordinates according X0, Y0 and SCALE.
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.
std::vector< ThreadData_t * > fThreadData
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.
std::mutex fMutex
size of thread-specific array
void SetSectionsValid(UInt_t mask)
const char * GetPointerName() const
Provide a pointer name containing uid.
virtual ~TGeoXtru()
destructor
virtual const char * GetName() const
Get the shape name.
Int_t ShapeDistancetoPrimitive(Int_t numpoints, Int_t px, Int_t py) const
Returns distance to shape primitive mesh.
Bool_t SectionsValid(UInt_t mask) const
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
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 SetXY(Double_t *x, Double_t *y)
Set X/Y array pointer for the polygon and daughters.
virtual Bool_t Contains(const Double_t *point) const
test if point is inside this shape
void TransformPoints(Double_t *points, UInt_t NbPoints) const
Tranform a set of points (LocalToMaster)
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
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 Int_t GetNmeshVertices() const
Return number of vertices of the mesh representation.
Generic 3D primitive description class.
void SetCurrentZ(Double_t z, Int_t iz)
Recompute current section vertices for a given Z position within range of section iz...
virtual void ComputeBBox()
compute bounding box of the pcon
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 Safety(const Double_t *point, Bool_t in=kTRUE) const
computes the closest distance from given point to this shape, according to option.
An extrusion with fixed outline shape in x-y and a sequence of z extents (segments).
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 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.
Bool_t TestShapeBit(UInt_t f) const
void FinishPolygon()
Decompose polygon in a convex outscribed part and a list of daughter polygons that have to be subtrac...
Bool_t IsClockwise() const
~ThreadData_t()
Destructor.
ThreadData_t & GetThreadData() const
void DrawPolygon(Option_t *option="")
Draw the section polygon.
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
compute closest distance from point px,py to each corner
TGeoXtru & operator=(const TGeoXtru &)
assignment operator
void SetIz(Int_t iz)
Set current z-plane.
void SetShapeBit(UInt_t f, Bool_t set)
Equivalent of TObject::SetBit.
you should not use this method at all Int_t Int_t z
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...
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
static Int_t ThreadId()
Translates the current thread id to an ordinal number.
Short_t Max(Short_t a, Short_t b)
virtual void SetSegsAndPols(TBuffer3D &buff) const
Fill TBuffer3D structure for segments and polygons.
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
virtual Bool_t Contains(const Double_t *point) const
Test if point is inside this shape.
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Int_t fThreadSize
Navigation data per thread.
virtual void SetPoints(Double_t *points) const
create polycone mesh points
Double_t Sqrt(Double_t x)
Double_t Area() const
Computes area of the polygon in [length^2].
double norm(double *x, double *p)
virtual void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm)
Compute normal to closest surface from POINT.
Int_t GetBasicColor() const
Get the basic color (0-7).
virtual Double_t Capacity() const
Compute capacity [length^3] of this shape.
Long64_t BinarySearch(Long64_t n, const T *array, T value)
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Bool_t DefinePolygon(Int_t nvert, const Double_t *xv, const Double_t *yv)
Creates the polygon representing the blueprint of any Xtru section.