18#include <TGeoTessellated.h>
20#include <TGeoMatrix.h>
36std::vector<int> BuildVertexLoop(
const TBuffer3D&
buf,
37 const std::vector<int>& segs)
40 std::unordered_map<int, std::vector<int>> adj;
43 int a =
buf.fSegs[3 *
s + 1];
44 int b =
buf.fSegs[3 *
s + 2];
50 int start = adj.begin()->first;
54 std::vector<int> loop;
59 const auto& nbrs = adj[curr];
69 if (next == -1 || next ==
start) {
79std::vector<std::vector<int>> ExtractPolygons(
const TBuffer3D&
buf)
81 std::vector<std::vector<int>> polys;
84 for (Int_t ip = 0; ip <
buf.NbPols(); ++ip) {
87 Int_t nseg =
buf.fPols[
idx++];
89 std::vector<int> segs(nseg);
90 for (Int_t
i = 0;
i < nseg; ++
i) {
94 auto verts = BuildVertexLoop(
buf, segs);
95 if (verts.size() >= 3) {
96 polys.push_back(std::move(verts));
103std::vector<std::array<int, 3>>
104 Triangulate(
const std::vector<std::vector<int>>& polys)
106 std::vector<std::array<int, 3>> tris;
107 for (
const auto& poly : polys) {
108 int nv = poly.size();
114 for (
int i = 1;
i < nv - 1; ++
i) {
115 tris.push_back({{
v0, poly[
i], poly[
i + 1]}});
121TGeoTessellated* MakeTessellated(
const TBuffer3D&
buf)
123 auto polys = ExtractPolygons(
buf);
124 auto tris = Triangulate(polys);
126 auto* tess =
new TGeoTessellated(
"tess");
127 const Double_t*
p =
buf.fPnts;
128 for (
auto& t : tris) {
130 TGeoTessellated::Vertex_t{
p[3 * t[0]],
p[3 * t[0] + 1],
p[3 * t[0] + 2]},
131 TGeoTessellated::Vertex_t{
p[3 * t[1]],
p[3 * t[1] + 1],
p[3 * t[1] + 2]},
132 TGeoTessellated::Vertex_t{
p[3 * t[2]],
p[3 * t[2] + 1],
p[3 * t[2] + 2]});
143 auto&
buf = shape->GetBuffer3D(TBuffer3D::kRawSizes | TBuffer3D::kRaw | TBuffer3D::kCore,
false);
144 auto tes = MakeTessellated(
buf);
152 double nn[3] = {
n[0],
n[1],
n[2]};
153 const double norm = std::sqrt(nn[0] * nn[0] + nn[1] * nn[1] + nn[2] * nn[2]);
159 double a[3] = {1., 0., 0.};
160 if (std::abs(nn[0]) > 0.9) {
164 double u[3] = {
a[1] * nn[2] -
a[2] * nn[1],
a[2] * nn[0] -
a[0] * nn[2],
a[0] * nn[1] -
a[1] * nn[0]};
165 const double unorm = std::sqrt(u[0] * u[0] + u[1] * u[1] + u[2] * u[2]);
169 const double v[3] = {nn[1] * u[2] - nn[2] * u[1], nn[2] * u[0] - nn[0] * u[2], nn[0] * u[1] - nn[1] * u[0]};
173 const double m[9] = {u[0],
v[0], nn[0], u[1],
v[1], nn[1], u[2],
v[2], nn[2]};
174 auto* rot =
new TGeoRotation(TString::Format(
"%s_rot",
name));
178 auto* tr =
new TGeoCombiTrans(TString::Format(
"%s_tr",
name), p[0] - reach * nn[0], p[1] - reach * nn[1],
179 p[2] - reach * nn[2], rot);
180 tr->RegisterYourself();
Collection of utility functions for TGeo.
static TGeoTessellated * TGeoShapeToTGeoTessellated(TGeoShape const *)
< Transform any (primitive) TGeoShape to a tessellated representation
static void makeHalfSpaceBox(const char *name, const double p[3], const double n[3], double reach)
GLuint const GLchar * name
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
GLenum GLuint GLenum GLsizei const GLchar * buf
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...