// @(#)root/eve:$Id$
// Author: Matevz Tadel, 2010

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

#include "TEveBox.h"
#include "TEveProjectionManager.h"

//==============================================================================
// TEveBox
//==============================================================================

//______________________________________________________________________________
//
// 3D box with arbitrary vertices (cuboid).
// Vertices 0-3 specify the "bottom" rectangle in clockwise direction and
// vertices 4-7 the "top" rectangle so that 4 is above 0, 5 above 1 and so on.
//
// If vertices are provided some local coordinates the transformation matrix
// of the element should also be set (but then the memory usage is increased
// by the size of the TEveTrans object).
//
// Currently only supports 3D -> 2D projections.

ClassImp(TEveBox);

//______________________________________________________________________________
TEveBox::TEveBox(const char* n, const char* t) :
   TEveShape(n, t)
{
   // Constructor.
}

//______________________________________________________________________________
TEveBox::~TEveBox()
{
   // Destructor.
}

//______________________________________________________________________________
void TEveBox::SetVertex(Int_t i, Float_t x, Float_t y, Float_t z)
{
   // Set vertex 'i'.

   fVertices[i][0] = x;
   fVertices[i][1] = y;
   fVertices[i][2] = z;
   ResetBBox();
}

//______________________________________________________________________________
void TEveBox::SetVertex(Int_t i, const Float_t* v)
{
   // Set vertex 'i'.

   fVertices[i][0] = v[0];
   fVertices[i][1] = v[1];
   fVertices[i][2] = v[2];
   ResetBBox();
}

//______________________________________________________________________________
void TEveBox::SetVertices(const Float_t* vs)
{
   // Set vertices.

   memcpy(fVertices, vs, sizeof(fVertices));
   ResetBBox();
}

//==============================================================================

//______________________________________________________________________________
void TEveBox::ComputeBBox()
{
   // Compute bounding-box of the data.

   TEveShape::CheckAndFixBoxOrientationFv(fVertices);

   BBoxInit();
   for (Int_t i=0; i<8; ++i)
   {
      BBoxCheckPoint(fVertices[i]);
   }
}

//______________________________________________________________________________
TClass* TEveBox::ProjectedClass(const TEveProjection*) const
{
   // Virtual from TEveProjectable, return TEveBoxProjected class.

   return TEveBoxProjected::Class();
}


//==============================================================================
// TEveBoxProjected
//==============================================================================

//______________________________________________________________________________
//
// Projection of TEveBox.

ClassImp(TEveBoxProjected);

Bool_t TEveBoxProjected::fgDebugCornerPoints = kFALSE;

//______________________________________________________________________________
TEveBoxProjected::TEveBoxProjected(const char* n, const char* t) :
   TEveShape(n, t),
   fBreakIdx(0)
{
   // Constructor.
}

//______________________________________________________________________________
TEveBoxProjected::~TEveBoxProjected()
{
   // Destructor.
}

//______________________________________________________________________________
void TEveBoxProjected::ComputeBBox()
{
   // Compute bounding-box, virtual from TAttBBox.

   BBoxInit();
   for (vVector2_i i = fPoints.begin(); i != fPoints.end(); ++i)
   {
      BBoxCheckPoint(i->fX, i->fY, fDepth);
   }
}

//______________________________________________________________________________
void TEveBoxProjected::SetDepthLocal(Float_t d)
{
   // This is virtual method from base-class TEveProjected.

   SetDepthCommon(d, this, fBBox);
}

//______________________________________________________________________________
void TEveBoxProjected::SetProjection(TEveProjectionManager* mng, TEveProjectable* model)
{
   // This is virtual method from base-class TEveProjected.

   TEveProjected::SetProjection(mng, model);
   CopyVizParams(dynamic_cast<TEveElement*>(model));
}

