ROOT logo
// @(#)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 "TEveShape.h"
#include "Riostream.h"

//______________________________________________________________________________
//
// Abstract base-class for 2D/3D shapes.
// It provides:
// - fill color / transparency, accessible via Get/SetMainColor/Transparency;
// - frame line color / width;
// - flag if frame should be drawn;
// - flag specifying whether frame or whole shape should be emphasised for
//   highlight.

ClassImp(TEveShape);

//______________________________________________________________________________
TEveShape::TEveShape(const char* n, const char* t) :
   TEveElementList(n, t),
   fFillColor(5),
   fLineColor(5),
   fLineWidth(1),
   fDrawFrame(kTRUE),
   fHighlightFrame(kFALSE),
   fMiniFrame(kTRUE)
{
   // Constructor.

   fCanEditMainColor        = kTRUE;
   fCanEditMainTransparency = kTRUE;
   SetMainColorPtr(&fFillColor);
}

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

//______________________________________________________________________________
void TEveShape::SetMainColor(Color_t color)
{
   // Set main color.
   // Override so that line-color can also be changed if it is equal
   // to fill color (which is treated as main color).

   if (fFillColor == fLineColor) {
      fLineColor = color;
      StampObjProps();
   }
   TEveElementList::SetMainColor(color);
}

//______________________________________________________________________________
void TEveShape::CopyVizParams(const TEveElement* el)
{
   // Copy visualization parameters from element el.

   const TEveShape* m = dynamic_cast<const TEveShape*>(el);
   if (m)
   {
      fFillColor = m->fFillColor;
      fLineColor = m->fLineColor;
      fLineWidth = m->fLineWidth;
      fDrawFrame      = m->fDrawFrame;
      fHighlightFrame = m->fHighlightFrame;
      fMiniFrame      = m->fMiniFrame;
   }

   TEveElementList::CopyVizParams(el);
}

//______________________________________________________________________________
void TEveShape::WriteVizParams(ostream& out, const TString& var)
{
   // Write visualization parameters.

   TEveElementList::WriteVizParams(out, var);

   TString t = "   " + var + "->";
   out << t << "SetFillColor(" << fFillColor << ");\n";
   out << t << "SetLineColor(" << fLineColor << ");\n";
   out << t << "SetLineWidth(" << fLineWidth << ");\n";
   out << t << "SetDrawFrame("      << ToString(fDrawFrame) << ");\n";
   out << t << "SetHighlightFrame(" << ToString(fHighlightFrame) << ");\n";
}

//______________________________________________________________________________
void TEveShape::Paint(Option_t*)
{
   // Paint this object. Only direct rendering is supported.

   PaintStandard(this);
}

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

