#include "TEvePolygonSetProjected.h"
#include "TEveVSDStructs.h"
#include "TEveGeoNode.h"
#include "TEveProjectionManager.h"
#include "TBuffer3D.h"
#include "TBuffer3DTypes.h"
#include "TVirtualPad.h"
#include "TVirtualViewer3D.h"
namespace
{
struct Seg_t
{
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;
}
ClassImp(TEvePolygonSetProjected)
TEvePolygonSetProjected::TEvePolygonSetProjected(const Text_t* n, const Text_t* t) :
TEveElementList(n, t),
fBuff(0),
fIdxMap(0),
fSurf(0),
fNPnts(0),
fPnts(0),
fFillColor(5),
fLineColor(3),
fLineWidth(1),
fTransparency (0)
{
SetMainColorPtr(&fFillColor);
}
TEvePolygonSetProjected::~TEvePolygonSetProjected()
{
ClearPolygonSet();
}
void TEvePolygonSetProjected::ClearPolygonSet()
{
Int_t* p;
for (vpPolygon_i i = fPols.begin(); i!= fPols.end(); i++)
{
p = (*i).fPnts; delete [] p;
}
fPols.clear();
delete [] fPnts;
}
void TEvePolygonSetProjected::SetProjection(TEveProjectionManager* proj,
TEveProjectable* model)
{
TEveProjected::SetProjection(proj, model);
TEveGeoShape* gre = dynamic_cast<TEveGeoShape*>(model);
fBuff = gre->MakeBuffer3D();
if (fBuff)
{
Color_t color = gre->GetMainColor();
SetMainColor(color);
SetLineColor((Color_t)TColor::GetColorBright(color));
SetMainTransparency(gre->GetMainTransparency());
}
}
void TEvePolygonSetProjected::UpdateProjection()
{
if (fBuff == 0) return;
ClearPolygonSet();
fPnts = 0;
fNPnts = 0;
fSurf = 0;
ProjectBuffer3D();
}
Bool_t TEvePolygonSetProjected::IsFirstIdxHead(Int_t s0, Int_t s1)
{
Int_t v0 = fBuff->fSegs[3*s0 + 1];
Int_t v2 = fBuff->fSegs[3*s1 + 1];
Int_t v3 = fBuff->fSegs[3*s1 + 2];
return v0 != v2 && v0 != v3;
}
void TEvePolygonSetProjected::ProjectAndReducePoints()
{
TEveProjection* projection = fProjector->GetProjection();
Int_t buffN = fBuff->NbPnts();
TEveVector* pnts = new TEveVector[buffN];
for (Int_t i = 0; i<buffN; ++i)
{
pnts[i].Set(fBuff->fPnts[3*i],fBuff->fPnts[3*i+1], fBuff->fPnts[3*i+2]);
projection->ProjectPoint(pnts[i].fX, pnts[i].fY, pnts[i].fZ, TEveProjection::kPP_Plane);
}
fIdxMap = new Int_t[buffN];
Int_t* ra = new Int_t[buffN];
for (UInt_t v = 0; v < (UInt_t)buffN; ++v)
{
fIdxMap[v] = -1;
for (Int_t k = 0; k < fNPnts; ++k)
{
if(pnts[v].SquareDistance(pnts[ra[k]]) < TEveProjection::fgEps*TEveProjection::fgEps)
{
fIdxMap[v] = k;
break;
}
}
if (fIdxMap[v] == -1)
{
fIdxMap[v] = fNPnts;
ra[fNPnts] = v;
++fNPnts;
}
}
fPnts = new TEveVector[fNPnts];
for (Int_t idx = 0; idx < fNPnts; ++idx)
{
Int_t i = ra[idx];
projection->ProjectPoint(pnts[i].fX, pnts[i].fY, pnts[i].fZ, TEveProjection::kPP_Distort);
fPnts[idx].Set(pnts[i]);
}
delete [] ra;
delete [] pnts;
}
void TEvePolygonSetProjected::AddPolygon(std::list<Int_t>& pp, vpPolygon_t& pols)
{
if (pp.size() <= 2) return;
Float_t bbox[] = { 1e6, -1e6, 1e6, -1e6, 1e6, -1e6 };
for (std::list<Int_t>::iterator u = pp.begin(); u!= pp.end(); u++)
{
Int_t idx = *u;
if (fPnts[idx].fX < bbox[0]) bbox[0] = fPnts[idx].fX;
if (fPnts[idx].fX > bbox[1]) bbox[1] = fPnts[idx].fX;
if (fPnts[idx].fY < bbox[2]) bbox[2] = fPnts[idx].fY;
if (fPnts[idx].fY > bbox[3]) bbox[3] = fPnts[idx].fY;
}
Float_t eps = 2*TEveProjection::fgEps;
if ((bbox[1]-bbox[0]) < eps || (bbox[3]-bbox[2]) < eps) return;
for (vpPolygon_i poi = pols.begin(); poi != pols.end(); poi++)
{
Polygon_t& refP = *poi;
if ((Int_t)pp.size() != refP.fNPnts)
continue;
std::list<Int_t>::iterator u = pp.begin();
Int_t pidx = refP.FindPoint(*u);
if (pidx < 0)
continue;
while (u != pp.end())
{
if ((*u) != refP.fPnts[pidx])
break;
++u;
if (++pidx >= refP.fNPnts) pidx = 0;
}
if (u == pp.end()) return;
}
Int_t* pv = new Int_t[pp.size()];
Int_t count=0;
for (std::list<Int_t>::iterator u = pp.begin(); u != pp.end(); u++)
{
pv[count] = *u;
count++;
}
pols.push_back(Polygon_t((Int_t)pp.size(), pv));
fSurf += (bbox[1]-bbox[0]) * (bbox[3]-bbox[2]);
}
void TEvePolygonSetProjected::MakePolygonsFromBP()
{
TEveProjection* projection = fProjector->GetProjection();
Int_t* bpols = fBuff->fPols;
for (UInt_t pi = 0; pi< fBuff->NbPols(); pi++)
{
std::list<Int_t> pp;
UInt_t segN = bpols[1];
Int_t* seg = &bpols[2];
Int_t tail, head;
Bool_t h = IsFirstIdxHead(seg[0], seg[1]);
if (h) {
head = fIdxMap[fBuff->fSegs[3*seg[0] + 1]];
tail = fIdxMap[fBuff->fSegs[3*seg[0] + 2]];
}
else
{
head = fIdxMap[fBuff->fSegs[3*seg[0] + 2]];
tail = fIdxMap[fBuff->fSegs[3*seg[0] + 1]];
}
pp.push_back(head);
LSeg_t segs;
for (UInt_t s = 1; s < segN; ++s)
segs.push_back(Seg_t(fBuff->fSegs[3*seg[s] + 1],fBuff->fSegs[3*seg[s] + 2]));
Bool_t accepted = kFALSE;
for (LSegIt_t it = segs.begin(); it != segs.end(); ++it)
{
Int_t mv1 = fIdxMap[(*it).fV1];
Int_t mv2 = fIdxMap[(*it).fV2];
accepted = projection->AcceptSegment(fPnts[mv1], fPnts[mv2], TEveProjection::fgEps);
if(accepted == kFALSE)
{
pp.clear();
break;
}
if(tail != pp.back()) pp.push_back(tail);
tail = (mv1 == tail) ? mv2 :mv1;
}
if (pp.empty() == kFALSE)
{
if (pp.front() == pp.back()) pp.pop_front();
AddPolygon(pp, fPolsBP);
}
bpols += (segN+2);
}
}
void TEvePolygonSetProjected::MakePolygonsFromBS()
{
LSeg_t segs;
LSegIt_t it;
TEveProjection* projection = fProjector->GetProjection();
for (UInt_t s = 0; s < fBuff->NbSegs(); ++s)
{
Bool_t duplicate = kFALSE;
Int_t vo1, vo2;
Int_t vor1, vor2;
vo1 = fBuff->fSegs[3*s + 1];
vo2 = fBuff->fSegs[3*s + 2];
vor1 = fIdxMap[vo1];
vor2 = fIdxMap[vo2];
if (vor1 == vor2) continue;
for (it = segs.begin(); it != segs.end(); it++ ){
Int_t vv1 = (*it).fV1;
Int_t vv2 = (*it).fV2;
if((vv1 == vor1 && vv2 == vor2 )||(vv1 == vor2 && vv2 == vor1 )) {
duplicate = kTRUE;
continue;
}
}
if (duplicate == kFALSE && projection->AcceptSegment(fPnts[vor1], fPnts[vor2], TEveProjection::fgEps))
segs.push_back(Seg_t(vor1, vor2));
}
while (segs.empty() == kFALSE)
{
std::list<Int_t> pp;
pp.push_back(segs.front().fV1);
Int_t tail = segs.front().fV2;
segs.pop_front();
Bool_t match = kTRUE;
while (match && segs.empty() == kFALSE)
{
for (LSegIt_t k = segs.begin(); k != segs.end(); ++k)
{
Int_t cv1 = (*k).fV1;
Int_t cv2 = (*k).fV2;
if (cv1 == tail || cv2 == tail)
{
pp.push_back(tail);
tail = (cv1 == tail) ? cv2 : cv1;
LSegIt_t to_erase = k--;
segs.erase(to_erase);
match = kTRUE;
break;
}
else
{
match = kFALSE;
}
}
if (tail == pp.front())
break;
}
AddPolygon(pp, fPolsBS);
}
}
void TEvePolygonSetProjected::ProjectBuffer3D()
{
ProjectAndReducePoints();
TEveProjection::EGeoMode_e mode = fProjector->GetProjection()->GetGeoMode();
switch (mode)
{
case TEveProjection::kGM_Polygons :
{
MakePolygonsFromBP();
fPolsBP.swap(fPols);
break;
}
case TEveProjection::kGM_Segments :
{
MakePolygonsFromBS();
fPolsBS.swap(fPols);
break;
}
case TEveProjection::kGM_Unknown:
{
Float_t surfBP = fSurf;
fSurf = 0;
MakePolygonsFromBS();
if(fSurf < surfBP)
{
fPolsBP.swap(fPols);
fPolsBS.clear();
}
else
{
fPolsBS.swap(fPols);
fPolsBP.clear();
}
}
default:
break;
}
delete [] fIdxMap;
ResetBBox();
}
void TEvePolygonSetProjected::ComputeBBox()
{
BBoxInit();
for (Int_t pi = 0; pi<fNPnts; ++pi)
BBoxCheckPoint(fPnts[pi].fX, fPnts[pi].fY, fPnts[pi].fZ);
AssertBBoxExtents(0.1);
}
void TEvePolygonSetProjected::Paint(Option_t* )
{
static const TEveException eh("TEvePolygonSetProjected::Paint ");
if (fNPnts == 0) return;
TBuffer3D buffer(TBuffer3DTypes::kGeneric);
buffer.fID = this;
buffer.fColor = GetMainColor();
buffer.fTransparency = fTransparency;
buffer.fLocalFrame = false;
buffer.SetSectionsValid(TBuffer3D::kCore);
Int_t reqSections = gPad->GetViewer3D()->AddObject(buffer);
if (reqSections != TBuffer3D::kNone)
Warning(eh, "Viewer3D requires more (%d).", reqSections);
}
void TEvePolygonSetProjected::DumpPolys() const
{
printf("TEvePolygonSetProjected %d polygons\n", (Int_t)fPols.size());
for (vpPolygon_ci i = fPols.begin(); i!= fPols.end(); i++)
{
Int_t nPnts = (*i).fNPnts;
printf("Points of polygon %d:\n", nPnts);
for (Int_t vi = 0; vi<nPnts; vi++) {
Int_t pi = (*i).fPnts[vi];
printf("(%f, %f, %f)", fPnts[pi].fX, fPnts[pi].fY, fPnts[pi].fZ);
}
printf("\n");
}
}
void TEvePolygonSetProjected::DumpBuffer3D()
{
Int_t* bpols = fBuff->fPols;
for(UInt_t pi = 0; pi< fBuff->NbPols(); ++pi)
{
UInt_t segN = bpols[1];
printf("%d polygon of %d has %d segments \n", pi,fBuff->NbPols(),segN);
Int_t* seg = &bpols[2];
for (UInt_t a=0; a<segN; ++a)
{
Int_t a1 = fBuff->fSegs[3*seg[a] + 1];
Int_t a2 = fBuff->fSegs[3*seg[a] + 2];
printf("(%d, %d) \n", a1, a2);
printf("ORIG points :(%f, %f, %f) (%f, %f, %f)\n",
fBuff->fPnts[3*a1],fBuff->fPnts[3*a1+1], fBuff->fPnts[3*a1+2],
fBuff->fPnts[3*a2],fBuff->fPnts[3*a2+1], fBuff->fPnts[3*a2+2]);
}
printf("\n");
bpols += (segN+2);
}
}
Last update: Thu Jan 17 08:49:01 2008
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.