<commit_before>// @(#)root/eve:$Id$
// Authors: <NAME> & <NAME>: 2006, 2007

/*************************************************************************
 * Copyright (C) 1995-2007, <NAME> and <NAME>.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include <ROOT/REvePolygonSetProjected.hxx>
#include <ROOT/REveGeoShape.hxx>
#include <ROOT/REveProjectionManager.hxx>
#include <ROOT/REveGluTess.hxx>
#include <ROOT/REveRenderData.hxx>

#include "TBuffer3D.h"
#include "TBuffer3DTypes.h"
#include "TVirtualPad.h"
#include "TVirtualViewer3D.h"

#include "json.hpp"


using namespace ROOT::Experimental;
namespace REX = ROOT::Experimental;

namespace
{
   struct Seg_t
   {
      // Helper class for building 2D polygons from TBuffer3D.
      Int_t fV1;
      Int_t fV2;

      Seg_t(Int_t i1=-1, Int_t i2=-1) : fV1(i1), fV2(i2) {}
   };

   typedef std::list<Seg_t>           LSeg_t;
   typedef std::list<Seg_t>::iterator LSegIt_t;
}

/** \class REvePolygonSetProjected
\ingroup REve
A set of projected polygons.
Used for storage of projected geometrical shapes.

Internal struct Polygon_t holds only indices into the master vertex
array in REvePolygonSetProjected.
*/

////////////////////////////////////////////////////////////////////////////////
/// Constructor.

REvePolygonSetProjected::REvePolygonSetProjected(const char* n, const char* t) :
   REveShape(n, t),
   fBuff(),
   fPnts()
{
}

////////////////////////////////////////////////////////////////////////////////
/// Destructor.

REvePolygonSetProjected::~REvePolygonSetProjected()
{
   fPols.clear();
}

////////////////////////////////////////////////////////////////////////////////
/// Fill core part of JSON representation.

Int_t REvePolygonSetProjected::WriteCoreJson(nlohmann::json& j, Int_t rnr_offset)
{
   Int_t ret = REveElement::WriteCoreJson(j, rnr_offset);

   j["fNPnts"] = fPnts.size();

   return ret;
}

////////////////////////////////////////////////////////////////////////////////
/// Crates representation for rendering.
/// This is complicated as we need to:
/// - generate outlines;
/// - convert polygons to triangles.
/// ??? Should we check if polygons are front facing? It was not done in old EVE,
/// just GL_FRONT_AND_BACK was used on top of gluTess.

void REvePolygonSetProjected::BuildRenderData()
{
   fRenderData = std::make_unique<REveRenderData>("makePolygonSetProjected", 3 * fPnts.size());

   Int_t n_pols = fPols.size();
   Int_t n_poly_info = 0;
   for (auto &p : fPols) n_poly_info += 1 + p.NPoints();

   std::vector<Double_t> verts;
   verts.reserve(3 * fPnts.size());
   std::vector<Int_t>    polys;
   polys.reserve(n_poly_info);

   for (auto &p : fPols)
   {
      polys.emplace_back(p.NPoints());
      polys.insert(polys.end(), p.fPnts.begin(), p.fPnts.end());
   }

   for (unsigned i = 0; i < fPnts.size(); ++i)
   {
      verts.push_back(fPnts[i].fX);
      verts.push_back(fPnts[i].fY);
      verts.push_back(fPnts[i].fZ);
      fRenderData->PushV(fPnts[i]);
   }

   Int_t n_trings = 0;
   {
      EveGlu::TriangleCollector tc;

      tc.ProcessData(verts, polys, n_pols);

      polys.swap(tc.RefPolyDesc());
      n_trings = tc.GetNTrianlges();
   }

   // Calculate size of index buffer.
   Int_t n_idxbuff = 2 + 3 * n_trings + n_pols + n_poly_info;
   fRenderData->Reserve(0,0,n_idxbuff);

   printf("REvePolygonSetProjected::BuildRenderData expect index buffer to be %d\n",  n_idxbuff);

   // Export triangles.
   fRenderData->PushI(REveRenderData::GL_TRIANGLES);
   fRenderData->PushI(n_trings);
   for (int i = 0; i < n_trings; ++i)
   {
      fRenderData->PushI(&polys[i*n_trings + 1], 3);
   }

   assert (fRenderData->SizeI() == 2 + 3 * n_trings);

   // Export outlines.
   for (auto &p : fPols)
   {
      fRenderData->PushI(REveRenderData::GL_LINE_LOOP);
      fRenderData->PushI(p.NPoints());
      fRenderData->PushI(p.fPnts);
   }

   assert (fRenderData->SizeI() == n_idxbuff);
}

////////////////////////////////////////////////////////////////////////////////
/// Override of virtual method from TAttBBox.

void REvePolygonSetProjected::ComputeBBox()
{
   if (fPnts.size() > 0) {
      BBoxInit();
      for (unsigned pi = 0; pi < fPnts.size(); ++pi)
         BBoxCheckPoint(fPnts[pi].fX, fPnts[pi].fY, fPnts[pi].fZ);
   } else {
      BBoxZero();
   }
}

////////////////////////////////////////////////////////////////////////////////
/// This is virtual method from base-class REveProjected.<commit_msg>eve7: fix wrong index calculation<commit_after>// @(#)root/eve:$Id$
// Authors: <NAME> & <NAME>: 2006, 2007

