00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "Riostream.h"
00013 #include "TROOT.h"
00014 #include "TPolyLine3D.h"
00015 #include "TVirtualPad.h"
00016 #include "TView.h"
00017 #include "TVirtualViewer3D.h"
00018 #include "TBuffer3D.h"
00019 #include "TBuffer3DTypes.h"
00020 #include "TGeometry.h"
00021 #include "TMath.h"
00022
00023 #include <assert.h>
00024
00025 ClassImp(TPolyLine3D);
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 TPolyLine3D::TPolyLine3D()
00078 {
00079
00080
00081 fN = 0;
00082 fP = 0;
00083 fLastPoint = -1;
00084 }
00085
00086
00087
00088 TPolyLine3D::TPolyLine3D(Int_t n, Option_t *option)
00089 {
00090
00091
00092
00093 fOption = option;
00094 SetBit(kCanDelete);
00095 fLastPoint = -1;
00096 if (n <= 0) {
00097 fN = 0;
00098 fP = 0;
00099 return;
00100 }
00101
00102 fN = n;
00103 fP = new Float_t[3*fN];
00104 for (Int_t i=0; i<3*fN; i++) fP[i] = 0;
00105 }
00106
00107
00108
00109 TPolyLine3D::TPolyLine3D(Int_t n, Float_t *p, Option_t *option)
00110 {
00111
00112
00113
00114 fOption = option;
00115 SetBit(kCanDelete);
00116 fLastPoint = -1;
00117 if (n <= 0) {
00118 fN = 0;
00119 fP = 0;
00120 return;
00121 }
00122
00123 fN = n;
00124 fP = new Float_t[3*fN];
00125 for (Int_t i=0; i<3*n; i++) {
00126 fP[i] = p[i];
00127 }
00128 fLastPoint = fN-1;
00129 }
00130
00131
00132
00133 TPolyLine3D::TPolyLine3D(Int_t n, Double_t *p, Option_t *option)
00134 {
00135
00136
00137
00138 fOption = option;
00139 SetBit(kCanDelete);
00140 fLastPoint = -1;
00141 if (n <= 0) {
00142 fN = 0;
00143 fP = 0;
00144 return;
00145 }
00146
00147 fN = n;
00148 fP = new Float_t[3*fN];
00149 for (Int_t i=0; i<3*n; i++) {
00150 fP[i] = (Float_t) p[i];
00151 }
00152 fLastPoint = fN-1;
00153 }
00154
00155
00156
00157 TPolyLine3D::TPolyLine3D(Int_t n, Float_t *x, Float_t *y, Float_t *z, Option_t *option)
00158 {
00159
00160
00161
00162 fOption = option;
00163 SetBit(kCanDelete);
00164 fLastPoint = -1;
00165 if (n <= 0) {
00166 fN = 0;
00167 fP = 0;
00168 return;
00169 }
00170
00171 fN = n;
00172 fP = new Float_t[3*fN];
00173 Int_t j = 0;
00174 for (Int_t i=0; i<n;i++) {
00175 fP[j] = x[i];
00176 fP[j+1] = y[i];
00177 fP[j+2] = z[i];
00178 j += 3;
00179 }
00180 fLastPoint = fN-1;
00181 }
00182
00183
00184
00185 TPolyLine3D::TPolyLine3D(Int_t n, Double_t *x, Double_t *y, Double_t *z, Option_t *option)
00186 {
00187
00188
00189
00190
00191 fOption = option;
00192 SetBit(kCanDelete);
00193 fLastPoint = -1;
00194 if (n <= 0) {
00195 fN = 0;
00196 fP = 0;
00197 return;
00198 }
00199
00200 fN = n;
00201 fP = new Float_t[3*fN];
00202 Int_t j = 0;
00203 for (Int_t i=0; i<n;i++) {
00204 fP[j] = (Float_t) x[i];
00205 fP[j+1] = (Float_t) y[i];
00206 fP[j+2] = (Float_t) z[i];
00207 j += 3;
00208 }
00209 fLastPoint = fN-1;
00210 }
00211
00212
00213 TPolyLine3D& TPolyLine3D::operator=(const TPolyLine3D& pl)
00214 {
00215
00216 if(this!=&pl) {
00217 TObject::operator=(pl);
00218 TAttLine::operator=(pl);
00219 TAtt3D::operator=(pl);
00220 fN=pl.fN;
00221 fP=pl.fP;
00222 fOption=pl.fOption;
00223 fLastPoint=pl.fLastPoint;
00224 }
00225 return *this;
00226 }
00227
00228
00229 TPolyLine3D::~TPolyLine3D()
00230 {
00231
00232
00233 if (fP) delete [] fP;
00234 }
00235
00236
00237
00238 TPolyLine3D::TPolyLine3D(const TPolyLine3D &polyline) : TObject(polyline), TAttLine(polyline), TAtt3D(polyline)
00239 {
00240
00241
00242 fP = 0;
00243 fLastPoint = 0;
00244 fN = 0;
00245 ((TPolyLine3D&)polyline).TPolyLine3D::Copy(*this);
00246 }
00247
00248
00249
00250 void TPolyLine3D::Copy(TObject &obj) const
00251 {
00252
00253
00254 TObject::Copy(obj);
00255 TAttLine::Copy(((TPolyLine3D&)obj));
00256 ((TPolyLine3D&)obj).fN = fN;
00257 if (((TPolyLine3D&)obj).fP)
00258 delete [] ((TPolyLine3D&)obj).fP;
00259 if (fN > 0) {
00260 ((TPolyLine3D&)obj).fP = new Float_t[3*fN];
00261 for (Int_t i=0; i<3*fN;i++) {((TPolyLine3D&)obj).fP[i] = fP[i];}
00262 } else {
00263 ((TPolyLine3D&)obj).fP = 0;
00264 }
00265 ((TPolyLine3D&)obj).fOption = fOption;
00266 ((TPolyLine3D&)obj).fLastPoint = fLastPoint;
00267 }
00268
00269
00270
00271 Int_t TPolyLine3D::DistancetoPrimitive(Int_t px, Int_t py)
00272 {
00273
00274
00275
00276
00277
00278
00279 const Int_t inaxis = 7;
00280 Int_t dist = 9999;
00281
00282 Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
00283 Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
00284 Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
00285 Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
00286
00287
00288 if (px < puxmin - inaxis) return dist;
00289 if (py > puymin + inaxis) return dist;
00290 if (px > puxmax + inaxis) return dist;
00291 if (py < puymax - inaxis) return dist;
00292
00293 TView *view = gPad->GetView();
00294 if (!view) return dist;
00295
00296 Int_t i, dsegment;
00297 Double_t x1,y1,x2,y2;
00298 Float_t xndc[3];
00299 for (i=0;i<Size()-1;i++) {
00300 view->WCtoNDC(&fP[3*i], xndc);
00301 x1 = xndc[0];
00302 y1 = xndc[1];
00303 view->WCtoNDC(&fP[3*i+3], xndc);
00304 x2 = xndc[0];
00305 y2 = xndc[1];
00306 dsegment = DistancetoLine(px,py,x1,y1,x2,y2);
00307 if (dsegment < dist) dist = dsegment;
00308 }
00309 return dist;
00310 }
00311
00312
00313
00314 void TPolyLine3D::Draw(Option_t *option)
00315 {
00316
00317
00318 AppendPad(option);
00319 }
00320
00321
00322
00323 void TPolyLine3D::DrawOutlineCube(TList *outline, Double_t *rmin, Double_t *rmax)
00324 {
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 Double_t xmin = rmin[0]; Double_t xmax = rmax[0];
00346 Double_t ymin = rmin[1]; Double_t ymax = rmax[1];
00347 Double_t zmin = rmin[2]; Double_t zmax = rmax[2];
00348
00349 TPolyLine3D *pl3d = (TPolyLine3D *)outline->First();
00350 if (!pl3d) {
00351 TView *view = gPad->GetView();
00352 TPolyLine3D *p1 = new TPolyLine3D(4);
00353 TPolyLine3D *p2 = new TPolyLine3D(4);
00354 TPolyLine3D *p3 = new TPolyLine3D(4);
00355 TPolyLine3D *p4 = new TPolyLine3D(4);
00356 p1->SetLineColor(view->GetLineColor());
00357 p1->SetLineStyle(view->GetLineStyle());
00358 p1->SetLineWidth(view->GetLineWidth());
00359 p1->Copy(*p2);
00360 p1->Copy(*p3);
00361 p1->Copy(*p4);
00362 outline->Add(p1);
00363 outline->Add(p2);
00364 outline->Add(p3);
00365 outline->Add(p4);
00366 }
00367
00368 pl3d = (TPolyLine3D *)outline->First();
00369
00370 if (pl3d) {
00371 pl3d->SetPoint(0, xmin, ymin, zmin);
00372 pl3d->SetPoint(1, xmax, ymin, zmin);
00373 pl3d->SetPoint(2, xmax, ymax, zmin);
00374 pl3d->SetPoint(3, xmin, ymax, zmin);
00375 }
00376
00377 pl3d = (TPolyLine3D *)outline->After(pl3d);
00378
00379 if (pl3d) {
00380 pl3d->SetPoint(0, xmax, ymin, zmin);
00381 pl3d->SetPoint(1, xmax, ymin, zmax);
00382 pl3d->SetPoint(2, xmax, ymax, zmax);
00383 pl3d->SetPoint(3, xmax, ymax, zmin);
00384 }
00385
00386 pl3d = (TPolyLine3D *)outline->After(pl3d);
00387
00388 if (pl3d) {
00389 pl3d->SetPoint(0, xmax, ymin, zmax);
00390 pl3d->SetPoint(1, xmin, ymin, zmax);
00391 pl3d->SetPoint(2, xmin, ymax, zmax);
00392 pl3d->SetPoint(3, xmax, ymax, zmax);
00393 }
00394
00395 pl3d = (TPolyLine3D *)outline->After(pl3d);
00396
00397 if (pl3d) {
00398 pl3d->SetPoint(0, xmin, ymin, zmax);
00399 pl3d->SetPoint(1, xmin, ymin, zmin);
00400 pl3d->SetPoint(2, xmin, ymax, zmin);
00401 pl3d->SetPoint(3, xmin, ymax, zmax);
00402 }
00403 }
00404
00405
00406
00407 void TPolyLine3D::DrawPolyLine(Int_t n, Float_t *p, Option_t *option)
00408 {
00409
00410
00411
00412
00413 TPolyLine3D *newpolyline = new TPolyLine3D();
00414 Int_t size = 3*Size();
00415 newpolyline->fN =n;
00416 newpolyline->fP = new Float_t[size];
00417 for (Int_t i=0; i<size;i++) { newpolyline->fP[i] = p[i];}
00418 TAttLine::Copy(*newpolyline);
00419 newpolyline->fOption = fOption;
00420 newpolyline->fLastPoint = fLastPoint;
00421 newpolyline->SetBit(kCanDelete);
00422 newpolyline->AppendPad(option);
00423 }
00424
00425
00426
00427 void TPolyLine3D::ExecuteEvent(Int_t event, Int_t px, Int_t py)
00428 {
00429
00430
00431 if (gPad->GetView())
00432 gPad->GetView()->ExecuteRotateView(event, px, py);
00433 }
00434
00435
00436
00437 void TPolyLine3D::ls(Option_t *option) const
00438 {
00439
00440
00441 TROOT::IndentLevel();
00442 cout <<"PolyLine3D N=" <<fN<<" Option="<<option<<endl;
00443 }
00444
00445
00446
00447 Int_t TPolyLine3D::Merge(TCollection *li)
00448 {
00449
00450
00451 if (!li) return 0;
00452 TIter next(li);
00453
00454
00455 TPolyLine3D *pl;
00456 Int_t npoints = 0;
00457 while ((pl = (TPolyLine3D*)next())) {
00458 if (!pl->InheritsFrom(TPolyLine3D::Class())) {
00459 Error("Add","Attempt to add object of class: %s to a %s",pl->ClassName(),this->ClassName());
00460 return -1;
00461 }
00462 npoints += pl->Size();
00463 }
00464
00465
00466 SetPoint(npoints-1,0,0,0);
00467
00468
00469 next.Reset();
00470 while ((pl = (TPolyLine3D*)next())) {
00471 Int_t np = pl->Size();
00472 Float_t *p = pl->GetP();
00473 for (Int_t i=0;i<np;i++) {
00474 SetPoint(i,p[3*i],p[3*i+1],p[3*i+2]);
00475 }
00476 }
00477
00478 return npoints;
00479 }
00480
00481
00482
00483 void TPolyLine3D::Paint(Option_t * )
00484 {
00485
00486
00487 UInt_t i;
00488
00489
00490 if (Size() <= 0) return;
00491
00492 static TBuffer3D buffer(TBuffer3DTypes::kLine);
00493
00494
00495
00496
00497 buffer.ClearSectionsValid();
00498
00499
00500 buffer.fID = this;
00501 buffer.fColor = GetLineColor();
00502 buffer.fTransparency = 0;
00503 buffer.fLocalFrame = kFALSE;
00504 buffer.SetSectionsValid(TBuffer3D::kCore);
00505
00506
00507 Int_t reqSections = gPad->GetViewer3D()->AddObject(buffer);
00508 if (reqSections == TBuffer3D::kNone) {
00509 return;
00510 }
00511
00512 if (reqSections & TBuffer3D::kRawSizes) {
00513 Int_t nbPnts = Size();
00514 Int_t nbSegs = nbPnts-1;
00515 if (!buffer.SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, 0, 0)) {
00516 return;
00517 }
00518 buffer.SetSectionsValid(TBuffer3D::kRawSizes);
00519 }
00520
00521 if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) {
00522
00523 for (i=0; i<3*buffer.NbPnts(); i++) {
00524 buffer.fPnts[i] = (Double_t)fP[i];
00525 }
00526
00527
00528 if (gGeometry && !buffer.fLocalFrame) {
00529 Double_t dlocal[3];
00530 Double_t dmaster[3];
00531 for (UInt_t j=0; j<buffer.NbPnts(); j++) {
00532 dlocal[0] = buffer.fPnts[3*j];
00533 dlocal[1] = buffer.fPnts[3*j+1];
00534 dlocal[2] = buffer.fPnts[3*j+2];
00535 gGeometry->Local2Master(&dlocal[0],&dmaster[0]);
00536 buffer.fPnts[3*j] = dmaster[0];
00537 buffer.fPnts[3*j+1] = dmaster[1];
00538 buffer.fPnts[3*j+2] = dmaster[2];
00539 }
00540 }
00541
00542
00543 Int_t c = (((GetLineColor()) %8) -1) * 4;
00544 if (c < 0) c = 0;
00545
00546
00547 for (i = 0; i < buffer.NbSegs(); i++) {
00548 buffer.fSegs[3*i ] = c;
00549 buffer.fSegs[3*i+1] = i;
00550 buffer.fSegs[3*i+2] = i+1;
00551 }
00552
00553 TAttLine::Modify();
00554
00555 buffer.SetSectionsValid(TBuffer3D::kRaw);
00556 }
00557
00558 gPad->GetViewer3D()->AddObject(buffer);
00559 }
00560
00561
00562
00563 void TPolyLine3D::Print(Option_t *option) const
00564 {
00565
00566
00567 printf(" TPolyLine3D N=%d, Option=%s\n",fN,option);
00568 TString opt = option;
00569 opt.ToLower();
00570 if (opt.Contains("all")) {
00571 for (Int_t i=0;i<Size();i++) {
00572 printf(" x[%d]=%g, y[%d]=%g, z[%d]=%g\n",i,fP[3*i],i,fP[3*i+1],i,fP[3*i+2]);
00573 }
00574 }
00575 }
00576
00577
00578
00579 void TPolyLine3D::SavePrimitive(ostream &out, Option_t * )
00580 {
00581
00582
00583 char quote = '"';
00584 out<<" "<<endl;
00585 if (gROOT->ClassSaved(TPolyLine3D::Class())) {
00586 out<<" ";
00587 } else {
00588 out<<" TPolyLine3D *";
00589 }
00590 Int_t size=Size();
00591 out<<"pline3D = new TPolyLine3D("<<fN<<","<<quote<<fOption<<quote<<");"<<endl;
00592
00593 SaveLineAttributes(out,"pline3D",1,1,1);
00594
00595 if (size > 0) {
00596 for (Int_t i=0;i<size;i++)
00597 out<<" pline3D->SetPoint("<<i<<","<<fP[3*i]<<","<<fP[3*i+1]<<","<<fP[3*i+2]<<");"<<endl;
00598 }
00599 out<<" pline3D->Draw();"<<endl;
00600 }
00601
00602
00603
00604 Int_t TPolyLine3D::SetNextPoint(Double_t x, Double_t y, Double_t z)
00605 {
00606
00607
00608
00609 fLastPoint++;
00610 SetPoint(fLastPoint, x, y, z);
00611 return fLastPoint;
00612 }
00613
00614
00615
00616 void TPolyLine3D::SetPoint(Int_t n, Double_t x, Double_t y, Double_t z)
00617 {
00618
00619
00620
00621
00622 if (n < 0) return;
00623 if (!fP || n >= fN) {
00624
00625 Int_t newN = TMath::Max(2*fN,n+1);
00626 Float_t *savepoint = new Float_t [3*newN];
00627 if (fP && fN){
00628 memcpy(savepoint,fP,3*fN*sizeof(Float_t));
00629 memset(&savepoint[3*fN],0,(newN-fN)*sizeof(Float_t));
00630 delete [] fP;
00631 }
00632 fP = savepoint;
00633 fN = newN;
00634 }
00635 fP[3*n ] = x;
00636 fP[3*n+1] = y;
00637 fP[3*n+2] = z;
00638 fLastPoint = TMath::Max(fLastPoint,n);
00639 }
00640
00641
00642
00643 void TPolyLine3D::SetPolyLine(Int_t n, Option_t *option)
00644 {
00645
00646
00647
00648 fOption = option;
00649 if (n <= 0) {
00650 fN = 0;
00651 fLastPoint = -1;
00652 delete [] fP;
00653 fP = 0;
00654 return;
00655 }
00656 fN = n;
00657 if (fP) delete [] fP;
00658 fP = new Float_t[3*fN];
00659 memset(fP,0,3*fN*sizeof(Float_t));
00660 fLastPoint = fN-1;
00661 }
00662
00663
00664
00665 void TPolyLine3D::SetPolyLine(Int_t n, Float_t *p, Option_t *option)
00666 {
00667
00668
00669
00670 fOption = option;
00671 if (n <= 0) {
00672 fN = 0;
00673 fLastPoint = -1;
00674 delete [] fP;
00675 fP = 0;
00676 return;
00677 }
00678 fN = n;
00679 if (fP) delete [] fP;
00680 fP = new Float_t[3*fN];
00681 if (p) {
00682 for (Int_t i=0; i<fN;i++) {
00683 fP[3*i] = p[3*i];
00684 fP[3*i+1] = p[3*i+1];
00685 fP[3*i+2] = p[3*i+2];
00686 }
00687 } else {
00688 memset(fP,0,3*fN*sizeof(Float_t));
00689 }
00690 fLastPoint = fN-1;
00691 }
00692
00693
00694
00695 void TPolyLine3D::SetPolyLine(Int_t n, Double_t *p, Option_t *option)
00696 {
00697
00698
00699
00700 fOption = option;
00701 if (n <= 0) {
00702 fN = 0;
00703 fLastPoint = -1;
00704 delete [] fP;
00705 fP = 0;
00706 return;
00707 }
00708 fN = n;
00709 if (fP) delete [] fP;
00710 fP = new Float_t[3*fN];
00711 if (p) {
00712 for (Int_t i=0; i<fN;i++) {
00713 fP[3*i] = (Float_t) p[3*i];
00714 fP[3*i+1] = (Float_t) p[3*i+1];
00715 fP[3*i+2] = (Float_t) p[3*i+2];
00716 }
00717 } else {
00718 memset(fP,0,3*fN*sizeof(Float_t));
00719 }
00720 fLastPoint = fN-1;
00721 }
00722
00723
00724
00725 void TPolyLine3D::Streamer(TBuffer &b)
00726 {
00727
00728
00729 UInt_t R__s, R__c;
00730 if (b.IsReading()) {
00731 b.ReadVersion(&R__s, &R__c);
00732 TObject::Streamer(b);
00733 TAttLine::Streamer(b);
00734 b >> fN;
00735 if (fN) {
00736 fP = new Float_t[3*fN];
00737 b.ReadFastArray(fP,3*fN);
00738 }
00739 fOption.Streamer(b);
00740 fLastPoint = fN-1;
00741 b.CheckByteCount(R__s, R__c, TPolyLine3D::IsA());
00742 } else {
00743 R__c = b.WriteVersion(TPolyLine3D::IsA(), kTRUE);
00744 TObject::Streamer(b);
00745 TAttLine::Streamer(b);
00746 Int_t size = Size();
00747 b << size;
00748 if (size) b.WriteFastArray(fP, 3*size);
00749 fOption.Streamer(b);
00750 b.SetByteCount(R__c, kTRUE);
00751 }
00752 }