//______________________________________________________________________________
Int_t TEveShape::FindConvexHull(const vVector2_t& pin, vVector2_t& pout, TEveElement* caller)
{
   // Determines the convex-hull of points in pin.
   //
   // Adds the hull points to pout and returns the number of added points.
   // If size of pout is less then 3 then either the number of input points
   // was too low or they were degenerate so that the hull is actually a line
   // segment or even a point.

   Int_t N = pin.size();

   // Find the minimum (bottom-left) point.
   Int_t min_point = 0;
   for (Int_t i = 1; i < N; ++i)
   {
      if (pin[i].fY < pin[min_point].fY || (pin[i].fY == pin[min_point].fY && pin[i].fX < pin[min_point].fX))
         min_point = i;
   }

   // Calculate angles and sort.
   std::vector<Float_t> angles(N);
   for (Int_t i = 0; i < N; ++i)
   {
      angles[i] = (pin[i] - pin[min_point]).Phi();
   }
   std::vector<Int_t> idcs(N);
   TMath::Sort(N, &angles[0], &idcs[0], kFALSE);

   // Weed out points with the same angle -- keep the furthest only.
   // The first point must stay.
   if (N > 2)
   {
      std::vector<Int_t> new_idcs;
      new_idcs.push_back(idcs[0]);
      std::vector<Int_t>::iterator a, b;
      a = idcs.begin(); ++a;
      b = a; ++b;
      while (b != idcs.end())
      {
         if (TMath::Abs(angles[*a] - angles[*b]) < 1e-5f)
         {
            if (pin[idcs[0]].SquareDistance(pin[*a]) < pin[idcs[0]].SquareDistance(pin[*b]))
               a = b;
         }
         else
         {
            new_idcs.push_back(*a);
            a = b;
         }
         ++b;
      }
      new_idcs.push_back(*a);
      idcs.swap(new_idcs);
   }

   N = idcs.size();

   // Find hull.
   std::vector<Int_t> hull;
   if (N > 2)
   {
      hull.push_back(idcs[0]);
      hull.push_back(idcs[1]);
      hull.push_back(idcs[2]);
      {
         Int_t i = 3;
         while (i < N)
         {
            Int_t n = hull.size() - 1;
            if ((pin[hull[n]] - pin[hull[n-1]]).Cross(pin[idcs[i]] - pin[hull[n]]) > 0)
            {
               hull.push_back(idcs[i]);
               ++i;
            }
            else
            {
               hull.pop_back();
            }
         }
      }
   }
   else
   {
      ::Warning("TEveShape::FindConvexHull()", "Polygon reduced to %d points. for '%s'.",
              N, caller ? caller->GetElementName() : "unknown");
      hull.swap(idcs);
   }

   // Add hull points into the output vector.
   N = hull.size();
   Int_t Nold = pout.size();
   pout.resize(Nold + N);
   for (Int_t i = 0; i < N; ++i)
   {
      pout[Nold + i] = pin[hull[i]];
   }

   // Print the hull.
   // for (Int_t i = 0; i < N; ++i)
   // {
   //    const TEveVector2 &p = pin[hull[i]];
   //    printf("%d [%d] (%5.1f, %5.1f) %f\n", i, hull[i], p.fX, p.fY, angles[hull[i]]);
   // }

   return N;
}

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

//______________________________________________________________________________
Bool_t TEveShape::IsBoxOrientationConsistentEv(const TEveVector box[8])
{
   // Checks if the first face normal is pointing into the other
   // direction as the vector pointing towards the opposite face.
   // This assumes standard box vertex arrangement.

   TEveVector f1 = box[1] - box[0];
   TEveVector f2 = box[3] - box[0];
   TEveVector up = box[4] - box[0];

   return up.Dot(f1.Cross(f2)) < 0;
}

//______________________________________________________________________________
Bool_t TEveShape::IsBoxOrientationConsistentFv(const Float_t box[8][3])
{
   // Checks if the first face normal is pointing into the other
   // direction as the vector pointing towards the opposite face.
   // This assumes standard box vertex arrangement.

   TEveVector b0(box[0]);
   TEveVector f1(box[1]); f1 -= b0;
   TEveVector f2(box[3]); f2 -= b0;
   TEveVector up(box[4]); up -= b0;

   return up.Dot(f1.Cross(f2)) < 0;
}

//______________________________________________________________________________
void TEveShape::CheckAndFixBoxOrientationEv(TEveVector box[8])
{
   // Make sure box orientation is consistent with standard arrangement.

   if ( ! IsBoxOrientationConsistentEv(box))
   {
      std::swap(box[1], box[3]);
      std::swap(box[5], box[7]);
   }
}