//______________________________________________________________________________
void TEveBoxProjected::UpdateProjection()
{
   // Re-project the box. Projects all points and finds 2D convex-hull.
   //
   // The only issue is with making sure that initial conditions for
   // hull-search are reasonable -- that is, there are no overlaps with the
   // first point.

   TEveBox *box = dynamic_cast<TEveBox*>(fProjectable);

   fDebugPoints.clear();

   // Project points in global CS, remove overlaps.
   vVector2_t pp[2];
   {
      TEveProjection *projection = fManager->GetProjection();
      TEveTrans      *trans      = box->PtrMainTrans(kFALSE);

      TEveVector pbuf;
      for (Int_t i = 0; i < 8; ++i)
      {
         projection->ProjectPointfv(trans, box->GetVertex(i), pbuf, fDepth);
         vVector2_t& ppv = pp[projection->SubSpaceId(pbuf)];

         TEveVector2 p(pbuf);
         Bool_t      overlap = kFALSE;
         for (vVector2_i j = ppv.begin(); j != ppv.end(); ++j)
         {
            if (p.SquareDistance(*j) < TEveProjection::fgEpsSqr)
            {
               overlap = kTRUE;
               break;
            }
         }
         if (! overlap)
         {
            ppv.push_back(p);
            if (fgDebugCornerPoints)
               fDebugPoints.push_back(p);
         }
      }
   }

   fPoints.clear();
   fBreakIdx = 0;

   if ( ! pp[0].empty())
   {
      FindConvexHull(pp[0], fPoints, this);
   }
   if ( ! pp[1].empty())
   {
      fBreakIdx = fPoints.size();
      FindConvexHull(pp[1], fPoints, this);
   }
}

//______________________________________________________________________________
Bool_t TEveBoxProjected::GetDebugCornerPoints()
{
   // Get state of fgDebugCornerPoints static.

   return fgDebugCornerPoints;
}