/*************************************************************************
 * Copyright (C) 1995-2007, <NAME> and <NAME>.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include <ROOT/REvePolygonSetProjected.hxx>
#include <ROOT/REveGeoShape.hxx>
#include <ROOT/REveProjectionManager.hxx>
#include <ROOT/REveGluTess.hxx>
#include <ROOT/REveRenderData.hxx>

#include "TBuffer3D.h"
#include "TBuffer3DTypes.h"
#include "TVirtualPad.h"
#include "TVirtualViewer3D.h"

#include "json.hpp"


using namespace ROOT::Experimental;
namespace REX = ROOT::Experimental;

namespace
{
   struct Seg_t
   {
      // Helper class for building 2D polygons from TBuffer3D.
      Int_t fV1;
      Int_t fV2;

      Seg_t(Int_t i1=-1, Int_t i2=-1) : fV1(i1), fV2(i2) {}
   };

   typedef std::list<Seg_t>           LSeg_t;
   typedef std::list<Seg_t>::iterator LSegIt_t;
}

/** \class REvePolygonSetProjected
\ingroup REve
A set of projected polygons.
Used for storage of projected geometrical shapes.

Internal struct Polygon_t holds only indices into the master vertex
array in REvePolygonSetProjected.
*/

////////////////////////////////////////////////////////////////////////////////
/// Constructor.

REvePolygonSetProjected::REvePolygonSetProjected(const char* n, const char* t) :
   REveShape(n, t),
   fBuff(),
   fPnts()
{
}

////////////////////////////////////////////////////////////////////////////////
/// Destructor.

REvePolygonSetProjected::~REvePolygonSetProjected()
{
   fPols.clear();
}

////////////////////////////////////////////////////////////////////////////////
/// Fill core part of JSON representation.

Int_t REvePolygonSetProjected::WriteCoreJson(nlohmann::json& j, Int_t rnr_offset)
{
   Int_t ret = REveElement::WriteCoreJson(j, rnr_offset);

   j["fNPnts"] = fPnts.size();

   return ret;
}

////////////////////////////////////////////////////////////////////////////////
/// Crates representation for rendering.
/// This is complicated as we need to:
/// - generate outlines;
/// - convert polygons to triangles.
/// ??? Should we check if polygons are front facing? It was not done in old EVE,
/// just GL_FRONT_AND_BACK was used on top of gluTess.

void REvePolygonSetProjected::BuildRenderData()
{
   fRenderData = std::make_unique<REveRenderData>("makePolygonSetProjected", 3 * fPnts.size());

   Int_t n_pols = fPols.size();
   Int_t n_poly_info = 0;
   for (auto &p : fPols) n_poly_info += 1 + p.NPoints();

   std::vector<Double_t> verts;
   verts.reserve(3 * fPnts.size());
   std::vector<Int_t>    polys;
   polys.reserve(n_poly_info);

   for (auto &p : fPols)
   {
      polys.emplace_back(p.NPoints());
      polys.insert(polys.end(), p.fPnts.begin(), p.fPnts.end());
   }

   for (unsigned i = 0; i < fPnts.size(); ++i)
   {
      verts.push_back(fPnts[i].fX);
      verts.push_back(fPnts[i].fY);
      verts.push_back(fPnts[i].fZ);
      fRenderData->PushV(fPnts[i]);
   }

   Int_t n_trings = 0;
   {
      EveGlu::TriangleCollector tc;

      tc.ProcessData(verts, polys, n_pols);

      polys.swap(tc.RefPolyDesc());
      n_trings = tc.GetNTrianlges();
   }

   // Calculate size of index buffer.
   Int_t n_idxbuff = 2 + 3 * n_trings + n_pols + n_poly_info;
   fRenderData->Reserve(0,0,n_idxbuff);

   assert(n_trings * 4 == (int)polys.size());

   // Export triangles.
   fRenderData->PushI(REveRenderData::GL_TRIANGLES);
   fRenderData->PushI(n_trings);
   for (int i = 0; i < n_trings; ++i)
   {
      fRenderData->PushI(&polys[i*4 + 1], 3);
   }

   assert (fRenderData->SizeI() == 2 + 3 * n_trings);

   // Export outlines.
   for (auto &p : fPols)
   {
      fRenderData->PushI(REveRenderData::GL_LINE_LOOP);
      fRenderData->PushI(p.NPoints());
      fRenderData->PushI(p.fPnts);
   }

   assert (fRenderData->SizeI() == n_idxbuff);
}

////////////////////////////////////////////////////////////////////////////////
/// Override of virtual method from TAttBBox.

void REvePolygonSetProjected::ComputeBBox()
{
   if (fPnts.size() > 0) {
      BBoxInit();
      for (unsigned pi = 0; pi < fPnts.size(); ++pi)
         BBoxCheckPoint(fPnts[pi].fX, fPnts[pi].fY, fPnts[pi].fZ);
   } else {
      BBoxZero();
   }
}

////////////////////////////////////////////////////////////////////////////////
/// This is virtual method from base-class REveProjected.
{'fraction_non_alphanumeric': 0.25196520280892987, 'fraction_numerical': 0.010376270831149774, 'mean_word_length': 2.0770719122863595, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6529914', 'n_tokens_mistral': 3270, 'n_tokens_neox': 3112, 'n_words': 644}