70 int line1[2], line2[2];
72 for (
int i = 0; i <
fNvert; ++i) {
75 for (
int j = 0;
j <
other.GetNvert(); ++
j) {
81 bool order1 = line1[1] == line1[0] + 1;
82 bool order2 = line2[1] == (line2[0] + 1) %
other.GetNvert();
124 return seed ^ (std::hash<long>{}(
value) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
126 for (
int i = 0; i < 3; i++) {
138 for (
auto it =
range.first; it !=
range.second; ++it) {
159 Error(
"AddFacet",
"Shape %s already fully defined. Not adding",
GetName());
169 Error(
"AddFacet",
"Triangular facet at index %d degenerated. Not adding.",
GetNfacets());
173 for (
auto i = 0; i < 3; ++i)
189 Error(
"AddFacet",
"Shape %s already fully defined. Not adding",
GetName());
193 Error(
"AddFacet",
"Shape %s Cannot add facets by indices without vertices. Not adding",
GetName());
208 Error(
"AddFacet",
"Shape %s already fully defined. Not adding",
GetName());
218 Error(
"AddFacet",
"Quadrilateral facet at index %d degenerated. Not adding.",
GetNfacets());
223 for (
auto i = 0; i <
nvert; ++i)
242 Error(
"AddFacet",
"Shape %s already fully defined. Not adding",
GetName());
246 Error(
"AddFacet",
"Shape %s Cannot add facets by indices without vertices. Not adding",
GetName());
266 for (
int i = 0; i <
nvert - 1; ++i) {
270 for (
int j = i + 1;
j <
nvert; ++
j) {
299 std::cout <<
"Facet: " <<
ifacet <<
" is degenerated\n";
305 for (
int i = 1; i <
nvert - 1; ++i) {
311 std::cout <<
"Facet: " <<
ifacet <<
" has zero surface area\n";
352 for (
int i = 0; i <
fNfacets; ++i) {
379 Error(
"Check",
"Tessellated solid %s has following not fully connected facets:",
GetName());
382 std::cout <<
icrt <<
" (" <<
fFacets[
icrt].GetNvert() <<
" edges, " << nn[
icrt] <<
" neighbours)\n";
389 Warning(
"Check",
"Tessellated solid %s has following facets with flipped normals:",
GetName());
393 std::cout <<
icrt <<
"\n";
401 Info(
"Check",
"Automatically flipped %d facets to match first defined facet",
nfixed);
415 double vmin[3] = {kBig, kBig, kBig};
416 double vmax[3] = {-kBig, -kBig, -kBig};
418 for (
int i = 0; i <
facet.GetNvert(); ++i) {
419 for (
int j = 0;
j < 3; ++
j) {
428 for (
int i = 0; i < 3; ++i)
464 std::cout <<
"=== Tessellated shape " <<
GetName() <<
" having " <<
GetNvertices() <<
" vertices and "
530 Error(
"ResizeCenter",
"Not all faces are defined");
536 for (
size_t i = 0; i <
fVertices.size(); ++i) {
581 using std::vector, std::string, std::ifstream, std::stringstream, std::endl;
633 if (!file.is_open()) {
634 ::Error(
"TGeoTessellated::ImportFromObjFormat",
"Unable to open %s",
objfile);
643 if (
line.rfind(
'v', 0) == 0 &&
line.rfind(
"vt", 0) != 0 &&
line.rfind(
"vn", 0) != 0 &&
line.rfind(
"vn", 0) != 0) {
645 double pos[4] = {0, 0, 0, 1};
646 ss >> tag >> pos[0] >> pos[1] >> pos[2] >> pos[3];
647 vertices.emplace_back(pos[0] * pos[3], pos[1] * pos[3], pos[2] * pos[3]);
650 else if (
line.rfind(
'f', 0) == 0) {
658 ::Error(
"TGeoTessellated::ImportFromObjFormat",
"Detected face having unsupported %zu vertices",
671 ::Error(
"TGeoTessellated::ImportFromObjFormat",
"Unsupported relative vertex index definition in %s",
686 ::Error(
"TGeoTessellated::ImportFromObjFormat",
"Not enough faces detected in %s",
objfile);
696 for (
int i = 0; i <
nfacets; ++i) {
698 if (
facet.nvert == 3)
703 tsl->CloseShape(
check,
true, verbose);
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
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...
bool IsNeighbour(const TGeoFacet &other, bool &flip) const
Check if a connected neighbour facet has compatible normal.
static int CompactFacet(Vertex_t *vert, int nvertices)
Compact consecutive equal vertices.
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)
const char * GetName() const override
Get the shape name.
void ResizeCenter(double maxsize)
Resize and center the shape in a box of size maxsize.
int AddVertex(const Vertex_t &vert)
Add a vertex checking for duplicates, returning the vertex index.
bool FacetCheck(int ifacet) const
Check validity of facet.
const Vertex_t & GetVertex(int i) const
void Print(Option_t *option="") const override
Prints basic info.
void SetSegsAndPols(TBuffer3D &buff) const override
Fills TBuffer3D structure for segments and polygons.
const TBuffer3D & GetBuffer3D(int reqSections, Bool_t localFrame) const override
Fills a static 3D buffer and returns a reference.
void SetPoints(double *points) const override
Fill tessellated points to an array.
bool CheckClosure(bool fixFlipped=true, bool verbose=true)
Check closure of the solid and check/fix flipped normals.
Vertex_t FacetComputeNormal(int ifacet, bool °enerated) const
Compute normal for a given facet.
void CloseShape(bool check=true, bool fixFlipped=true, bool verbose=true)
Close the shape: calculate bounding box and compact vertices.
Tessellated::Vertex_t Vertex_t
void GetMeshNumbers(int &nvert, int &nsegs, int &npols) const override
Returns numbers of vertices, segments and polygons composing the shape mesh.
std::vector< TGeoFacet > fFacets
static TGeoTessellated * ImportFromObjFormat(const char *objfile, bool check=false, bool verbose=false)
Reader from .obj format.
TBuffer3D * MakeBuffer3D() const override
Creates a TBuffer3D describing this shape.
void ComputeBBox() override
Compute bounding box.
std::multimap< long, int > fVerticesMap
bool AddFacet(const Vertex_t &pt0, const Vertex_t &pt1, const Vertex_t &pt2)
Adding a triangular facet from vertex positions in absolute coordinates.
std::vector< Vertex_t > fVertices
bool fClosedBody
Shape fully defined.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
ROOT::Geom::Vertex_t Vertex_t
static Vertex_t Cross(Vertex_t const &left, Vertex_t const &right)
The cross (vector) product of two Vector3D<T> objects.
void Normalize()
Normalizes the vector by dividing each entry by the length.