//______________________________________________________________________________
void TEveShape::CheckAndFixBoxOrientationFv(Float_t box[8][3])
{
   // Make sure box orientation is consistent with standard arrangement.

   if ( ! IsBoxOrientationConsistentFv(box))
   {
      std::swap(box[1][0], box[3][0]);
      std::swap(box[1][1], box[3][1]);
      std::swap(box[1][2], box[3][2]);
      std::swap(box[5][0], box[7][0]);
      std::swap(box[5][1], box[7][1]);
      std::swap(box[5][2], box[7][2]);
   }
}
 TEveShape.cxx:1
 TEveShape.cxx:2
 TEveShape.cxx:3
 TEveShape.cxx:4
 TEveShape.cxx:5
 TEveShape.cxx:6
 TEveShape.cxx:7
 TEveShape.cxx:8
 TEveShape.cxx:9
 TEveShape.cxx:10
 TEveShape.cxx:11
 TEveShape.cxx:12
 TEveShape.cxx:13
 TEveShape.cxx:14
 TEveShape.cxx:15
 TEveShape.cxx:16
 TEveShape.cxx:17
 TEveShape.cxx:18
 TEveShape.cxx:19
 TEveShape.cxx:20
 TEveShape.cxx:21
 TEveShape.cxx:22
 TEveShape.cxx:23
 TEveShape.cxx:24
 TEveShape.cxx:25
 TEveShape.cxx:26
 TEveShape.cxx:27
 TEveShape.cxx:28
 TEveShape.cxx:29
 TEveShape.cxx:30
 TEveShape.cxx:31
 TEveShape.cxx:32
 TEveShape.cxx:33
 TEveShape.cxx:34
 TEveShape.cxx:35
 TEveShape.cxx:36
 TEveShape.cxx:37
 TEveShape.cxx:38
 TEveShape.cxx:39
 TEveShape.cxx:40
 TEveShape.cxx:41
 TEveShape.cxx:42
 TEveShape.cxx:43
 TEveShape.cxx:44
 TEveShape.cxx:45
 TEveShape.cxx:46
 TEveShape.cxx:47
 TEveShape.cxx:48
 TEveShape.cxx:49
 TEveShape.cxx:50
 TEveShape.cxx:51
 TEveShape.cxx:52
 TEveShape.cxx:53
 TEveShape.cxx:54
 TEveShape.cxx:55
 TEveShape.cxx:56
 TEveShape.cxx:57
 TEveShape.cxx:58
 TEveShape.cxx:59
 TEveShape.cxx:60
 TEveShape.cxx:61
 TEveShape.cxx:62
 TEveShape.cxx:63
 TEveShape.cxx:64
 TEveShape.cxx:65
 TEveShape.cxx:66
 TEveShape.cxx:67
 TEveShape.cxx:68
 TEveShape.cxx:69
 TEveShape.cxx:70
 TEveShape.cxx:71
 TEveShape.cxx:72
 TEveShape.cxx:73
 TEveShape.cxx:74
 TEveShape.cxx:75
 TEveShape.cxx:76
 TEveShape.cxx:77
 TEveShape.cxx:78
 TEveShape.cxx:79
 TEveShape.cxx:80
 TEveShape.cxx:81
 TEveShape.cxx:82
 TEveShape.cxx:83
 TEveShape.cxx:84
 TEveShape.cxx:85
 TEveShape.cxx:86
 TEveShape.cxx:87
 TEveShape.cxx:88
 TEveShape.cxx:89
 TEveShape.cxx:90
 TEveShape.cxx:91
 TEveShape.cxx:92
 TEveShape.cxx:93
 TEveShape.cxx:94
 TEveShape.cxx:95
 TEveShape.cxx:96
 TEveShape.cxx:97
 TEveShape.cxx:98
 TEveShape.cxx:99
 TEveShape.cxx:100
 TEveShape.cxx:101
 TEveShape.cxx:102
 TEveShape.cxx:103
 TEveShape.cxx:104
 TEveShape.cxx:105
 TEveShape.cxx:106
 TEveShape.cxx:107
 TEveShape.cxx:108
 TEveShape.cxx:109
 TEveShape.cxx:110
 TEveShape.cxx:111
 TEveShape.cxx:112
 TEveShape.cxx:113
 TEveShape.cxx:114
 TEveShape.cxx:115
 TEveShape.cxx:116
 TEveShape.cxx:117
 TEveShape.cxx:118
 TEveShape.cxx:119
 TEveShape.cxx:120
 TEveShape.cxx:121
 TEveShape.cxx:122
 TEveShape.cxx:123
 TEveShape.cxx:124
 TEveShape.cxx:125
 TEveShape.cxx:126
 TEveShape.cxx:127
 TEveShape.cxx:128
 TEveShape.cxx:129
 TEveShape.cxx:130
 TEveShape.cxx:131
 TEveShape.cxx:132
 TEveShape.cxx:133
 TEveShape.cxx:134
 TEveShape.cxx:135
 TEveShape.cxx:136
 TEveShape.cxx:137
 TEveShape.cxx:138
 TEveShape.cxx:139
 TEveShape.cxx:140
 TEveShape.cxx:141
 TEveShape.cxx:142
 TEveShape.cxx:143
 TEveShape.cxx:144
 TEveShape.cxx:145
 TEveShape.cxx:146
 TEveShape.cxx:147
 TEveShape.cxx:148
 TEveShape.cxx:149
 TEveShape.cxx:150
 TEveShape.cxx:151
 TEveShape.cxx:152
 TEveShape.cxx:153
 TEveShape.cxx:154
 TEveShape.cxx:155
 TEveShape.cxx:156
 TEveShape.cxx:157
 TEveShape.cxx:158
 TEveShape.cxx:159
 TEveShape.cxx:160
 TEveShape.cxx:161
 TEveShape.cxx:162
 TEveShape.cxx:163
 TEveShape.cxx:164
 TEveShape.cxx:165
 TEveShape.cxx:166
 TEveShape.cxx:167
 TEveShape.cxx:168
 TEveShape.cxx:169
 TEveShape.cxx:170
 TEveShape.cxx:171
 TEveShape.cxx:172
 TEveShape.cxx:173
 TEveShape.cxx:174
 TEveShape.cxx:175
 TEveShape.cxx:176
 TEveShape.cxx:177
 TEveShape.cxx:178
 TEveShape.cxx:179
 TEveShape.cxx:180
 TEveShape.cxx:181
 TEveShape.cxx:182
 TEveShape.cxx:183
 TEveShape.cxx:184
 TEveShape.cxx:185
 TEveShape.cxx:186
 TEveShape.cxx:187
 TEveShape.cxx:188
 TEveShape.cxx:189
 TEveShape.cxx:190
 TEveShape.cxx:191
 TEveShape.cxx:192
 TEveShape.cxx:193
 TEveShape.cxx:194
 TEveShape.cxx:195
 TEveShape.cxx:196
 TEveShape.cxx:197
 TEveShape.cxx:198
 TEveShape.cxx:199
 TEveShape.cxx:200
 TEveShape.cxx:201
 TEveShape.cxx:202
 TEveShape.cxx:203
 TEveShape.cxx:204
 TEveShape.cxx:205
 TEveShape.cxx:206
 TEveShape.cxx:207
 TEveShape.cxx:208
 TEveShape.cxx:209
 TEveShape.cxx:210
 TEveShape.cxx:211
 TEveShape.cxx:212
 TEveShape.cxx:213
 TEveShape.cxx:214
 TEveShape.cxx:215
 TEveShape.cxx:216
 TEveShape.cxx:217
 TEveShape.cxx:218
 TEveShape.cxx:219
 TEveShape.cxx:220
 TEveShape.cxx:221
 TEveShape.cxx:222
 TEveShape.cxx:223
 TEveShape.cxx:224
 TEveShape.cxx:225
 TEveShape.cxx:226
 TEveShape.cxx:227
 TEveShape.cxx:228
 TEveShape.cxx:229
 TEveShape.cxx:230
 TEveShape.cxx:231
 TEveShape.cxx:232
 TEveShape.cxx:233
 TEveShape.cxx:234
 TEveShape.cxx:235
 TEveShape.cxx:236
 TEveShape.cxx:237
 TEveShape.cxx:238
 TEveShape.cxx:239
 TEveShape.cxx:240
 TEveShape.cxx:241
 TEveShape.cxx:242
 TEveShape.cxx:243
 TEveShape.cxx:244
 TEveShape.cxx:245
 TEveShape.cxx:246
 TEveShape.cxx:247
 TEveShape.cxx:248
 TEveShape.cxx:249
 TEveShape.cxx:250
 TEveShape.cxx:251
 TEveShape.cxx:252
 TEveShape.cxx:253
 TEveShape.cxx:254
 TEveShape.cxx:255
 TEveShape.cxx:256
 TEveShape.cxx:257
 TEveShape.cxx:258
 TEveShape.cxx:259
 TEveShape.cxx:260
 TEveShape.cxx:261
 TEveShape.cxx:262
 TEveShape.cxx:263
 TEveShape.cxx:264
 TEveShape.cxx:265
 TEveShape.cxx:266
 TEveShape.cxx:267
 TEveShape.cxx:268
 TEveShape.cxx:269
 TEveShape.cxx:270
 TEveShape.cxx:271
 TEveShape.cxx:272
 TEveShape.cxx:273