// @(#)root/g3d:$Id$
// Author: Nenad Buncic   17/09/95

/*************************************************************************
 * Copyright (C) 1995-2000, 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 "TNode.h"
#include "TShape.h"
#include "TView.h"
#include "TVirtualPad.h"
#include "TGeometry.h"
#include "TMaterial.h"
#include "TBuffer3D.h"
#include "TBuffer3DTypes.h"
#include "TVirtualViewer3D.h"
#include "TClass.h"
#include "TMath.h"

#include <assert.h>

ClassImp(TShape)


//______________________________________________________________________________
//
//  This is the base class for all geometry shapes.
//  The list of shapes currently supported correspond to the shapes
//  in Geant version 3:
//     TBRIK,TCONE,TCONS,TGTRA,TPARA,TPCON,TPGON
//    ,TTRAP,TTRD1,TTRD2,THYPE, TTUBE and TTUBS.
//
//  The figure below shows instances of all these shapes. This figure
//  is generated by the ROOT 3-D viewer.
//Begin_Html
/*
<img src="gif/tshape_classtree.gif">
*/
//End_Html
//Begin_Html
/*
<img src="gif/shapes.gif">
*/
//End_Html
//


//______________________________________________________________________________
TShape::TShape()
{
   // Shape default constructor

   fVisibility = 1;
   fMaterial   = 0;
   fNumber     = 0;
}


//______________________________________________________________________________
TShape::TShape(const char *name,const char *title, const char *materialname)
       : TNamed (name, title), TAttLine(), TAttFill()
{
   // Shape normal constructor

   fVisibility = 1;
   if (!gGeometry) gGeometry = new TGeometry("Geometry","Default Geometry");
   fMaterial   = gGeometry->GetMaterial(materialname);
   fNumber     = gGeometry->GetListOfShapes()->GetSize();
   gGeometry->GetListOfShapes()->Add(this);
#ifdef WIN32
   // The color "1" - default produces a very bad 3D image with OpenGL
   Color_t lcolor = 16;
   SetLineColor(lcolor);
#endif
}

//______________________________________________________________________________
TShape::TShape(const TShape& ts) :
  TNamed(ts),
  TAttLine(ts),
  TAttFill(ts),
  TAtt3D(ts),
  fNumber(ts.fNumber),
  fVisibility(ts.fVisibility),
  fMaterial(ts.fMaterial)
{
   //copy constructor
}

//______________________________________________________________________________
TShape& TShape::operator=(const TShape& ts)
{
   //assignement operator
   if (this!=&ts) {
      TNamed::operator=(ts);
      TAttLine::operator=(ts);
      TAttFill::operator=(ts);
      TAtt3D::operator=(ts);
      fNumber=ts.fNumber;
      fVisibility=ts.fVisibility;
      fMaterial=ts.fMaterial;
   }
   return *this;
}

//______________________________________________________________________________
TShape::~TShape()
{
   // Shape default destructor

   if (gGeometry) gGeometry->GetListOfShapes()->Remove(this);
}


//______________________________________________________________________________
Int_t TShape::ShapeDistancetoPrimitive(Int_t numPoints, Int_t px, Int_t py)
{
   // Distance to primitive.

   Int_t dist = 9999;

   TView *view = gPad->GetView();
   if (!(numPoints && view)) return dist;

   Double_t *points =  new Double_t[3*numPoints];
   SetPoints(points);
   Double_t dpoint2, x1, y1, xndc[3];
   for (Int_t i = 0; i < numPoints; i++) {
      if (gGeometry) gGeometry->Local2Master(&points[3*i],&points[3*i]);
      view->WCtoNDC(&points[3*i], xndc);
      x1     = gPad->XtoAbsPixel(xndc[0]);
      y1     = gPad->YtoAbsPixel(xndc[1]);
      dpoint2= (px-x1)*(px-x1) + (py-y1)*(py-y1);
      if (dpoint2 < dist) dist = (Int_t)dpoint2;
   }
   delete [] points;
   return Int_t(TMath::Sqrt(Float_t(dist)));
}


//______________________________________________________________________________
void TShape::Paint(Option_t *)
{
   // This method is used only when a shape is painted outside a TNode.

   TVirtualViewer3D * viewer3D = gPad->GetViewer3D();
   if (viewer3D) {
      const TBuffer3D & buffer = GetBuffer3D(TBuffer3D::kAll);
      viewer3D->AddObject(buffer);
   }
}

//______________________________________________________________________________
void TShape::SetPoints(Double_t *) const
{
   // Set points.

   AbstractMethod("SetPoints(Double_t *buffer) const");
}


//______________________________________________________________________________
void TShape::Streamer(TBuffer &R__b)
{
   // Stream an object of class TShape.

   if (R__b.IsReading()) {
      UInt_t R__s, R__c;
      Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
      if (R__v > 1) {
         R__b.ReadClassBuffer(TShape::Class(), this, R__v, R__s, R__c);
         return;
      }
      //====process old versions before automatic schema evolution
      TNamed::Streamer(R__b);
      TAttLine::Streamer(R__b);
      TAttFill::Streamer(R__b);
      TAtt3D::Streamer(R__b);
      R__b >> fNumber;
      R__b >> fVisibility;
      R__b >> fMaterial;
      R__b.CheckByteCount(R__s, R__c, TShape::IsA());
      //====end of old versions

   } else {
      R__b.WriteClassBuffer(TShape::Class(),this);
   }
}


//______________________________________________________________________________
void TShape::TransformPoints(Double_t *points, UInt_t NbPnts) const
{
   // Tranform points (LocalToMaster)

   if (gGeometry && points) {
      Double_t dlocal[3];
      Double_t dmaster[3];
      for (UInt_t j=0; j<NbPnts; j++) {
         dlocal[0] = points[3*j];
         dlocal[1] = points[3*j+1];
         dlocal[2] = points[3*j+2];
         gGeometry->Local2Master(&dlocal[0],&dmaster[0]);
         points[3*j]   = dmaster[0];
         points[3*j+1] = dmaster[1];
         points[3*j+2] = dmaster[2];
      }
   }
}


//______________________________________________________________________________
void TShape::FillBuffer3D(TBuffer3D & buffer, Int_t reqSections) const
{
   // We have to set kRawSize (unless already done) to allocate buffer space
   // before kRaw can be filled

   if (reqSections & TBuffer3D::kRaw)
   {
      if (!(reqSections & TBuffer3D::kRawSizes) && !buffer.SectionsValid(TBuffer3D::kRawSizes))
      {
         assert(kFALSE);
      }
   }

   if (reqSections & TBuffer3D::kCore) {
      buffer.ClearSectionsValid();

      // We are only filling TBuffer3D in the master frame. Therefore the shape
      // described in buffer is a specific placement - and this needs to be
      // identified uniquely. Use the current node set in TNode::Paint which calls us
      buffer.fID = gNode;
      buffer.fColor = GetLineColor();
      buffer.fTransparency = 0;
      buffer.fLocalFrame = kFALSE; // Only support master frame for these shapes
      buffer.fReflection = kFALSE;

      buffer.SetLocalMasterIdentity();
      buffer.SetSectionsValid(TBuffer3D::kCore);
   }
}


//______________________________________________________________________________
Int_t TShape::GetBasicColor() const
{
   // Get basic solor.

   Int_t basicColor = ((GetLineColor() %8) -1) * 4;
   if (basicColor < 0) basicColor = 0;

   return basicColor;
}


//______________________________________________________________________________
const TBuffer3D &TShape::GetBuffer3D(Int_t /* reqSections */ ) const
{
   // Stub to avoid forcing implementation at this stage

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