When is a TView created?

When drawing a lego or some other three dimensional represetion of an object when is the TView created? I’ve been trying to see how it is created by looking in THistPainter. There is a gPad->GetView() but it isn’t clear where it is created.
Thank you

The best is to look at:

void THistPainter::Paint2DErrors(Option_t *)

it paints errors in 3D and that’s very similar to what you want to do (lines in 3D)

Thank you very much for the advice. Please keep it coming!

To develop the code I made a seperate drawing function. It is part of my 3D Vector Field class I am making

class VFGrid : public TH3

void DrawTest();

I found that when I do a TView *vew = gPad->GetView() that the view does not yet exist. I have also found that doing things like gPad->PaintLine3D(…) does not show a line in the pad.

Question 1) in the example you cited, is the view created when the call
fLego = new TPainter3dAlgorithms is called?

Question 2) Why wouldnt the PaintLine3D show up?

Thank you.

Yes. See the constructor of this class

Here we hit again the question of the difference between “Paint()” and “Draw()”. The “PaintPrimitives()” methods in TPad should be used only in the main “Paint()” method of objects stored in the TPad list. I explain: when you do “Draw()” on an object nothing is drawn on screen. “Draw()” only puts that object in the TPad list of objects-to-be-painted. Then, when TPad::Update() is called, the whole list is traversed and the "Paint()"method of each object in that list is called. The “Paint()” methods use the “PaintPrimitives()” methods in TPad. That’s why when you call a “PaintPrimitives()” method directly, nothing is visible on screen because it is immediatly wiped out by the TPad redrawing.

That makes perfect sense. Thank you.

When I look at Draw methods, it appears that they only call the AppendPad method. I assume that is what you mean when you say the object is put into the list of object-to-be painted.

I am further assuming that when the pad is redrawn, that it cycles through that list and calls the individual THistPainter method necessary for the object. Given that I am writing a new method, do I have to add my method into the THistPainter class?

I’m guessing that I need to provide an overloaded method for TObject, but I’m not sure which it is.



You are right.

Yes, a new painting technique for some existing ROOT object (TH3 ?) should end up as a new option and a new method in THistpainter.

Note that for a test you can also produce TLines and use the Draw() method for each TLine. That will work. The TList in the pad will contain only TLines but for a first test that is good enough. Like that you do not need to modify anything in THistPainter.

Oliver, I’m hoping that you are still monitoring this thread.

I’ve made a call to TPainter3dAlgorithms from within my paint method and it crashes. I’m trying to do an analysis of what would cause that to happen, but was wondering if you might have a suggestion off the top of your head.

Below is a code segment:

fXbuf[0] = fXaxis.GetXmin();
fYbuf[0] = fXaxis.GetXmax();
fXbuf[1] = fYaxis.GetXmin();
fYbuf[1] = fYaxis.GetXmax();
fXbuf[2] = fZaxis.GetXmin();
fYbuf[2] = fZaxis.GetXmax();

TPainter3dAlgorithms* fLego = new TPainter3dAlgorithms( fXbuf, fYbuf);

I’m guessing that something else needs to be initialized prior to creating this.


Hi Chris,

That piece of code is a bit short to understand what’s going wrong. Note that TPainter3DAlgorythms is not meant to be use by end users. If you insist to do so I would suggest you start from and existing code like Paint2DErrors and modify it step by step. First include the code of Paint2D errors in the place you would like to make you new code. Make sure it works without modifying it. Then modify the code gradualy, testing each steps, to reach your aim.

Hi Oliver,
That is what I did do. I’m pretty sure that I understand where the problem is occuring. I may not be going about this the correct way.

TPainter3dAlgorithms makes use of a global variable gCurrentHist that it does not check the existance of. It is defined and set in THistPainter. cxx by the parent paint algorithms.

I was trying to see if I could fully flesh out the Vector Field paint method before integrating it into the root structure. As I said that may not be appropriate. At this point I should as the following questions:

  1. Would the root team be willing to incorporate code that I sent to it?
  2. If yes, are there applicable coding standards I should adhere to and who should I send the code to with the instructions for integration?

Thank you

Yes, if your new option is working and is useful we will integrate it.
See root.cern.ch/root/Conventions.html for the coding rules. Basically follows what is done in the THistPainter file.

I’m not sure exactly who to address this question to or if it even deserves to be in this thread.

I’m a bit confused about streamers. I get the impression that the streamer should be automatically generated. Where my confusion comes in is for objects within the class that are dynamically allocated.

Am I correct in assuming that I must provide my own streamer if I have a dynamically allocated array of objects, even if it is a array of root objects?

If so, where is a good example of where this is done?
I am looking in TH1.cxx at the streamer code there, specifically how is fbuffer allocated and filled?

Regards and Thanks

Hi Chris,

I can only point the chapter “Streamers” on page 163 of the User’s Guide (see at ftp://root.cern.ch/root/doc/chapter11.pdf ) and hope that someone else will answer your questions.

Cheers, Ilka

That is certainly where I am now, reading that chapter. The inheritance baffles me a bit.
Thanks for your reply.