// @(#)root/base:$Id$
// Author: Richard Maunder  10/3/2005

/*************************************************************************
 * 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 "TViewer3DPad.h"
#include "TVirtualPad.h"
#include "TView.h"
#include "TBuffer3D.h"
#include "TBuffer3DTypes.h"

#include <assert.h>

//______________________________________________________________________________
//
// Provides 3D viewer interface (TVirtualViewer3D) support on a pad.
// Will be merged with TView / TView3D eventually.


ClassImp(TViewer3DPad)

//______________________________________________________________________________
Bool_t TViewer3DPad::PreferLocalFrame() const
{
   // Indicates if we prefer positions in local frame. Always false - pad
   // drawing is always done in master frame.
   return kFALSE;
}


//______________________________________________________________________________
void TViewer3DPad::BeginScene()
{
   // Open a scene on the viewer
   assert(!fBuilding);

   // Create a 3D view if none exists
   TView *view = fPad.GetView();
   if (!view) {
      view = TView::CreateView(1,0,0); // Cartesian view by default
      if (!view) {
         assert(kFALSE);
         return;
      }
      fPad.SetView(view);

      // Set view to perform first auto-range (scaling) pass 
      view->SetAutoRange(kTRUE);
   }

   fBuilding = kTRUE;
}

//______________________________________________________________________________
void TViewer3DPad::EndScene()
{
   // Close the scene on the viewer
   assert(fBuilding);

   // If we are doing for auto-range pass on view invoke another pass
   TView *view = fPad.GetView();
   if (view) {
      if (view->GetAutoRange()) {
         view->SetAutoRange(kFALSE);
         fPad.Paint();
      }
   }   
   
   fBuilding = kFALSE;
}

//______________________________________________________________________________
Int_t TViewer3DPad::AddObject(const TBuffer3D & buffer, Bool_t * addChildren)
{
   // Add an 3D object described by the buffer to the viewer. Returns flags
   // to indicate:
   // i) if extra sections of the buffer need completing. 
   // ii) if child objects of the buffer object should be added (always true)

   // Accept any children
   if (addChildren) {
      *addChildren = kTRUE;
   }

   TView * view = fPad.GetView();
   if (!view) {
      assert(kFALSE);
      return TBuffer3D::kNone;
   }

   UInt_t reqSections = TBuffer3D::kCore|TBuffer3D::kRawSizes|TBuffer3D::kRaw;
   if (!buffer.SectionsValid(reqSections)) {
      return reqSections;
   }

   UInt_t i;
   Int_t i0, i1, i2;

   // Range pass
   if (view->GetAutoRange()) {
      Double_t x0, y0, z0, x1, y1, z1;

      x0 = x1 = buffer.fPnts[0];
      y0 = y1 = buffer.fPnts[1];
      z0 = z1 = buffer.fPnts[2];
      for (i=1; i<buffer.NbPnts(); i++) {
         i0 = 3*i; i1 = i0+1; i2 = i0+2;
         x0 = buffer.fPnts[i0] < x0 ? buffer.fPnts[i0] : x0;
         y0 = buffer.fPnts[i1] < y0 ? buffer.fPnts[i1] : y0;
         z0 = buffer.fPnts[i2] < z0 ? buffer.fPnts[i2] : z0;
         x1 = buffer.fPnts[i0] > x1 ? buffer.fPnts[i0] : x1;
         y1 = buffer.fPnts[i1] > y1 ? buffer.fPnts[i1] : y1;
         z1 = buffer.fPnts[i2] > z1 ? buffer.fPnts[i2] : z1;
      }
      view->SetRange(x0,y0,z0,x1,y1,z1,2);
   }
   // Actual drawing pass
   else {
      // Do not show semi transparent objects
      if (buffer.fTransparency > 50) {
         return TBuffer3D::kNone;
      }
      if (buffer.Type()== TBuffer3DTypes::kMarker ) {
         Double_t pndc[3], temp[3];
         for (i=0; i<buffer.NbPnts(); i++) {
            for ( i0=0; i0<3; i0++ ) temp[i0] = buffer.fPnts[3*i+i0];
            view->WCtoNDC(temp, pndc);
            fPad.PaintPolyMarker(1, &pndc[0], &pndc[1]);
         }
      } else {
         for (i=0; i<buffer.NbSegs(); i++) {
            i0 = 3*buffer.fSegs[3*i+1];
            Double_t *ptpoints_0 = &(buffer.fPnts[i0]);
            i0 = 3*buffer.fSegs[3*i+2];
            Double_t *ptpoints_3 = &(buffer.fPnts[i0]);
            fPad.PaintLine3D(ptpoints_0, ptpoints_3);
         }
      }
   }

   return TBuffer3D::kNone;
}

//______________________________________________________________________________
Int_t TViewer3DPad::AddObject(UInt_t /*placedID*/, const TBuffer3D & buffer, Bool_t * addChildren)
{
   // We don't support placed ID shapes - ID is discarded
   return AddObject(buffer,addChildren);
}


