00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "Riostream.h"
00013 #include "TView.h"
00014 #include "TPolyMarker3D.h"
00015 #include "TVirtualPad.h"
00016 #include "TH3.h"
00017 #include "TRandom.h"
00018 #include "TBuffer3D.h"
00019 #include "TBuffer3DTypes.h"
00020 #include "TVirtualViewer3D.h"
00021 #include "TGeometry.h"
00022 #include "TROOT.h"
00023 #include "TMath.h"
00024
00025 #include <assert.h>
00026
00027 ClassImp(TPolyMarker3D);
00028
00029 const Int_t kDimension = 3;
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 TPolyMarker3D::TPolyMarker3D()
00066 {
00067
00068
00069 fN = 0;
00070 fP = 0;
00071 fLastPoint = -1;
00072 fName = "TPolyMarker3D";
00073 }
00074
00075
00076 TPolyMarker3D::TPolyMarker3D(Int_t n, Marker_t marker, Option_t *option)
00077 {
00078
00079
00080 fName = "TPolyMarker3D";
00081 fOption = option;
00082 SetMarkerStyle(marker);
00083 SetBit(kCanDelete);
00084 fLastPoint = -1;
00085 if (n <= 0) {
00086 fN = 0;
00087 fP = 0;
00088 return;
00089 }
00090
00091 fN = n;
00092 fP = new Float_t [kDimension*fN];
00093 for (Int_t i = 0; i < kDimension*fN; i++) fP[i] = 0;
00094 }
00095
00096
00097 TPolyMarker3D::TPolyMarker3D(Int_t n, Float_t *p, Marker_t marker,
00098 Option_t *option)
00099 {
00100
00101
00102 fName = "TPolyMarker3D";
00103 SetMarkerStyle(marker);
00104 SetBit(kCanDelete);
00105 fOption = option;
00106 fLastPoint = -1;
00107 if (n <= 0) {
00108 fN = 0;
00109 fP = 0;
00110 return;
00111 }
00112
00113 fN = n;
00114 fP = new Float_t [kDimension*fN];
00115 if (p) {
00116 for (Int_t i = 0; i < kDimension*fN; i++)
00117 fP[i] = p[i];
00118 fLastPoint = fN-1;
00119 } else
00120 memset(fP,0,kDimension*fN*sizeof(Float_t));
00121 }
00122
00123
00124 TPolyMarker3D::TPolyMarker3D(Int_t n, Double_t *p, Marker_t marker,
00125 Option_t *option)
00126 {
00127
00128
00129
00130 fName = "TPolyMarker3D";
00131 SetMarkerStyle(marker);
00132 SetBit(kCanDelete);
00133 fOption = option;
00134 fLastPoint = -1;
00135 if (n <= 0) {
00136 fN = 0;
00137 fP = 0;
00138 return;
00139 }
00140
00141 fN = n;
00142 fP = new Float_t [kDimension*fN];
00143 if (p) {
00144 for (Int_t i = 0; i < kDimension*fN; i++)
00145 fP[i] = (Float_t) p[i];
00146 fLastPoint = fN-1;
00147 } else
00148 memset(fP,0,kDimension*fN*sizeof(Float_t));
00149 }
00150
00151
00152 TPolyMarker3D& TPolyMarker3D::operator=(const TPolyMarker3D& tp3)
00153 {
00154
00155 if(this!=&tp3) {
00156 TObject::operator=(tp3);
00157 TAttMarker::operator=(tp3);
00158 TAtt3D::operator=(tp3);
00159 fN=tp3.fN;
00160 fP=tp3.fP;
00161 fOption=tp3.fOption;
00162 fLastPoint=tp3.fLastPoint;
00163 fName=tp3.fName;
00164 }
00165 return *this;
00166 }
00167
00168
00169 TPolyMarker3D::~TPolyMarker3D()
00170 {
00171
00172
00173 fN = 0;
00174 if (fP) delete [] fP;
00175 fLastPoint = -1;
00176 }
00177
00178
00179 TPolyMarker3D::TPolyMarker3D(const TPolyMarker3D &p) :
00180 TObject(p), TAttMarker(p), TAtt3D(p)
00181 {
00182
00183
00184 fP = 0;
00185 p.Copy(*this);
00186 }
00187
00188
00189 void TPolyMarker3D::Copy(TObject &obj) const
00190 {
00191
00192
00193 TObject::Copy(obj);
00194 ((TPolyMarker3D&)obj).fN = fN;
00195 if (fN > 0) {
00196 ((TPolyMarker3D&)obj).fP = new Float_t [kDimension*fN];
00197 for (Int_t i = 0; i < kDimension*fN; i++) ((TPolyMarker3D&)obj).fP[i] = fP[i];
00198 } else {
00199 ((TPolyMarker3D&)obj).fP = 0;
00200 }
00201 ((TPolyMarker3D&)obj).SetMarkerStyle(GetMarkerStyle());
00202 ((TPolyMarker3D&)obj).fOption = fOption;
00203 ((TPolyMarker3D&)obj).fLastPoint = fLastPoint;
00204 ((TPolyMarker3D&)obj).fName = fName;
00205 }
00206
00207
00208 Int_t TPolyMarker3D::DistancetoPrimitive(Int_t px, Int_t py)
00209 {
00210
00211
00212
00213
00214
00215
00216 const Int_t inaxis = 7;
00217 Int_t dist = 9999;
00218
00219 Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
00220 Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
00221 Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
00222 Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
00223
00224
00225 if (px < puxmin - inaxis) return dist;
00226 if (py > puymin + inaxis) return dist;
00227 if (px > puxmax + inaxis) return dist;
00228 if (py < puymax - inaxis) return dist;
00229
00230 TView *view = gPad->GetView();
00231 if (!view) return dist;
00232 Int_t i, dpoint;
00233 Float_t xndc[3];
00234 Int_t x1,y1;
00235 Double_t u,v;
00236 for (i=0;i<Size();i++) {
00237 view->WCtoNDC(&fP[3*i], xndc);
00238 u = (Double_t)xndc[0];
00239 v = (Double_t)xndc[1];
00240 if (u < gPad->GetUxmin() || u > gPad->GetUxmax()) continue;
00241 if (v < gPad->GetUymin() || v > gPad->GetUymax()) continue;
00242 x1 = gPad->XtoAbsPixel(u);
00243 y1 = gPad->YtoAbsPixel(v);
00244 dpoint = Int_t(TMath::Sqrt((((Double_t)px-x1)*((Double_t)px-x1)
00245 + ((Double_t)py-y1)*((Double_t)py-y1))));
00246 if (dpoint < dist) dist = dpoint;
00247 }
00248 return dist;
00249 }
00250
00251
00252 void TPolyMarker3D::Draw(Option_t *option)
00253 {
00254
00255
00256 AppendPad(option);
00257 }
00258
00259
00260 void TPolyMarker3D::DrawPolyMarker(Int_t n, Float_t *p, Marker_t, Option_t *option)
00261 {
00262
00263
00264
00265
00266 TPolyMarker3D *newpolymarker = new TPolyMarker3D();
00267 newpolymarker->fN = n;
00268 newpolymarker->fP = new Float_t [kDimension*fN];
00269 for (Int_t i = 0; i < kDimension*fN; i++) newpolymarker->fP[i] = p[i];
00270 newpolymarker->SetMarkerStyle(GetMarkerStyle());
00271 newpolymarker->fOption = fOption;
00272 newpolymarker->fLastPoint = fLastPoint;
00273 newpolymarker->SetBit(kCanDelete);
00274 newpolymarker->AppendPad(option);
00275 }
00276
00277
00278 void TPolyMarker3D::ExecuteEvent(Int_t event, Int_t px, Int_t py)
00279 {
00280
00281
00282 if (gPad->GetView())
00283 gPad->GetView()->ExecuteRotateView(event, px, py);
00284 }
00285
00286
00287 void TPolyMarker3D::ls(Option_t *option) const
00288 {
00289
00290
00291 TROOT::IndentLevel();
00292 cout << " TPolyMarker3D N=" << Size() <<" Option="<<option<<endl;
00293 }
00294
00295
00296 Int_t TPolyMarker3D::Merge(TCollection *li)
00297 {
00298
00299
00300 if (!li) return 0;
00301 TIter next(li);
00302
00303
00304 TPolyMarker3D *pm;
00305 Int_t npoints = Size();
00306 while ((pm = (TPolyMarker3D*)next())) {
00307 if (!pm->InheritsFrom(TPolyMarker3D::Class())) {
00308 Error("Add","Attempt to add object of class: %s to a %s",pm->ClassName(),this->ClassName());
00309 return -1;
00310 }
00311 npoints += pm->Size();
00312 }
00313 Int_t currPoint = Size();
00314
00315
00316 SetPoint(npoints-1,0,0,0);
00317
00318
00319 next.Reset();
00320 while ((pm = (TPolyMarker3D*)next())) {
00321 Int_t np = pm->Size();
00322 Float_t *p = pm->GetP();
00323 for (Int_t i = 0; i < np; i++) {
00324 SetPoint(currPoint++, p[3*i], p[3*i+1], p[3*i+2]);
00325 }
00326 }
00327 return npoints;
00328 }
00329
00330
00331 void TPolyMarker3D::Paint(Option_t * )
00332 {
00333
00334
00335
00336 if (Size() <= 0) return;
00337
00338 static TBuffer3D buffer(TBuffer3DTypes::kMarker);
00339
00340 buffer.ClearSectionsValid();
00341
00342
00343 buffer.fID = this;
00344 buffer.fColor = GetMarkerColor();
00345 buffer.fTransparency = 0;
00346 buffer.fLocalFrame = kFALSE;
00347 buffer.SetSectionsValid(TBuffer3D::kCore);
00348
00349
00350 Int_t reqSections = gPad->GetViewer3D()->AddObject(buffer);
00351 if (reqSections == TBuffer3D::kNone) {
00352 return;
00353 }
00354
00355 if (reqSections & TBuffer3D::kRawSizes) {
00356 if (!buffer.SetRawSizes(Size(), 3*Size(), 1, 1, 0, 0)) {
00357 return;
00358 }
00359 buffer.SetSectionsValid(TBuffer3D::kRawSizes);
00360 }
00361
00362 if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) {
00363
00364 for (UInt_t i=0; i<3*buffer.NbPnts(); i++) {
00365 buffer.fPnts[i] = (Double_t)fP[i];
00366 }
00367
00368
00369
00370 if (gGeometry) {
00371 Double_t dlocal[3];
00372 Double_t dmaster[3];
00373 for (UInt_t j=0; j<buffer.NbPnts(); j++) {
00374 dlocal[0] = buffer.fPnts[3*j];
00375 dlocal[1] = buffer.fPnts[3*j+1];
00376 dlocal[2] = buffer.fPnts[3*j+2];
00377 gGeometry->Local2Master(&dlocal[0],&dmaster[0]);
00378 buffer.fPnts[3*j] = dmaster[0];
00379 buffer.fPnts[3*j+1] = dmaster[1];
00380 buffer.fPnts[3*j+2] = dmaster[2];
00381 }
00382 }
00383
00384
00385 Int_t c = (((GetMarkerColor()) %8) -1) * 4;
00386 if (c < 0) c = 0;
00387
00388
00389 buffer.fSegs[0] = c;
00390
00391 buffer.SetSectionsValid(TBuffer3D::kRaw);
00392
00393 TAttMarker::Modify();
00394 }
00395
00396 gPad->GetViewer3D()->AddObject(buffer);
00397 }
00398
00399
00400 void TPolyMarker3D::PaintH3(TH1 *h, Option_t *option)
00401 {
00402
00403
00404 const Int_t kMaxEntry = 100000;
00405 Int_t in, bin, binx, biny, binz;
00406
00407 TAxis *xaxis = h->GetXaxis();
00408 TAxis *yaxis = h->GetYaxis();
00409 TAxis *zaxis = h->GetZaxis();
00410 Double_t entry = 0;
00411 for (binz=zaxis->GetFirst();binz<=zaxis->GetLast();binz++) {
00412 for (biny=yaxis->GetFirst();biny<=yaxis->GetLast();biny++) {
00413 for (binx=xaxis->GetFirst();binx<=xaxis->GetLast();binx++) {
00414 bin = h->GetBin(binx,biny,binz);
00415 entry += h->GetBinContent(bin);
00416 }
00417 }
00418 }
00419
00420
00421
00422
00423 Double_t scale = 1.;
00424 if (entry > kMaxEntry) scale = kMaxEntry/Double_t(entry);
00425
00426
00427 TView *view = gPad->GetView();
00428 if (!view) {
00429 gPad->Range(-1,-1,1,1);
00430 view = TView::CreateView(1,0,0);
00431 }
00432 view->SetRange(xaxis->GetBinLowEdge(xaxis->GetFirst()),
00433 yaxis->GetBinLowEdge(yaxis->GetFirst()),
00434 zaxis->GetBinLowEdge(zaxis->GetFirst()),
00435 xaxis->GetBinUpEdge(xaxis->GetLast()),
00436 yaxis->GetBinUpEdge(yaxis->GetLast()),
00437 zaxis->GetBinUpEdge(zaxis->GetLast()));
00438
00439 view->PadRange(gPad->GetFrameFillColor());
00440
00441 if (entry == 0) return;
00442 Int_t nmk = Int_t(TMath::Min(Double_t(kMaxEntry),entry));
00443 TPolyMarker3D *pm3d = new TPolyMarker3D(nmk);
00444 pm3d->SetMarkerStyle(h->GetMarkerStyle());
00445 pm3d->SetMarkerColor(h->GetMarkerColor());
00446 pm3d->SetMarkerSize(h->GetMarkerSize());
00447 gPad->Modified(kTRUE);
00448
00449 entry = 0;
00450 Double_t x,y,z,xw,yw,zw,xp,yp,zp;
00451 Int_t ncounts;
00452 for (binz=zaxis->GetFirst();binz<=zaxis->GetLast();binz++) {
00453 z = zaxis->GetBinLowEdge(binz);
00454 zw = zaxis->GetBinWidth(binz);
00455 for (biny=yaxis->GetFirst();biny<=yaxis->GetLast();biny++) {
00456 y = yaxis->GetBinLowEdge(biny);
00457 yw = yaxis->GetBinWidth(biny);
00458 for (binx=xaxis->GetFirst();binx<=xaxis->GetLast();binx++) {
00459 x = xaxis->GetBinLowEdge(binx);
00460 xw = xaxis->GetBinWidth(binx);
00461 bin = h->GetBin(binx,biny,binz);
00462 ncounts = Int_t(h->GetBinContent(bin)*scale+0.5);
00463 for (in=0;in<ncounts;in++) {
00464 xp = x + xw*gRandom->Rndm(in);
00465 yp = y + yw*gRandom->Rndm(in);
00466 zp = z + zw*gRandom->Rndm(in);
00467 pm3d->SetPoint(Int_t(entry),xp,yp,zp);
00468 entry++;
00469 }
00470 }
00471 }
00472 }
00473 pm3d->Paint(option);
00474 delete pm3d;
00475 }
00476
00477
00478 void TPolyMarker3D::Print(Option_t *option) const
00479 {
00480
00481
00482 printf("TPolyMarker3D N=%d, Option=%s\n",fN,option);
00483 TString opt = option;
00484 opt.ToLower();
00485 if (opt.Contains("all")) {
00486 for (Int_t i=0;i<Size();i++) {
00487 TROOT::IndentLevel();
00488 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]);
00489 }
00490 }
00491 }
00492
00493
00494 void TPolyMarker3D::SavePrimitive(ostream &out, Option_t * )
00495 {
00496
00497
00498 char quote = '"';
00499 out<<" "<<endl;
00500 if (gROOT->ClassSaved(TPolyMarker3D::Class())) {
00501 out<<" ";
00502 } else {
00503 out<<" TPolyMarker3D *";
00504 }
00505 out<<"pmarker3D = new TPolyMarker3D("<<fN<<","<<GetMarkerStyle()<<","<<quote<<fOption<<quote<<");"<<endl;
00506 out<<" pmarker3D->SetName("<<quote<<GetName()<<quote<<");"<<endl;
00507
00508 SaveMarkerAttributes(out,"pmarker3D",1,1,1);
00509
00510 for (Int_t i=0;i<Size();i++) {
00511 out<<" pmarker3D->SetPoint("<<i<<","<<fP[3*i]<<","<<fP[3*i+1]<<","<<fP[3*i+2]<<");"<<endl;
00512 }
00513 out<<" pmarker3D->Draw();"<<endl;
00514 }
00515
00516
00517 void TPolyMarker3D::SetName(const char *name)
00518 {
00519
00520
00521
00522
00523
00524 fName = name;
00525 if (gPad && TestBit(kMustCleanup)) gPad->Modified();
00526 }
00527
00528
00529 Int_t TPolyMarker3D::SetNextPoint(Double_t x, Double_t y, Double_t z)
00530 {
00531
00532
00533
00534 fLastPoint++;
00535 SetPoint(fLastPoint, x, y, z);
00536 return fLastPoint;
00537 }
00538
00539
00540 void TPolyMarker3D::SetPoint(Int_t n, Double_t x, Double_t y, Double_t z)
00541 {
00542
00543
00544
00545
00546 if (n < 0) return;
00547 if (!fP || n >= fN) {
00548
00549 Int_t newN = TMath::Max(2*fN,n+1);
00550 Float_t *savepoint = new Float_t [kDimension*newN];
00551 if (fP && fN){
00552 memcpy(savepoint,fP,kDimension*fN*sizeof(Float_t));
00553 memset(&savepoint[kDimension*fN],0,(newN-fN)*sizeof(Float_t));
00554 delete [] fP;
00555 }
00556 fP = savepoint;
00557 fN = newN;
00558 }
00559 fP[kDimension*n ] = x;
00560 fP[kDimension*n+1] = y;
00561 fP[kDimension*n+2] = z;
00562 fLastPoint = TMath::Max(fLastPoint,n);
00563 }
00564
00565
00566 void TPolyMarker3D::SetPolyMarker(Int_t n, Float_t *p, Marker_t marker, Option_t *option)
00567 {
00568
00569
00570
00571 SetMarkerStyle(marker);
00572 fOption = option;
00573 if (n <= 0) {
00574 fN = 0;
00575 fLastPoint = -1;
00576 delete [] fP;
00577 fP = 0;
00578 return;
00579 }
00580 fN = n;
00581 if (fP) delete [] fP;
00582 fP = new Float_t [3*fN];
00583 for (Int_t i = 0; i < fN; i++) {
00584 if (p) {
00585 fP[3*i] = p[3*i];
00586 fP[3*i+1] = p[3*i+1];
00587 fP[3*i+2] = p[3*i+2];
00588 } else {
00589 memset(fP,0,kDimension*fN*sizeof(Float_t));
00590 }
00591 }
00592 fLastPoint = fN-1;
00593 }
00594
00595
00596 void TPolyMarker3D::SetPolyMarker(Int_t n, Double_t *p, Marker_t marker, Option_t *option)
00597 {
00598
00599
00600
00601 SetMarkerStyle(marker);
00602 fOption = option;
00603 if (n <= 0) {
00604 fN = 0;
00605 fLastPoint = -1;
00606 delete [] fP;
00607 fP = 0;
00608 return;
00609 }
00610 fN = n;
00611 if (fP) delete [] fP;
00612 fP = new Float_t [3*fN];
00613 for (Int_t i = 0; i < fN; i++) {
00614 if (p) {
00615 fP[3*i] = (Float_t) p[3*i];
00616 fP[3*i+1] = (Float_t) p[3*i+1];
00617 fP[3*i+2] = (Float_t) p[3*i+2];
00618 } else {
00619 memset(fP,0,kDimension*fN*sizeof(Float_t));
00620 }
00621 }
00622 fLastPoint = fN-1;
00623 }
00624
00625
00626 void TPolyMarker3D::Streamer(TBuffer &b)
00627 {
00628
00629
00630 UInt_t R__s, R__c;
00631 if (b.IsReading()) {
00632 Version_t R__v = b.ReadVersion(&R__s, &R__c);
00633 TObject::Streamer(b);
00634 TAttMarker::Streamer(b);
00635 b >> fN;
00636 if (fN) {
00637 fP = new Float_t[kDimension*fN];
00638 b.ReadFastArray(fP,kDimension*fN);
00639 }
00640 fLastPoint = fN-1;
00641 fOption.Streamer(b);
00642 if (R__v > 1) fName.Streamer(b);
00643 b.CheckByteCount(R__s, R__c, TPolyMarker3D::IsA());
00644 } else {
00645 R__c = b.WriteVersion(TPolyMarker3D::IsA(), kTRUE);
00646 TObject::Streamer(b);
00647 TAttMarker::Streamer(b);
00648 Int_t size = Size();
00649 b << size;
00650 if (size) b.WriteFastArray(fP, kDimension*size);
00651 fOption.Streamer(b);
00652 fName.Streamer(b);
00653 b.SetByteCount(R__c, kTRUE);
00654 }
00655 }
00656
00657
00658 void TPolyMarker3D::GetPoint(Int_t n, Float_t &x, Float_t &y, Float_t &z) const
00659 {
00660
00661
00662
00663 if (n < 0 || n >= Size()) return;
00664 if (!fP) return;
00665 x = fP[kDimension*n ];
00666 y = fP[kDimension*n+1];
00667 z = fP[kDimension*n+2];
00668 }
00669
00670
00671 void TPolyMarker3D::GetPoint(Int_t n, Double_t &x, Double_t &y, Double_t &z) const
00672 {
00673
00674
00675
00676 if (n < 0 || n >= Size()) return;
00677 if (!fP) return;
00678 x = (Double_t)fP[kDimension*n ];
00679 y = (Double_t)fP[kDimension*n+1];
00680 z = (Double_t)fP[kDimension*n+2];
00681 }
00682
00683