108 std::unique_ptr<Double_t[]>
fXc;
109 std::unique_ptr<Double_t[]>
fYc;
121 auto data = std::make_unique<OwnedThreadData_t>(
fNvert);
124 data->fPoly = std::make_unique<TGeoPolygon>(
fNvert);
126 data->fPoly->FinishPolygon();
142 Error(
"DefinePolygon",
"Shape %s of type XTRU has an illegal polygon.",
GetName());
152 fGeneration.fetch_add(1, std::memory_order_release);
206 Error(
"ctor",
"Cannot create TGeoXtru %s with less than 2 Z planes",
GetName());
286 for (iz = 0; iz <
fNz - 1; iz++) {
287 dz =
fZ[iz + 1] -
fZ[iz];
292 capacity += (area * dz / 3.) * (sc1 * sc1 + sc1 * sc2 + sc2 * sc2);
304 Error(
"ComputeBBox",
"In shape %s polygon not defined",
GetName());
329 fOrigin[2] = 0.5 * (zmin + zmax);
332 fDZ = 0.5 * (zmax - zmin);
342 memset(norm, 0, 3 *
sizeof(
Double_t));
343 norm[2] = (dir[2] > 0) ? 1 : -1;
349 Double_t ndotd = norm[0] * dir[0] + norm[1] * dir[1] + norm[2] * dir[2];
365 if (point[2] <
fZ[0])
367 if (point[2] >
fZ[
fNz - 1])
370 if (iz < 0 || iz ==
fNz - 1)
427 snext = (
fZ[iz] - point[2]) / dir[2];
430 pt[0] = point[0] + snext * dir[0];
431 pt[1] = point[1] + snext * dir[1];
432 pt[2] = point[2] + snext * dir[2];
443 Double_t ndotd = norm[0] * dir[0] + norm[1] * dir[1] + norm[2] * dir[2];
447 safe = (vert[0] - point[0]) * norm[0] + (vert[1] - point[1]) * norm[1] + (vert[2] - point[2]) * norm[2];
454 safe = (point[0] - vert[0]) * norm[0] + (point[1] - vert[1]) * norm[1] + (point[2] - vert[2]) * norm[2];
458 snext = safe / ndotd;
461 if (
fZ[iz] <
fZ[iz + 1]) {
462 znew = point[2] + snext * dir[2];
465 if (znew >
fZ[iz + 1])
468 pt[0] = point[0] + snext * dir[0];
469 pt[1] = point[1] + snext * dir[1];
470 pt[2] = point[2] + snext * dir[2];
484 if (iact < 3 && safe) {
488 if (iact == 1 && step < *safe)
522 Int_t iv, ipl, inext;
525 for (iv = 0; iv <
fNvert; iv++) {
541 Int_t incseg = (dir[2] > 0) ? 1 : -1;
544 while (iz >= 0 && iz <
fNz - 1) {
546 ipl = iz + ((incseg + 1) >> 1);
547 inext = ipl + incseg;
548 sz = (
fZ[ipl] - point[2]) / dir[2];
552 pt[0] = point[0] + sz * dir[0];
553 pt[1] = point[1] + sz * dir[1];
557 if (ipl == 0 || ipl ==
fNz - 1) {
583 for (iv = 0; iv <
fNvert; iv++) {
609 if (iact < 3 && safe) {
613 if (iact == 1 && step < *safe)
634 snext = (
fZ[0] - point[2]) / dir[2];
637 for (i = 0; i < 3; i++)
638 pt[i] = point[i] + snext * dir[i];
651 snext = (
fZ[
fNz - 1] - point[2]) / dir[2];
654 for (i = 0; i < 3; i++)
655 pt[i] = point[i] + snext * dir[i];
674 for (i = 0; i < 3; i++)
675 pt[i] += dist * dir[i];
679 else if (iz ==
fNz - 1)
692 for (iv = 0; iv <
fNvert; iv++) {
694 if (dist < stepmax) {
697 return (snext + dist);
703 return (snext + stepmax);
707 Int_t incseg = (dir[2] > 0) ? 1 : -1;
708 while (iz >= 0 && iz <
fNz - 1) {
713 for (iv = 0; iv <
fNvert; iv++) {
715 if (dist < stepmax) {
719 return (snext + dist);
725 return (snext + stepmax);
742 Error(
"DefinePolygon",
"In shape %s cannot create polygon with less than 3 vertices",
GetName());
746 for (
Int_t i = 0; i < nvert - 1; i++) {
747 for (
Int_t j = i + 1; j < nvert; j++) {
749 Error(
"DefinePolygon",
"In shape %s 2 vertices cannot be identical",
GetName());
775 if ((snum < 0) || (snum >=
fNz))
782 if (
fZ[snum] <
fZ[snum - 1]) {
784 "In shape: %s, Z position of section "
785 "%i, z=%e, not in increasing order, %i, z=%e",
786 GetName(), snum,
fZ[snum], snum - 1,
fZ[snum - 1]);
790 if (snum == (
fNz - 1)) {
802 if (ipl < 0 || ipl > (
fNz - 1)) {
803 Error(
"GetZ",
"In shape %s, ipl=%i out of range (0,%i)",
GetName(), ipl,
fNz - 1);
816 v1[0] = vert[9] - vert[0];
817 v1[1] = vert[10] - vert[1];
818 v1[2] = vert[11] - vert[2];
819 v2[0] = vert[3] - vert[0];
820 v2[1] = vert[4] - vert[1];
821 v2[2] = vert[5] - vert[2];
822 norm[0] =
v1[1] *
v2[2] -
v1[2] *
v2[1];
823 cross += norm[0] * norm[0];
824 norm[1] =
v1[2] *
v2[0] -
v1[0] *
v2[2];
825 cross += norm[1] * norm[1];
826 norm[2] =
v1[0] *
v2[1] -
v1[1] *
v2[0];
827 cross += norm[2] * norm[2];
831 for (
Int_t i = 0; i < 3; i++)
909 for (
Int_t i = 0; i < 4; i++) {
911 k = 3 * ((i + 1) % 4);
912 v1[0] = point[0] - vert[j];
913 v1[1] = point[1] - vert[j + 1];
914 v1[2] = point[2] - vert[j + 2];
915 v2[0] = vert[k] - vert[j];
916 v2[1] = vert[k + 1] - vert[j + 1];
917 v2[2] = vert[k + 2] - vert[j + 2];
918 cross = (
v1[1] *
v2[2] -
v1[2] *
v2[1]) * norm[0] + (
v1[2] *
v2[0] -
v1[0] *
v2[2]) * norm[1] +
919 (
v1[0] *
v2[1] -
v1[1] *
v2[0]) * norm[2];
931 printf(
"*** Shape %s: TGeoXtru ***\n",
GetName());
932 printf(
" Nz = %i\n",
fNz);
933 printf(
" List of (x,y) of polygon vertices:\n");
935 printf(
" x = %11.5f y = %11.5f\n",
fX[ivert],
fY[ivert]);
936 for (
Int_t ipl = 0; ipl <
fNz; ipl++)
937 printf(
" plane %i: z=%11.5f x0=%11.5f y0=%11.5f scale=%11.5f\n", ipl,
fZ[ipl],
fX0[ipl],
fY0[ipl],
939 printf(
" Bounding box:\n");
951 Int_t nbPnts = nz * nvert;
952 Int_t nbSegs = nvert * (2 * nz - 1);
953 Int_t nbPols = nvert * (nz - 1) + 2;
956 6 * (nbPols - 2) + 2 * (2 + nvert));
975 Int_t indx = 0, indx2, k;
976 for (i = 0; i < nz; i++) {
980 for (j = 0; j < nvert; j++) {
983 buff.
fSegs[indx++] = indx2 + j;
984 buff.
fSegs[indx++] = indx2 + k;
987 for (i = 0; i < nz - 1; i++) {
991 for (j = 0; j < nvert; j++) {
994 buff.
fSegs[indx++] = indx2 + j;
995 buff.
fSegs[indx++] = indx2 + k;
1002 for (i = 0; i < nz - 1; i++) {
1004 for (j = 0; j < nvert; j++) {
1005 k = (j + 1) % nvert;
1006 buff.
fPols[indx++] =
c + j % 3;
1007 buff.
fPols[indx++] = 4;
1008 buff.
fPols[indx++] = indx2 + j;
1009 buff.
fPols[indx++] = nz * nvert + indx2 + k;
1010 buff.
fPols[indx++] = indx2 + nvert + j;
1011 buff.
fPols[indx++] = nz * nvert + indx2 + j;
1014 buff.
fPols[indx++] =
c + 2;
1015 buff.
fPols[indx++] = nvert;
1017 for (j = nvert - 1; j >= 0; --j) {
1018 buff.
fPols[indx++] = indx2 + j;
1022 buff.
fPols[indx++] = nvert;
1023 indx2 = (nz - 1) * nvert;
1025 for (j = 0; j < nvert; j++) {
1026 buff.
fPols[indx++] = indx2 + j;
1051 if ((in1 & !in2) | (in2 & !in1)) {
1062 safz =
fZ[iz] - point[2];
1066 saf1 = point[2] -
fZ[iz + 1];
1081 for (iseg = 0; iseg <
fNvert; iseg++) {
1084 saf1 = (point[0] - vert[0]) * norm[0] + (point[1] - vert[1]) * norm[1] + (point[2] - vert[2]) * norm[2];
1117 for (iz = 0; iz <
fNz - 1; iz++) {
1130 safz =
fZ[0] - point[2];
1132 if (iz ==
fNz - 1) {
1134 safz = point[2] -
fZ[
fNz - 1];
1139 for (i = iz; i <
fNz - 1; i++) {
1145 for (i = iz - 1; i >= 0; i--) {
1161 out <<
" // Shape: " <<
GetName() <<
" type: " <<
ClassName() << std::endl;
1162 out <<
" auto " <<
GetPointerName() <<
" = new TGeoXtru(" <<
fNz <<
");" << std::endl;
1165 out <<
" xvert[" << i <<
"] = " <<
fX[i] <<
"; yvert[" << i <<
"] = " <<
fY[i] <<
";" << std::endl;
1167 out <<
" " <<
GetPointerName() <<
"->DefinePolygon(" <<
fNvert <<
", xvert, yvert);" << std::endl;
1169 out <<
" " <<
GetPointerName() <<
"->DefineSection(" << i <<
", " <<
fZ[i] <<
", " <<
fX0[i] <<
", " <<
fY0[i]
1170 <<
", " <<
fScale[i] <<
");" << std::endl;
1184 a = (
fX0[ind1] *
fZ[ind2] -
fX0[ind2] *
fZ[ind1]) * invdz;
1185 b = (
fX0[ind2] -
fX0[ind1]) * invdz;
1187 a = (
fY0[ind1] *
fZ[ind2] -
fY0[ind2] *
fZ[ind1]) * invdz;
1188 b = (
fY0[ind2] -
fY0[ind1]) * invdz;
1203 td.
fXc[i] = scale *
fX[i] + x0;
1204 td.
fYc[i] = scale *
fY[i] + y0;
1225 Error(
"SetDimensions",
"Cannot create TGeoXtru %s with less than 2 Z planes",
GetName());
1243 DefineSection(i, param[1 + 4 * i], param[2 + 4 * i], param[3 + 4 * i], param[4 + 4 * i]);
1256 for (i = 0; i <
fNz; i++) {
1259 for (j = 0; j <
fNvert; j++) {
1265 for (j = 0; j <
fNvert; j++) {
1285 for (i = 0; i <
fNz; i++) {
1288 for (j = 0; j <
fNvert; j++) {
1294 for (j = 0; j <
fNvert; j++) {
1312 nsegs = nv * (2 * nz - 1);
1313 npols = nv * (nz - 1) + 2;
1342 Int_t nbPnts = nz * nvert;
1343 Int_t nbSegs = nvert * (2 * nz - 1);
1344 Int_t nbPols = nvert * (nz - 1) + 2;
1345 if (buffer.
SetRawSizes(nbPnts, 3 * nbPnts, nbSegs, 3 * nbSegs, nbPols, 6 * (nbPols - 2) + 2 * (2 + nvert))) {
1370 for (
Int_t i = 0; i < vecsize; i++)
1381 for (
Int_t i = 0; i < vecsize; i++)
1391 for (
Int_t i = 0; i < vecsize; i++)
1401 for (
Int_t i = 0; i < vecsize; i++)
1412 for (
Int_t i = 0; i < vecsize; i++)
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
int Int_t
Signed integer 4 bytes (int)
float Float_t
Float 4 bytes (float)
double Double_t
Double 8 bytes.
const char Option_t
Option string (const char)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t points
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.
void FillBuffer3D(TBuffer3D &buffer, Int_t reqSections, Bool_t localFrame) const override
Fills the supplied buffer, with sections in desired frame See TBuffer3D.h for explanation of sections...
Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=nullptr) const override
Compute distance from outside point to surface of the box.
void InspectShape() const override
Prints shape parameters.
Bool_t Contains(const Double_t *point) const override
Test if point is inside this shape.
Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const override
Computes the closest distance from given point to this shape.
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.
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.
void Draw(Option_t *option="") override
Draw the polygon.
Bool_t IsClockwise() const
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.
const char * GetName() const override
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...
ThreadData_t & GetThreadData() const
Per-thread non-owning cache of scratch state indexed by this shape.
Int_t GetNmeshVertices() const override
Return number of vertices of the mesh representation.
void DistFromInside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t *step) const override
Compute distance from array of input points having directions specified by dirs. Store output in dist...
void ClearThreadData() const override
Release object-owned scratch buffers and invalidate the non-owning TLS slots.
Double_t Capacity() const override
Compute capacity [length^3] of this shape.
void ComputeBBox() override
compute bounding box of the pcon
std::vector< std::unique_ptr< OwnedThreadData_t > > fOwnedData
! Object-owned per-thread buffers
void Contains_v(const Double_t *points, Bool_t *inside, Int_t vecsize) const override
Check the inside status for each of the points in the array.
Bool_t Contains(const Double_t *point) const override
test if point is inside this shape
std::atomic< Bool_t > fIllegalChecked
bumped whenever the per-thread state must be rebuilt
void SetCurrentVertices(Double_t x0, Double_t y0, Double_t scale)
Set current vertex coordinates according X0, Y0 and SCALE.
static std::atomic< UInt_t > fgInstanceCount
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
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...
void InspectShape() const override
Print actual Xtru parameters.
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
compute closest distance from point px,py to each corner
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.
void Sizeof3D() const override
fill size of this 3-D object
~TGeoXtru() override
destructor
const TBuffer3D & GetBuffer3D(Int_t reqSections, Bool_t localFrame) const override
Fills a static 3D buffer and returns a reference.
void InitThreadSlot(ThreadData_t &td) const
(Re)build the per-thread scratch state for this shape into the given slot.
Bool_t DefinePolygon(Int_t nvert, const Double_t *xv, const Double_t *yv)
Creates the polygon representing the blueprint of any Xtru section.
void SetCurrentZ(Double_t z, Int_t iz)
Recompute current section vertices for a given Z position within range of section iz.
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.
Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const override
computes the closest distance from given point to this shape, according to option.
void ComputeNormal_v(const Double_t *points, const Double_t *dirs, Double_t *norms, Int_t vecsize) override
Compute the normal for an array o points so that norm.dot.dir is positive Input: Arrays of point coor...
std::atomic< Int_t > fGeneration
non-reused index of this shape into the per-thread vector
void SetDimensions(Double_t *param) override
void DrawPolygon(Option_t *option="")
Draw the section polygon.
void SetPoints(Double_t *points) const override
create polycone mesh points
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::mutex fOwnedDataMutex
! Protects cold allocation and cleanup
Double_t DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=nullptr) const override
compute distance from inside point to surface of the polycone locate Z segment
void DistFromOutside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t *step) const override
Compute distance from array of input points having directions specified by dirs. Store output in dist...
void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const override
Compute normal to closest surface from POINT.
TBuffer3D * MakeBuffer3D() const override
Creates a TBuffer3D describing this shape.
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.
void SetSegsAndPols(TBuffer3D &buff) const override
Fill TBuffer3D structure for segments and polygons.
void SetSeg(Int_t iseg)
Set current segment.
Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=nullptr) const override
compute distance from outside point to surface of the tube Warning("DistFromOutside",...
void GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const override
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.
void SetIz(Int_t iz)
Set current z-plane.
void Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const override
Compute safe distance from each of the points in the input array.
Bool_t IsConvex() const final
Check shape convexity.
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)
Returns the largest of a and b.
Double_t Sqrt(Double_t x)
Returns the square root of x.
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Binary search in an array of n values to locate value.
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
std::unique_ptr< Double_t[]> fYc
std::unique_ptr< Double_t[]> fXc
OwnedThreadData_t(std::size_t size)
std::unique_ptr< TGeoPolygon > fPoly
illegal-polygon warning already emitted
TGeoPolygon * fPoly
[fNvert] current Y positions for polygon vertices
Double_t * fYc
[fNvert] current X positions for polygon vertices
Int_t fIz
current segment [0,fNvert-1]
Double_t * fXc
current z plane [0,fNz-1]
Int_t fInitGen
polygon defining section shape