00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "TViewerX3D.h"
00020 #include "X3DBuffer.h"
00021 #include "TVirtualPad.h"
00022 #include "TView.h"
00023 #include "TMath.h"
00024 #include "TROOT.h"
00025
00026 #include "TRootHelpDialog.h"
00027 #include "TGClient.h"
00028 #include "TGCanvas.h"
00029 #include "TGMenu.h"
00030 #include "TGWidget.h"
00031 #include "TGMsgBox.h"
00032 #include "TVirtualX.h"
00033
00034 #include "TBuffer3D.h"
00035 #include "TBuffer3DTypes.h"
00036
00037 #include "HelpText.h"
00038
00039 #include <assert.h>
00040
00041 const char gHelpX3DViewer[] = "\
00042 PRESS \n\
00043 \tw\t--- wireframe mode\n\
00044 \te\t--- hidden line mode\n\
00045 \tr\t--- hidden surface mode\n\
00046 \tu\t--- move object down\n\
00047 \ti\t--- move object up\n\
00048 \to\t--- toggle controls style\n\
00049 \ts\t--- toggle stereo display\n\
00050 \td\t--- toggle blue stereo view\n\
00051 \tf\t--- toggle double buffer\n\
00052 \th\t--- move object right\n\
00053 \tj\t--- move object forward\n\
00054 \tk\t--- move object backward\n\
00055 \tl\t--- move object left\n\
00056 \tx a\t--- rotate about x\n\
00057 \ty b\t--- rotate about y\n\
00058 \tz c\t--- rotate about z\n\
00059 \t1 2 3\t--- autorotate about x\n\
00060 \t4 5 6\t--- autorotate about y\n\
00061 \t7 8 9\t--- autorotate about z\n\
00062 \t[ ] { }\t--- adjust focus\n\n\
00063 HOLD the left mouse button and MOVE mouse to ROTATE object\n\n\
00064 ";
00065
00066
00067 extern "C" {
00068 Window_t x3d_main(Float_t *longitude, Float_t *latitude, Float_t *psi,
00069 Option_t *option, Window_t parent);
00070 void x3d_set_display(Display_t display);
00071 int x3d_dispatch_event(Handle_t event);
00072 void x3d_update();
00073 void x3d_get_position(Float_t *longitude, Float_t *latitude, Float_t *psi);
00074 int x3d_exec_command(int px, int py, char command);
00075 void x3d_terminate();
00076 }
00077
00078
00079
00080 enum EX3DViewerCommands {
00081 kFileNewViewer,
00082 kFileSave,
00083 kFileSaveAs,
00084 kFilePrint,
00085 kFileCloseViewer,
00086
00087 kHelpAbout,
00088 kHelpOnViewer
00089 };
00090
00091 Bool_t TViewerX3D::fgCreated = kFALSE;
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 class TX3DContainer : public TGCompositeFrame {
00106 private:
00107 TViewerX3D *fViewer;
00108 public:
00109 TX3DContainer(TViewerX3D *c, Window_t id, const TGWindow *parent);
00110
00111 Bool_t HandleButton(Event_t *ev)
00112 { x3d_dispatch_event(gVirtualX->GetNativeEvent());
00113 return fViewer->HandleContainerButton(ev); }
00114 Bool_t HandleConfigureNotify(Event_t *ev)
00115 { TGFrame::HandleConfigureNotify(ev);
00116 return x3d_dispatch_event(gVirtualX->GetNativeEvent()); }
00117 Bool_t HandleKey(Event_t *)
00118 { return x3d_dispatch_event(gVirtualX->GetNativeEvent()); }
00119 Bool_t HandleMotion(Event_t *)
00120 { return x3d_dispatch_event(gVirtualX->GetNativeEvent()); }
00121 Bool_t HandleExpose(Event_t *)
00122 { return x3d_dispatch_event(gVirtualX->GetNativeEvent()); }
00123 Bool_t HandleColormapChange(Event_t *)
00124 { return x3d_dispatch_event(gVirtualX->GetNativeEvent()); }
00125 };
00126
00127
00128
00129 TX3DContainer::TX3DContainer(TViewerX3D *c, Window_t id, const TGWindow *p)
00130 : TGCompositeFrame(gClient, id, p)
00131 {
00132
00133
00134 fViewer = c;
00135 }
00136
00137
00138 ClassImp(TViewerX3D)
00139
00140
00141
00142 TViewerX3D::TViewerX3D(TVirtualPad *pad)
00143 : TVirtualViewer3D(),
00144 fCanvas(0), fContainer(0), fMenuBar(0), fFileMenu(0),
00145 fHelpMenu(0), fMenuBarLayout(0), fMenuBarItemLayout(0),
00146 fMenuBarHelpLayout(0), fCanvasLayout(0),
00147 fPad(pad), fBuildingScene(kFALSE), fPass(kSize)
00148 {
00149
00150 fMainFrame = new TX3DFrame(*this, gClient->GetRoot(), 800, 600);
00151 fOption = "x3d";
00152 fX3DWin = 0;
00153 fWidth = 800;
00154 fHeight = 600;
00155 fXPos = 0;
00156 fYPos = 0;
00157 fTitle = "x3d";
00158 }
00159
00160
00161
00162 TViewerX3D::TViewerX3D(TVirtualPad *pad, Option_t *option, const char *title,
00163 UInt_t width, UInt_t height)
00164 : TVirtualViewer3D(),
00165 fCanvas(0), fContainer(0), fMenuBar(0), fFileMenu(0),
00166 fHelpMenu(0), fMenuBarLayout(0), fMenuBarItemLayout(0),
00167 fMenuBarHelpLayout(0), fCanvasLayout(0),
00168 fPad(pad), fBuildingScene(kFALSE), fPass(kSize)
00169 {
00170
00171 fMainFrame = new TX3DFrame(*this, gClient->GetRoot(), 800, 600);
00172 fOption = option;
00173 fX3DWin = 0;
00174 fWidth = width;
00175 fHeight = height;
00176 fXPos = 0;
00177 fYPos = 0;
00178 fTitle = title;
00179 }
00180
00181
00182
00183 TViewerX3D::TViewerX3D(TVirtualPad *pad, Option_t *option, const char *title,
00184 Int_t x, Int_t y, UInt_t width, UInt_t height)
00185 : TVirtualViewer3D(),
00186 fCanvas(0), fContainer(0), fMenuBar(0), fFileMenu(0),
00187 fHelpMenu(0), fMenuBarLayout(0), fMenuBarItemLayout(0),
00188 fMenuBarHelpLayout(0), fCanvasLayout(0),
00189 fPad(pad), fBuildingScene(kFALSE), fPass(kSize)
00190 {
00191
00192 fMainFrame = new TX3DFrame(*this, gClient->GetRoot(), 800, 600);
00193 fOption = option;
00194 fX3DWin = 0;
00195 fWidth = width;
00196 fHeight = height;
00197 fXPos = x;
00198 fYPos = y;
00199 fTitle = title;
00200 }
00201
00202
00203
00204 TViewerX3D::~TViewerX3D()
00205 {
00206
00207
00208 if (!fPad) return;
00209
00210 if (fgCreated) {
00211 DeleteX3DWindow();
00212 }
00213 delete fCanvasLayout;
00214 delete fMenuBarHelpLayout;
00215 delete fMenuBarItemLayout;
00216 delete fMenuBarLayout;
00217 delete fHelpMenu;
00218 delete fFileMenu;
00219 delete fMenuBar;
00220 delete fContainer;
00221 delete fCanvas;
00222 delete fMainFrame;
00223 fgCreated = kFALSE;
00224 }
00225
00226
00227
00228 void TViewerX3D::Close()
00229 {
00230
00231 assert(!fBuildingScene);
00232 fPad->ReleaseViewer3D();
00233 delete this;
00234 }
00235
00236
00237
00238 void TViewerX3D::CreateViewer(const char *name)
00239 {
00240
00241
00242
00243 fFileMenu = new TGPopupMenu(fMainFrame->GetClient()->GetRoot());
00244 fFileMenu->AddEntry("&New Viewer", kFileNewViewer);
00245 fFileMenu->AddSeparator();
00246 fFileMenu->AddEntry("Save", kFileSave);
00247 fFileMenu->AddEntry("Save As...", kFileSaveAs);
00248 fFileMenu->AddSeparator();
00249 fFileMenu->AddEntry("&Print...", kFilePrint);
00250 fFileMenu->AddSeparator();
00251 fFileMenu->AddEntry("&Close Viewer", kFileCloseViewer);
00252
00253
00254 fFileMenu->DisableEntry(kFileNewViewer);
00255 fFileMenu->DisableEntry(kFileSave);
00256 fFileMenu->DisableEntry(kFileSaveAs);
00257 fFileMenu->DisableEntry(kFilePrint);
00258
00259 fHelpMenu = new TGPopupMenu(fMainFrame->GetClient()->GetRoot());
00260 fHelpMenu->AddEntry("&About ROOT...", kHelpAbout);
00261 fHelpMenu->AddSeparator();
00262 fHelpMenu->AddEntry("Help On X3D Viewer...", kHelpOnViewer);
00263
00264
00265 fFileMenu->Associate(fMainFrame);
00266 fHelpMenu->Associate(fMainFrame);
00267
00268
00269 fMenuBarLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 0, 0, 1, 1);
00270 fMenuBarItemLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0);
00271 fMenuBarHelpLayout = new TGLayoutHints(kLHintsTop | kLHintsRight);
00272
00273
00274 fMenuBar = new TGMenuBar(fMainFrame, 1, 1, kHorizontalFrame);
00275 fMenuBar->AddPopup("&File", fFileMenu, fMenuBarItemLayout);
00276 fMenuBar->AddPopup("&Help", fHelpMenu, fMenuBarHelpLayout);
00277
00278 fMainFrame->AddFrame(fMenuBar, fMenuBarLayout);
00279
00280
00281 fCanvas = new TGCanvas(fMainFrame, fMainFrame->GetWidth()+4, fMainFrame->GetHeight()+4,
00282 kSunkenFrame | kDoubleBorder);
00283 InitX3DWindow();
00284 if (!fX3DWin) {
00285 fContainer = 0;
00286 fCanvasLayout = 0;
00287 return;
00288 }
00289 fContainer = new TX3DContainer(this, fX3DWin, fCanvas->GetViewPort());
00290 fCanvas->SetContainer(fContainer);
00291 fCanvasLayout = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY);
00292 fMainFrame->AddFrame(fCanvas, fCanvasLayout);
00293
00294
00295
00296 fMainFrame->SetWindowName(name);
00297 fMainFrame->SetIconName(name);
00298 fMainFrame->SetClassHints("X3DViewer", "X3DViewer");
00299
00300 fMainFrame->SetMWMHints(kMWMDecorAll, kMWMFuncAll, kMWMInputModeless);
00301
00302 fMainFrame->MapSubwindows();
00303
00304
00305 fMainFrame->Resize(fMainFrame->GetDefaultSize());
00306
00307 fMainFrame->MoveResize(fXPos, fYPos, fWidth, fHeight);
00308 fMainFrame->SetWMPosition(fXPos, fYPos);
00309 fgCreated = kTRUE;
00310 }
00311
00312
00313
00314 void TViewerX3D::InitX3DWindow()
00315 {
00316
00317
00318 TView *view = fPad->GetView();
00319 if (!view) {
00320 Error("InitX3DWindow", "view is not set");
00321 return;
00322 }
00323
00324 const Float_t kPI = Float_t (TMath::Pi());
00325
00326 Float_t longitude_rad = ( 90 + view->GetLongitude()) * kPI/180.0;
00327 Float_t latitude_rad = (-90 + view->GetLatitude() ) * kPI/180.0;
00328 Float_t psi_rad = ( view->GetPsi() ) * kPI/180.0;
00329
00330
00331 x3d_set_display(gVirtualX->GetDisplay());
00332 fX3DWin = (Window_t) x3d_main(&longitude_rad, &latitude_rad, &psi_rad,
00333 fOption.Data(), fCanvas->GetViewPort()->GetId());
00334 }
00335
00336
00337
00338 void TViewerX3D::BeginScene()
00339 {
00340
00341 if (fgCreated) {
00342 return;
00343 }
00344
00345 fBuildingScene = kTRUE;
00346
00347 if (fPass == kSize) {
00348 gSize3D.numPoints = 0;
00349 gSize3D.numSegs = 0;
00350 gSize3D.numPolys = 0;
00351 }
00352 }
00353
00354
00355
00356 void TViewerX3D::EndScene()
00357 {
00358
00359 if (fgCreated) {
00360 return;
00361 }
00362
00363 fBuildingScene = kFALSE;
00364
00365
00366 if (gSize3D.numPoints != 0) {
00367 if (fPass == kSize) {
00368
00369 if (!AllocateX3DBuffer()) {
00370 Error("InitX3DWindow", "x3d buffer allocation failure");
00371 return;
00372 }
00373
00374
00375 fPass = kDraw;
00376 fPad->Paint();
00377 fPass = kSize;
00378 CreateViewer(fTitle);
00379 Show();
00380 }
00381 } else {
00382 Int_t retval;
00383 new TGMsgBox(gClient->GetRoot(), gClient->GetRoot(),
00384 "X3D Viewer", "Cannot display this content in the X3D viewer",
00385 kMBIconExclamation, kMBOk, &retval);
00386 Close();
00387 }
00388 }
00389
00390
00391
00392 Int_t TViewerX3D::AddObject(const TBuffer3D & buffer, Bool_t * addChildren)
00393 {
00394
00395 if (fgCreated) {
00396 if (addChildren) {
00397 *addChildren = kFALSE;
00398 }
00399 return TBuffer3D::kNone;
00400 }
00401 else if (addChildren) {
00402 *addChildren = kTRUE;
00403 }
00404
00405 UInt_t reqSections = TBuffer3D::kCore|TBuffer3D::kRawSizes;
00406
00407
00408 if (fPass == kDraw) {
00409 reqSections |= TBuffer3D::kRaw;
00410 }
00411
00412 if (!buffer.SectionsValid(reqSections)) {
00413 return reqSections;
00414 }
00415
00416 if (buffer.Type() == TBuffer3DTypes::kMarker) {
00417 PaintPolyMarker(buffer);
00418 return TBuffer3D::kNone;
00419 }
00420
00421 switch(fPass) {
00422 case(kSize): {
00423 gSize3D.numPoints += buffer.NbPnts();
00424 gSize3D.numSegs += buffer.NbSegs();
00425 gSize3D.numPolys += buffer.NbPols();
00426 break;
00427 }
00428 case (kDraw): {
00429 X3DBuffer *x3dBuff = new X3DBuffer;
00430 x3dBuff->numPoints = buffer.NbPnts();
00431 x3dBuff->numSegs = buffer.NbSegs();
00432 x3dBuff->numPolys = buffer.NbPols();
00433 x3dBuff->points = new Float_t[3*buffer.NbPnts()];
00434 for (UInt_t i=0; i<3*buffer.NbPnts();i++)
00435 x3dBuff->points[i] = (Float_t)buffer.fPnts[i];
00436 x3dBuff->segs = buffer.fSegs;
00437 x3dBuff->polys = buffer.fPols;
00438 FillX3DBuffer(x3dBuff);
00439 delete [] x3dBuff->points;
00440 delete x3dBuff;
00441 break;
00442 }
00443 default: {
00444 assert(kFALSE);
00445 break;
00446 }
00447 }
00448
00449 return TBuffer3D::kNone;
00450 }
00451
00452
00453
00454 Int_t TViewerX3D::AddObject(UInt_t , const TBuffer3D & buffer, Bool_t * addChildren)
00455 {
00456
00457 return AddObject(buffer,addChildren);
00458 }
00459
00460
00461
00462 void TViewerX3D::PaintPolyMarker(const TBuffer3D & buffer) const
00463 {
00464
00465 if (fgCreated) {
00466 return;
00467 }
00468 UInt_t mode;
00469
00470 if (buffer.NbPnts() > 10000) mode = 1;
00471 else if (buffer.NbPnts() > 3000) mode = 2;
00472 else mode = 3;
00473
00474 switch(fPass) {
00475 case(kSize): {
00476 gSize3D.numPoints += 2*mode*buffer.NbPnts();
00477 gSize3D.numSegs += mode*buffer.NbPnts();
00478 break;
00479 }
00480 case (kDraw): {
00481 X3DBuffer *x3dBuff = new X3DBuffer;
00482 x3dBuff->numPoints = 2*mode*buffer.NbPnts();
00483 x3dBuff->numSegs = mode*buffer.NbPnts();
00484 x3dBuff->numPolys = 0;
00485 x3dBuff->points = new Float_t[3*x3dBuff->numPoints];
00486 x3dBuff->segs = new Int_t[3*x3dBuff->numSegs];
00487 x3dBuff->polys = 0;
00488
00489 Double_t delta = 0.002;
00490
00491 for (UInt_t i = 0; i < buffer.NbPnts(); i++) {
00492 for (UInt_t j = 0; j < mode; j++) {
00493 for (UInt_t k = 0; k < 2; k++) {
00494 delta *= -1;
00495 for (UInt_t n = 0; n < 3; n++) {
00496 x3dBuff->points[mode*6*i+6*j+3*k+n] =
00497 buffer.fPnts[3*i+n] * (1 + (j == n ? delta : 0));
00498 }
00499 }
00500 }
00501 }
00502
00503 for (Int_t i=0; i<x3dBuff->numSegs; i++) {
00504 x3dBuff->segs[3*i ] = buffer.fSegs[0];
00505 x3dBuff->segs[3*i+1] = 2*i;
00506 x3dBuff->segs[3*i+2] = 2*i+1;
00507 }
00508
00509 FillX3DBuffer(x3dBuff);
00510 delete [] x3dBuff->points;
00511 delete [] x3dBuff->segs;
00512 delete x3dBuff;
00513 break;
00514 }
00515 }
00516 }
00517
00518
00519
00520 Int_t TViewerX3D::ExecCommand(Int_t px, Int_t py, char command)
00521 {
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565 return x3d_exec_command(px,py,command);
00566 }
00567
00568
00569
00570 void TViewerX3D::GetPosition(Float_t &longitude, Float_t &latitude, Float_t &psi)
00571 {
00572
00573 x3d_get_position(&longitude, &latitude, &psi);
00574 }
00575
00576
00577 void TViewerX3D::DeleteX3DWindow()
00578 {
00579
00580
00581 x3d_terminate();
00582 }
00583
00584
00585
00586 void TViewerX3D::Update()
00587 {
00588
00589
00590 x3d_update();
00591 }
00592
00593
00594
00595 Bool_t TViewerX3D::ProcessFrameMessage(Long_t msg, Long_t parm1, Long_t)
00596 {
00597
00598
00599 TRootHelpDialog *hd;
00600
00601 switch (GET_MSG(msg)) {
00602
00603 case kC_COMMAND:
00604
00605 switch (GET_SUBMSG(msg)) {
00606
00607 case kCM_BUTTON:
00608 case kCM_MENU:
00609
00610 switch (parm1) {
00611
00612 case kFileNewViewer:
00613 if (fPad) fPad->GetViewer3D("x3d");
00614 break;
00615 case kFileSave:
00616 case kFileSaveAs:
00617 case kFilePrint:
00618 break;
00619 case kFileCloseViewer:
00620 fMainFrame->SendCloseMessage();
00621 break;
00622
00623
00624 case kHelpAbout:
00625 {
00626 char str[32];
00627 snprintf(str,32, "About ROOT %s...", gROOT->GetVersion());
00628 hd = new TRootHelpDialog(fMainFrame, str, 600, 400);
00629 hd->SetText(gHelpAbout);
00630 hd->Popup();
00631 }
00632 break;
00633 case kHelpOnViewer:
00634 hd = new TRootHelpDialog(fMainFrame, "Help on X3D Viewer...", 600, 400);
00635 hd->SetText(gHelpX3DViewer);
00636 hd->Popup();
00637 break;
00638 }
00639 default:
00640 break;
00641 }
00642 default:
00643 break;
00644 }
00645 return kTRUE;
00646 }
00647
00648
00649
00650 Bool_t TViewerX3D::HandleContainerButton(Event_t * )
00651 {
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678 return kTRUE;
00679 }