//______________________________________________________________________________
void TEveBoxProjected::SetDebugCornerPoints(Bool_t d)
{
   // Set state of fgDebugCornerPoints static.
   // When this is true, points will be drawn at the corners of
   // computed convex hull.

   fgDebugCornerPoints = d;
}
 TEveBox.cxx:1
 TEveBox.cxx:2
 TEveBox.cxx:3
 TEveBox.cxx:4
 TEveBox.cxx:5
 TEveBox.cxx:6
 TEveBox.cxx:7
 TEveBox.cxx:8
 TEveBox.cxx:9
 TEveBox.cxx:10
 TEveBox.cxx:11
 TEveBox.cxx:12
 TEveBox.cxx:13
 TEveBox.cxx:14
 TEveBox.cxx:15
 TEveBox.cxx:16
 TEveBox.cxx:17
 TEveBox.cxx:18
 TEveBox.cxx:19
 TEveBox.cxx:20
 TEveBox.cxx:21
 TEveBox.cxx:22
 TEveBox.cxx:23
 TEveBox.cxx:24
 TEveBox.cxx:25
 TEveBox.cxx:26
 TEveBox.cxx:27
 TEveBox.cxx:28
 TEveBox.cxx:29
 TEveBox.cxx:30
 TEveBox.cxx:31
 TEveBox.cxx:32
 TEveBox.cxx:33
 TEveBox.cxx:34
 TEveBox.cxx:35
 TEveBox.cxx:36
 TEveBox.cxx:37
 TEveBox.cxx:38
 TEveBox.cxx:39
 TEveBox.cxx:40
 TEveBox.cxx:41
 TEveBox.cxx:42
 TEveBox.cxx:43
 TEveBox.cxx:44
 TEveBox.cxx:45
 TEveBox.cxx:46
 TEveBox.cxx:47
 TEveBox.cxx:48
 TEveBox.cxx:49
 TEveBox.cxx:50
 TEveBox.cxx:51
 TEveBox.cxx:52
 TEveBox.cxx:53
 TEveBox.cxx:54
 TEveBox.cxx:55
 TEveBox.cxx:56
 TEveBox.cxx:57
 TEveBox.cxx:58
 TEveBox.cxx:59
 TEveBox.cxx:60
 TEveBox.cxx:61
 TEveBox.cxx:62
 TEveBox.cxx:63
 TEveBox.cxx:64
 TEveBox.cxx:65
 TEveBox.cxx:66
 TEveBox.cxx:67
 TEveBox.cxx:68
 TEveBox.cxx:69
 TEveBox.cxx:70
 TEveBox.cxx:71
 TEveBox.cxx:72
 TEveBox.cxx:73
 TEveBox.cxx:74
 TEveBox.cxx:75
 TEveBox.cxx:76
 TEveBox.cxx:77
 TEveBox.cxx:78
 TEveBox.cxx:79
 TEveBox.cxx:80
 TEveBox.cxx:81
 TEveBox.cxx:82
 TEveBox.cxx:83
 TEveBox.cxx:84
 TEveBox.cxx:85
 TEveBox.cxx:86
 TEveBox.cxx:87
 TEveBox.cxx:88
 TEveBox.cxx:89
 TEveBox.cxx:90
 TEveBox.cxx:91
 TEveBox.cxx:92
 TEveBox.cxx:93
 TEveBox.cxx:94
 TEveBox.cxx:95
 TEveBox.cxx:96
 TEveBox.cxx:97
 TEveBox.cxx:98
 TEveBox.cxx:99
 TEveBox.cxx:100
 TEveBox.cxx:101
 TEveBox.cxx:102
 TEveBox.cxx:103
 TEveBox.cxx:104
 TEveBox.cxx:105
 TEveBox.cxx:106
 TEveBox.cxx:107
 TEveBox.cxx:108
 TEveBox.cxx:109
 TEveBox.cxx:110
 TEveBox.cxx:111
 TEveBox.cxx:112
 TEveBox.cxx:113
 TEveBox.cxx:114
 TEveBox.cxx:115
 TEveBox.cxx:116
 TEveBox.cxx:117
 TEveBox.cxx:118
 TEveBox.cxx:119
 TEveBox.cxx:120
 TEveBox.cxx:121
 TEveBox.cxx:122
 TEveBox.cxx:123
 TEveBox.cxx:124
 TEveBox.cxx:125
 TEveBox.cxx:126
 TEveBox.cxx:127
 TEveBox.cxx:128
 TEveBox.cxx:129
 TEveBox.cxx:130
 TEveBox.cxx:131
 TEveBox.cxx:132
 TEveBox.cxx:133
 TEveBox.cxx:134
 TEveBox.cxx:135
 TEveBox.cxx:136
 TEveBox.cxx:137
 TEveBox.cxx:138
 TEveBox.cxx:139
 TEveBox.cxx:140
 TEveBox.cxx:141
 TEveBox.cxx:142
 TEveBox.cxx:143
 TEveBox.cxx:144
 TEveBox.cxx:145
 TEveBox.cxx:146
 TEveBox.cxx:147
 TEveBox.cxx:148
 TEveBox.cxx:149
 TEveBox.cxx:150
 TEveBox.cxx:151
 TEveBox.cxx:152
 TEveBox.cxx:153
 TEveBox.cxx:154
 TEveBox.cxx:155
 TEveBox.cxx:156
 TEveBox.cxx:157
 TEveBox.cxx:158
 TEveBox.cxx:159
 TEveBox.cxx:160
 TEveBox.cxx:161
 TEveBox.cxx:162
 TEveBox.cxx:163
 TEveBox.cxx:164
 TEveBox.cxx:165
 TEveBox.cxx:166
 TEveBox.cxx:167
 TEveBox.cxx:168
 TEveBox.cxx:169
 TEveBox.cxx:170
 TEveBox.cxx:171
 TEveBox.cxx:172
 TEveBox.cxx:173
 TEveBox.cxx:174
 TEveBox.cxx:175
 TEveBox.cxx:176
 TEveBox.cxx:177
 TEveBox.cxx:178
 TEveBox.cxx:179
 TEveBox.cxx:180
 TEveBox.cxx:181
 TEveBox.cxx:182
 TEveBox.cxx:183
 TEveBox.cxx:184
 TEveBox.cxx:185
 TEveBox.cxx:186
 TEveBox.cxx:187
 TEveBox.cxx:188
 TEveBox.cxx:189
 TEveBox.cxx:190
 TEveBox.cxx:191
 TEveBox.cxx:192
 TEveBox.cxx:193
 TEveBox.cxx:194
 TEveBox.cxx:195
 TEveBox.cxx:196
 TEveBox.cxx:197
 TEveBox.cxx:198
 TEveBox.cxx:199
 TEveBox.cxx:200
 TEveBox.cxx:201
 TEveBox.cxx:202
 TEveBox.cxx:203
 TEveBox.cxx:204
 TEveBox.cxx:205
 TEveBox.cxx:206
 TEveBox.cxx:207
 TEveBox.cxx:208
 TEveBox.cxx:209
 TEveBox.cxx:210
 TEveBox.cxx:211
 TEveBox.cxx:212
 TEveBox.cxx:213
 TEveBox.cxx:214
 TEveBox.cxx:215
 TEveBox.cxx:216
 TEveBox.cxx:217
 TEveBox.cxx:218
 TEveBox.cxx:219
 TEveBox.cxx:220
 TEveBox.cxx:221
 TEveBox.cxx:222
 TEveBox.cxx:223
 TEveBox.cxx:224
 TEveBox.cxx:225
 TEveBox.cxx:226
 TEveBox.cxx:227
 TEveBox.cxx:228
 TEveBox.cxx:229
 TEveBox.cxx:230
 TEveBox.cxx:231