//______________________________________________________________________________
Bool_t TViewer3DPad::OpenComposite(const TBuffer3D & /*buffer*/, Bool_t * /*addChildren*/) 
{
   // Composite shapes not supported on this viewer currently - ignore.
   // Will result in a set of individual component shapes
   return kTRUE;
};

//______________________________________________________________________________
void TViewer3DPad::CloseComposite() 
{};

//______________________________________________________________________________
void TViewer3DPad::AddCompositeOp(UInt_t /*operation*/) 
{};
 TViewer3DPad.cxx:1
 TViewer3DPad.cxx:2
 TViewer3DPad.cxx:3
 TViewer3DPad.cxx:4
 TViewer3DPad.cxx:5
 TViewer3DPad.cxx:6
 TViewer3DPad.cxx:7
 TViewer3DPad.cxx:8
 TViewer3DPad.cxx:9
 TViewer3DPad.cxx:10
 TViewer3DPad.cxx:11
 TViewer3DPad.cxx:12
 TViewer3DPad.cxx:13
 TViewer3DPad.cxx:14
 TViewer3DPad.cxx:15
 TViewer3DPad.cxx:16
 TViewer3DPad.cxx:17
 TViewer3DPad.cxx:18
 TViewer3DPad.cxx:19
 TViewer3DPad.cxx:20
 TViewer3DPad.cxx:21
 TViewer3DPad.cxx:22
 TViewer3DPad.cxx:23
 TViewer3DPad.cxx:24
 TViewer3DPad.cxx:25
 TViewer3DPad.cxx:26
 TViewer3DPad.cxx:27
 TViewer3DPad.cxx:28
 TViewer3DPad.cxx:29
 TViewer3DPad.cxx:30
 TViewer3DPad.cxx:31
 TViewer3DPad.cxx:32
 TViewer3DPad.cxx:33
 TViewer3DPad.cxx:34
 TViewer3DPad.cxx:35
 TViewer3DPad.cxx:36
 TViewer3DPad.cxx:37
 TViewer3DPad.cxx:38
 TViewer3DPad.cxx:39
 TViewer3DPad.cxx:40
 TViewer3DPad.cxx:41
 TViewer3DPad.cxx:42
 TViewer3DPad.cxx:43
 TViewer3DPad.cxx:44
 TViewer3DPad.cxx:45
 TViewer3DPad.cxx:46
 TViewer3DPad.cxx:47
 TViewer3DPad.cxx:48
 TViewer3DPad.cxx:49
 TViewer3DPad.cxx:50
 TViewer3DPad.cxx:51
 TViewer3DPad.cxx:52
 TViewer3DPad.cxx:53
 TViewer3DPad.cxx:54
 TViewer3DPad.cxx:55
 TViewer3DPad.cxx:56
 TViewer3DPad.cxx:57
 TViewer3DPad.cxx:58
 TViewer3DPad.cxx:59
 TViewer3DPad.cxx:60
 TViewer3DPad.cxx:61
 TViewer3DPad.cxx:62
 TViewer3DPad.cxx:63
 TViewer3DPad.cxx:64
 TViewer3DPad.cxx:65
 TViewer3DPad.cxx:66
 TViewer3DPad.cxx:67
 TViewer3DPad.cxx:68
 TViewer3DPad.cxx:69
 TViewer3DPad.cxx:70
 TViewer3DPad.cxx:71
 TViewer3DPad.cxx:72
 TViewer3DPad.cxx:73
 TViewer3DPad.cxx:74
 TViewer3DPad.cxx:75
 TViewer3DPad.cxx:76
 TViewer3DPad.cxx:77
 TViewer3DPad.cxx:78
 TViewer3DPad.cxx:79
 TViewer3DPad.cxx:80
 TViewer3DPad.cxx:81
 TViewer3DPad.cxx:82
 TViewer3DPad.cxx:83
 TViewer3DPad.cxx:84
 TViewer3DPad.cxx:85
 TViewer3DPad.cxx:86
 TViewer3DPad.cxx:87
 TViewer3DPad.cxx:88
 TViewer3DPad.cxx:89
 TViewer3DPad.cxx:90
 TViewer3DPad.cxx:91
 TViewer3DPad.cxx:92
 TViewer3DPad.cxx:93
 TViewer3DPad.cxx:94
 TViewer3DPad.cxx:95
 TViewer3DPad.cxx:96
 TViewer3DPad.cxx:97
 TViewer3DPad.cxx:98
 TViewer3DPad.cxx:99
 TViewer3DPad.cxx:100
 TViewer3DPad.cxx:101
 TViewer3DPad.cxx:102
 TViewer3DPad.cxx:103
 TViewer3DPad.cxx:104
 TViewer3DPad.cxx:105
 TViewer3DPad.cxx:106
 TViewer3DPad.cxx:107
 TViewer3DPad.cxx:108
 TViewer3DPad.cxx:109
 TViewer3DPad.cxx:110
 TViewer3DPad.cxx:111
 TViewer3DPad.cxx:112
 TViewer3DPad.cxx:113
 TViewer3DPad.cxx:114
 TViewer3DPad.cxx:115
 TViewer3DPad.cxx:116
 TViewer3DPad.cxx:117
 TViewer3DPad.cxx:118
 TViewer3DPad.cxx:119
 TViewer3DPad.cxx:120
 TViewer3DPad.cxx:121
 TViewer3DPad.cxx:122
 TViewer3DPad.cxx:123
 TViewer3DPad.cxx:124
 TViewer3DPad.cxx:125
 TViewer3DPad.cxx:126
 TViewer3DPad.cxx:127
 TViewer3DPad.cxx:128
 TViewer3DPad.cxx:129
 TViewer3DPad.cxx:130
 TViewer3DPad.cxx:131
 TViewer3DPad.cxx:132
 TViewer3DPad.cxx:133
 TViewer3DPad.cxx:134
 TViewer3DPad.cxx:135
 TViewer3DPad.cxx:136
 TViewer3DPad.cxx:137
 TViewer3DPad.cxx:138
 TViewer3DPad.cxx:139
 TViewer3DPad.cxx:140
 TViewer3DPad.cxx:141
 TViewer3DPad.cxx:142
 TViewer3DPad.cxx:143
 TViewer3DPad.cxx:144
 TViewer3DPad.cxx:145
 TViewer3DPad.cxx:146
 TViewer3DPad.cxx:147
 TViewer3DPad.cxx:148
 TViewer3DPad.cxx:149
 TViewer3DPad.cxx:150
 TViewer3DPad.cxx:151
 TViewer3DPad.cxx:152
 TViewer3DPad.cxx:153
 TViewer3DPad.cxx:154
 TViewer3DPad.cxx:155
 TViewer3DPad.cxx:156
 TViewer3DPad.cxx:157
 TViewer3DPad.cxx:158
 TViewer3DPad.cxx:159
 TViewer3DPad.cxx:160
 TViewer3DPad.cxx:161
 TViewer3DPad.cxx:162
 TViewer3DPad.cxx:163
 TViewer3DPad.cxx:164
 TViewer3DPad.cxx:165
 TViewer3DPad.cxx:166
 TViewer3DPad.cxx:167
 TViewer3DPad.cxx:168
 TViewer3DPad.cxx:169
 TViewer3DPad.cxx:170
 TViewer3DPad.cxx:171
 TViewer3DPad.cxx:172