From 81fcfd92f3d31dcc37e73e0b28897e2f2499a6b0 Mon Sep 17 00:00:00 2001 From: Fons Rademakers Date: Mon, 26 Nov 2007 14:31:05 +0000 Subject: [PATCH] from Matevz: add the TEve classes to the svn trunk. Code compiles without warnings on MacOS X, Linux and Windows XP. Tutorials still don't work, as init code is still missing (coming later today). git-svn-id: http://root.cern.ch/svn/root/trunk@21044 27541ba8-7e3a-0410-8455-c3a389f83636 --- Makefile | 8 +- config/Makefile.depend | 20 +- eve/Module.mk | 71 ++ eve/inc/LinkDef.h | 187 +++ eve/inc/TEveBoxSet.h | 82 ++ eve/inc/TEveBoxSetGL.h | 55 + eve/inc/TEveBrowser.h | 93 ++ eve/inc/TEveChunkManager.h | 149 +++ eve/inc/TEveDigitSet.h | 137 +++ eve/inc/TEveDigitSetEditor.h | 62 + eve/inc/TEveElement.h | 258 ++++ eve/inc/TEveElementEditor.h | 54 + eve/inc/TEveEventManager.h | 41 + eve/inc/TEveFrameBox.h | 89 ++ eve/inc/TEveFrameBoxGL.h | 36 + eve/inc/TEveGLText.h | 159 +++ eve/inc/TEveGLUtil.h | 91 ++ eve/inc/TEveGValuators.h | 200 ++++ eve/inc/TEveGedEditor.h | 45 + eve/inc/TEveGeoNode.h | 166 +++ eve/inc/TEveGeoNodeEditor.h | 84 ++ eve/inc/TEveGeoShapeExtract.h | 59 + eve/inc/TEveGridStepper.h | 60 + eve/inc/TEveGridStepperEditor.h | 75 ++ eve/inc/TEveLine.h | 52 + eve/inc/TEveLineEditor.h | 47 + eve/inc/TEveLineGL.h | 47 + eve/inc/TEveMacro.h | 36 + eve/inc/TEveManager.h | 181 +++ eve/inc/TEvePad.h | 36 + eve/inc/TEvePointSet.h | 170 +++ eve/inc/TEvePointSetArrayEditor.h | 48 + eve/inc/TEvePointSetProjectedGL.h | 38 + eve/inc/TEvePolygonSetProjected.h | 131 +++ eve/inc/TEvePolygonSetProjectedEditor.h | 46 + eve/inc/TEvePolygonSetProjectedGL.h | 33 + eve/inc/TEveProjectionBases.h | 87 ++ eve/inc/TEveProjectionManager.h | 83 ++ eve/inc/TEveProjectionManagerEditor.h | 76 ++ eve/inc/TEveProjectionManagerGL.h | 69 ++ eve/inc/TEveProjections.h | 127 ++ eve/inc/TEveQuadSet.h | 131 +++ eve/inc/TEveQuadSetGL.h | 51 + eve/inc/TEveRGBAPalette.h | 207 ++++ eve/inc/TEveRGBAPaletteEditor.h | 89 ++ eve/inc/TEveScene.h | 82 ++ eve/inc/TEveSceneInfo.h | 53 + eve/inc/TEveStraightLineSet.h | 141 +++ eve/inc/TEveStraightLineSetEditor.h | 49 + eve/inc/TEveStraightLineSetGL.h | 50 + eve/inc/TEveTrack.h | 245 ++++ eve/inc/TEveTrackEditor.h | 141 +++ eve/inc/TEveTrackGL.h | 46 + eve/inc/TEveTrackProjected.h | 76 ++ eve/inc/TEveTrackProjectedGL.h | 42 + eve/inc/TEveTrackPropagator.h | 169 +++ eve/inc/TEveTrackPropagatorEditor.h | 115 ++ eve/inc/TEveTrans.h | 169 +++ eve/inc/TEveTransEditor.h | 82 ++ eve/inc/TEveTreeTools.h | 113 ++ eve/inc/TEveTriangleSet.h | 95 ++ eve/inc/TEveTriangleSetEditor.h | 44 + eve/inc/TEveTriangleSetGL.h | 46 + eve/inc/TEveUtil.h | 170 +++ eve/inc/TEveVSD.h | 71 ++ eve/inc/TEveVSDStructs.h | 357 ++++++ eve/inc/TEveViewer.h | 83 ++ eve/src/TEveBoxSet.cxx | 249 ++++ eve/src/TEveBoxSetGL.cxx | 351 ++++++ eve/src/TEveBrowser.cxx | 595 ++++++++++ eve/src/TEveChunkManager.cxx | 93 ++ eve/src/TEveDigitSet.cxx | 305 +++++ eve/src/TEveDigitSetEditor.cxx | 187 +++ eve/src/TEveElement.cxx | 822 +++++++++++++ eve/src/TEveElementEditor.cxx | 160 +++ eve/src/TEveEventManager.cxx | 48 + eve/src/TEveFrameBox.cxx | 168 +++ eve/src/TEveFrameBoxGL.cxx | 101 ++ eve/src/TEveGLText.cxx | 727 ++++++++++++ eve/src/TEveGLUtil.cxx | 215 ++++ eve/src/TEveGValuators.cxx | 443 +++++++ eve/src/TEveGedEditor.cxx | 119 ++ eve/src/TEveGeoNode.cxx | 580 +++++++++ eve/src/TEveGeoNodeEditor.cxx | 219 ++++ eve/src/TEveGeoShapeExtract.cxx | 80 ++ eve/src/TEveGridStepper.cxx | 101 ++ eve/src/TEveGridStepperEditor.cxx | 193 +++ eve/src/TEveLine.cxx | 41 + eve/src/TEveLineEditor.cxx | 84 ++ eve/src/TEveLineGL.cxx | 71 ++ eve/src/TEveMacro.cxx | 112 ++ eve/src/TEveManager.cxx | 534 +++++++++ eve/src/TEvePad.cxx | 38 + eve/src/TEvePointSet.cxx | 602 ++++++++++ eve/src/TEvePointSetArrayEditor.cxx | 86 ++ eve/src/TEvePointSetProjectedGL.cxx | 33 + eve/src/TEvePolygonSetProjected.cxx | 473 ++++++++ eve/src/TEvePolygonSetProjectedEditor.cxx | 83 ++ eve/src/TEvePolygonSetProjectedGL.cxx | 161 +++ eve/src/TEveProjectionBases.cxx | 98 ++ eve/src/TEveProjectionManager.cxx | 256 ++++ eve/src/TEveProjectionManagerEditor.cxx | 335 ++++++ eve/src/TEveProjectionManagerGL.cxx | 315 +++++ eve/src/TEveProjections.cxx | 278 +++++ eve/src/TEveQuadSet.cxx | 473 ++++++++ eve/src/TEveQuadSetGL.cxx | 521 +++++++++ eve/src/TEveRGBAPalette.cxx | 257 ++++ eve/src/TEveRGBAPaletteEditor.cxx | 261 +++++ eve/src/TEveScene.cxx | 127 ++ eve/src/TEveSceneInfo.cxx | 81 ++ eve/src/TEveStraightLineSet.cxx | 186 +++ eve/src/TEveStraightLineSetEditor.cxx | 88 ++ eve/src/TEveStraightLineSetGL.cxx | 188 +++ eve/src/TEveTrack.cxx | 1301 +++++++++++++++++++++ eve/src/TEveTrackEditor.cxx | 511 ++++++++ eve/src/TEveTrackGL.cxx | 116 ++ eve/src/TEveTrackProjected.cxx | 246 ++++ eve/src/TEveTrackProjectedGL.cxx | 117 ++ eve/src/TEveTrackPropagator.cxx | 444 +++++++ eve/src/TEveTrackPropagatorEditor.cxx | 398 +++++++ eve/src/TEveTrans.cxx | 830 +++++++++++++ eve/src/TEveTransEditor.cxx | 232 ++++ eve/src/TEveTreeTools.cxx | 125 ++ eve/src/TEveTriangleSet.cxx | 198 ++++ eve/src/TEveTriangleSetEditor.cxx | 61 + eve/src/TEveTriangleSetGL.cxx | 123 ++ eve/src/TEveUtil.cxx | 395 +++++++ eve/src/TEveVSD.cxx | 240 ++++ eve/src/TEveVSDStructs.cxx | 82 ++ eve/src/TEveViewer.cxx | 200 ++++ fonts/eve_fontdefault.txf | Bin 0 -> 3220 bytes fonts/eve_fonthelvetica34.txf | Bin 0 -> 9364 bytes icons/eve_pointset.xpm | 25 + icons/eve_rnr00_t.xpm | 23 + icons/eve_rnr01_t.xpm | 23 + icons/eve_rnr10_t.xpm | 23 + icons/eve_rnr11_t.xpm | 23 + icons/eve_scene.xpm | 24 + icons/eve_track.xpm | 61 + icons/eve_viewer.xpm | 108 ++ tutorials/eve/broken_torus.tring | 1003 ++++++++++++++++ tutorials/eve/lineset_test.C | 26 + tutorials/eve/nasashuttle.3ds | Bin 0 -> 219441 bytes tutorials/eve/quad_test.C | 198 ++++ tutorials/eve/triangleset.C | 56 + tutorials/eve/view3ds.C | 583 +++++++++ 146 files changed, 25831 insertions(+), 7 deletions(-) create mode 100644 eve/Module.mk create mode 100644 eve/inc/LinkDef.h create mode 100644 eve/inc/TEveBoxSet.h create mode 100644 eve/inc/TEveBoxSetGL.h create mode 100644 eve/inc/TEveBrowser.h create mode 100644 eve/inc/TEveChunkManager.h create mode 100644 eve/inc/TEveDigitSet.h create mode 100644 eve/inc/TEveDigitSetEditor.h create mode 100644 eve/inc/TEveElement.h create mode 100644 eve/inc/TEveElementEditor.h create mode 100644 eve/inc/TEveEventManager.h create mode 100644 eve/inc/TEveFrameBox.h create mode 100644 eve/inc/TEveFrameBoxGL.h create mode 100644 eve/inc/TEveGLText.h create mode 100644 eve/inc/TEveGLUtil.h create mode 100644 eve/inc/TEveGValuators.h create mode 100644 eve/inc/TEveGedEditor.h create mode 100644 eve/inc/TEveGeoNode.h create mode 100644 eve/inc/TEveGeoNodeEditor.h create mode 100644 eve/inc/TEveGeoShapeExtract.h create mode 100644 eve/inc/TEveGridStepper.h create mode 100644 eve/inc/TEveGridStepperEditor.h create mode 100644 eve/inc/TEveLine.h create mode 100644 eve/inc/TEveLineEditor.h create mode 100644 eve/inc/TEveLineGL.h create mode 100644 eve/inc/TEveMacro.h create mode 100644 eve/inc/TEveManager.h create mode 100644 eve/inc/TEvePad.h create mode 100644 eve/inc/TEvePointSet.h create mode 100644 eve/inc/TEvePointSetArrayEditor.h create mode 100644 eve/inc/TEvePointSetProjectedGL.h create mode 100644 eve/inc/TEvePolygonSetProjected.h create mode 100644 eve/inc/TEvePolygonSetProjectedEditor.h create mode 100644 eve/inc/TEvePolygonSetProjectedGL.h create mode 100644 eve/inc/TEveProjectionBases.h create mode 100644 eve/inc/TEveProjectionManager.h create mode 100644 eve/inc/TEveProjectionManagerEditor.h create mode 100644 eve/inc/TEveProjectionManagerGL.h create mode 100644 eve/inc/TEveProjections.h create mode 100644 eve/inc/TEveQuadSet.h create mode 100644 eve/inc/TEveQuadSetGL.h create mode 100644 eve/inc/TEveRGBAPalette.h create mode 100644 eve/inc/TEveRGBAPaletteEditor.h create mode 100644 eve/inc/TEveScene.h create mode 100644 eve/inc/TEveSceneInfo.h create mode 100644 eve/inc/TEveStraightLineSet.h create mode 100644 eve/inc/TEveStraightLineSetEditor.h create mode 100644 eve/inc/TEveStraightLineSetGL.h create mode 100644 eve/inc/TEveTrack.h create mode 100644 eve/inc/TEveTrackEditor.h create mode 100644 eve/inc/TEveTrackGL.h create mode 100644 eve/inc/TEveTrackProjected.h create mode 100644 eve/inc/TEveTrackProjectedGL.h create mode 100644 eve/inc/TEveTrackPropagator.h create mode 100644 eve/inc/TEveTrackPropagatorEditor.h create mode 100644 eve/inc/TEveTrans.h create mode 100644 eve/inc/TEveTransEditor.h create mode 100644 eve/inc/TEveTreeTools.h create mode 100644 eve/inc/TEveTriangleSet.h create mode 100644 eve/inc/TEveTriangleSetEditor.h create mode 100644 eve/inc/TEveTriangleSetGL.h create mode 100644 eve/inc/TEveUtil.h create mode 100644 eve/inc/TEveVSD.h create mode 100644 eve/inc/TEveVSDStructs.h create mode 100644 eve/inc/TEveViewer.h create mode 100644 eve/src/TEveBoxSet.cxx create mode 100644 eve/src/TEveBoxSetGL.cxx create mode 100644 eve/src/TEveBrowser.cxx create mode 100644 eve/src/TEveChunkManager.cxx create mode 100644 eve/src/TEveDigitSet.cxx create mode 100644 eve/src/TEveDigitSetEditor.cxx create mode 100644 eve/src/TEveElement.cxx create mode 100644 eve/src/TEveElementEditor.cxx create mode 100644 eve/src/TEveEventManager.cxx create mode 100644 eve/src/TEveFrameBox.cxx create mode 100644 eve/src/TEveFrameBoxGL.cxx create mode 100644 eve/src/TEveGLText.cxx create mode 100644 eve/src/TEveGLUtil.cxx create mode 100644 eve/src/TEveGValuators.cxx create mode 100644 eve/src/TEveGedEditor.cxx create mode 100644 eve/src/TEveGeoNode.cxx create mode 100644 eve/src/TEveGeoNodeEditor.cxx create mode 100644 eve/src/TEveGeoShapeExtract.cxx create mode 100644 eve/src/TEveGridStepper.cxx create mode 100644 eve/src/TEveGridStepperEditor.cxx create mode 100644 eve/src/TEveLine.cxx create mode 100644 eve/src/TEveLineEditor.cxx create mode 100644 eve/src/TEveLineGL.cxx create mode 100644 eve/src/TEveMacro.cxx create mode 100644 eve/src/TEveManager.cxx create mode 100644 eve/src/TEvePad.cxx create mode 100644 eve/src/TEvePointSet.cxx create mode 100644 eve/src/TEvePointSetArrayEditor.cxx create mode 100644 eve/src/TEvePointSetProjectedGL.cxx create mode 100644 eve/src/TEvePolygonSetProjected.cxx create mode 100644 eve/src/TEvePolygonSetProjectedEditor.cxx create mode 100644 eve/src/TEvePolygonSetProjectedGL.cxx create mode 100644 eve/src/TEveProjectionBases.cxx create mode 100644 eve/src/TEveProjectionManager.cxx create mode 100644 eve/src/TEveProjectionManagerEditor.cxx create mode 100644 eve/src/TEveProjectionManagerGL.cxx create mode 100644 eve/src/TEveProjections.cxx create mode 100644 eve/src/TEveQuadSet.cxx create mode 100644 eve/src/TEveQuadSetGL.cxx create mode 100644 eve/src/TEveRGBAPalette.cxx create mode 100644 eve/src/TEveRGBAPaletteEditor.cxx create mode 100644 eve/src/TEveScene.cxx create mode 100644 eve/src/TEveSceneInfo.cxx create mode 100644 eve/src/TEveStraightLineSet.cxx create mode 100644 eve/src/TEveStraightLineSetEditor.cxx create mode 100644 eve/src/TEveStraightLineSetGL.cxx create mode 100644 eve/src/TEveTrack.cxx create mode 100644 eve/src/TEveTrackEditor.cxx create mode 100644 eve/src/TEveTrackGL.cxx create mode 100644 eve/src/TEveTrackProjected.cxx create mode 100644 eve/src/TEveTrackProjectedGL.cxx create mode 100644 eve/src/TEveTrackPropagator.cxx create mode 100644 eve/src/TEveTrackPropagatorEditor.cxx create mode 100644 eve/src/TEveTrans.cxx create mode 100644 eve/src/TEveTransEditor.cxx create mode 100644 eve/src/TEveTreeTools.cxx create mode 100644 eve/src/TEveTriangleSet.cxx create mode 100644 eve/src/TEveTriangleSetEditor.cxx create mode 100644 eve/src/TEveTriangleSetGL.cxx create mode 100644 eve/src/TEveUtil.cxx create mode 100644 eve/src/TEveVSD.cxx create mode 100644 eve/src/TEveVSDStructs.cxx create mode 100644 eve/src/TEveViewer.cxx create mode 100644 fonts/eve_fontdefault.txf create mode 100644 fonts/eve_fonthelvetica34.txf create mode 100644 icons/eve_pointset.xpm create mode 100644 icons/eve_rnr00_t.xpm create mode 100644 icons/eve_rnr01_t.xpm create mode 100644 icons/eve_rnr10_t.xpm create mode 100644 icons/eve_rnr11_t.xpm create mode 100644 icons/eve_scene.xpm create mode 100644 icons/eve_track.xpm create mode 100644 icons/eve_viewer.xpm create mode 100644 tutorials/eve/broken_torus.tring create mode 100644 tutorials/eve/lineset_test.C create mode 100644 tutorials/eve/nasashuttle.3ds create mode 100644 tutorials/eve/quad_test.C create mode 100644 tutorials/eve/triangleset.C create mode 100644 tutorials/eve/view3ds.C diff --git a/Makefile b/Makefile index d059a82a58..664610e4ea 100644 --- a/Makefile +++ b/Makefile @@ -75,7 +75,7 @@ endif endif ifeq ($(BUILDGL),yes) ifeq ($(BUILDFTGL),yes) -MODULES += ftgl +MODULES += ftgl eve endif MODULES += gl endif @@ -219,7 +219,7 @@ MODULES += unix winnt x11 x11ttf win32gdk gl ftgl rfio castor \ ldap mlp krb5auth rpdutils globusauth pyroot ruby gfal \ qt qtroot qtgsi xrootd netx proofx alien clarens peac oracle \ xmlparser mathcore mathmore reflex cintex roofitcore roofit \ - minuit2 monalisa fftw odbc unuran gdml g4root cint7 + minuit2 monalisa fftw odbc unuran gdml eve g4root cint7 MODULES := $(sort $(MODULES)) # removes duplicates endif @@ -1077,7 +1077,7 @@ showbuild: showit: @echo "Modules:$(word 1, $(MODULES))" @$(foreach m, $(filter-out $(word 1, $(MODULES)), $(MODULES)), \ - echo -e "\t$(m)" ;) + echo -e "\t$(m)" ;) @echo "Libraries:$(word 1, $(ALLLIBS))" @$(foreach l, $(filter-out $(word 1, $(ALLLIBS)), $(ALLLIBS)), \ - echo -e "\t$(l)" ;) + echo -e "\t$(l)" ;) diff --git a/config/Makefile.depend b/config/Makefile.depend index 6ffa5e5322..6601d15780 100644 --- a/config/Makefile.depend +++ b/config/Makefile.depend @@ -12,7 +12,7 @@ ASIMAGELIBDEPM = $(GRAFLIB) ASIMAGEGUILIBDEPM = $(GRAFLIB) $(HISTLIB) $(GUILIB) $(ASIMAGELIB) $(IOLIB) ASIMAGEGSLIBDEPM = $(GRAFLIB) $(ASIMAGELIB) GEDLIBDEPM = $(HISTLIB) $(GPADLIB) $(GRAFLIB) $(GUILIB) $(TREELIB) \ - $(TREEPLAYERLIB) + $(TREEPLAYERLIB) POSTSCRIPTLIBDEPM = $(GRAFLIB) GUILIBDEPM = $(GPADLIB) $(GRAFLIB) $(IOLIB) GUIHTMLLIBDEPM = $(GUILIB) $(GRAFLIB) $(NETLIB) @@ -31,7 +31,7 @@ PROOFLIBDEPM = $(NETLIB) $(TREELIB) $(THREADLIB) $(IOLIB) PROOFPLAYERLIBDEPM = $(PROOFLIB) $(HISTLIB) $(IOLIB) $(TREELIB) $(NETLIB) \ $(THREADLIB) PROOFDRAWLIBDEPM = $(TREEPLAYERLIB) $(G3DLIB) $(GRAFLIB) $(GPADLIB) \ - $(PROOFPLAYERLIB) $(HISTLIB) $(TREELIB) $(PROOFLIB) + $(PROOFPLAYERLIB) $(HISTLIB) $(TREELIB) $(PROOFLIB) PROOFXLIBDEPM = $(NETLIB) $(PROOFLIB) $(THREADLIB) SESSIONVIEWERLIBDEPM = $(PROOFLIB) $(GUILIB) $(GPADLIB) $(GRAFLIB) $(TREELIB) PEACLIBDEPM = $(PROOFLIB) $(CLARENSLIB) @@ -93,6 +93,10 @@ X11TTFLIBDEPM = $(X11LIB) $(GRAFLIB) X3DLIBDEPM = $(G3DLIB) $(GUILIB) MONALISALIBDEPM = $(NETLIB) $(IOLIB) THREADLIBDEPM = $(IOLIB) +EVELIBDEPM = $(GEOMLIB) $(GEOMPAINTERLIB) $(G3DLIB) $(GUILIB) \ + $(GPADLIB) $(GRAFLIB) $(HISTLIB) $(PHYSICSLIB) \ + $(GEDLIB) $(EGLIB) $(TREELIB) $(TREEPLAYERLIB) \ + $(GLLIB) $(FTGLLIB) $(IOLIB) $(RINTLIB) ifeq ($(EXPLICITLINK),yes) @@ -173,6 +177,7 @@ X11TTFLIBDEP = $(X11TTFLIBDEPM) X3DLIBDEP = $(X3DLIBDEPM) MONALISALIBDEP = $(MONALISALIBDEPM) THREADLIBDEP = $(THREADLIBDEPM) +EVELIBDEP = $(EVELIBDEPM) ifeq ($(PLATFORM),win32) @@ -187,7 +192,7 @@ ASIMAGEGUILIBEXTRA = lib/libGraf.lib lib/libHist.lib lib/libGui.lib \ lib/libASImage.lib lib/libRIO.lib ASIMAGEGSLIBEXTRA = lib/libGraf.lib lib/libASImage.lib GEDLIBEXTRA = lib/libHist.lib lib/libGpad.lib lib/libGraf.lib \ - lib/libTree.lib lib/libTreePlayer.lib lib/libGui.lib + lib/libTree.lib lib/libTreePlayer.lib lib/libGui.lib POSTSCRIPTLIBEXTRA = lib/libGraf.lib GUILIBEXTRA = lib/libGpad.lib lib/libGraf.lib lib/libRIO.lib HISTPAINTERLIBEXTRA = lib/libGraf.lib lib/libHist.lib lib/libMatrix.lib \ @@ -276,6 +281,12 @@ GDMLLIBEXTRA = lib/libGeom.lib lib/libXMLIO.lib lib/libHist.lib \ UNURANLIBEXTRA = lib/libHist.lib MONALISALIBEXTRA = lib/libNet.lib lib/libRIO.lib THREADLIBEXTRA = lib/libRIO.lib +EVELIBEXTRA = lib/libGeom.lib lib/libGeomPainter.lib \ + lib/libGpad.lib lib/libGraf3d.lib lib/libGui.lib \ + lib/libGraf.lib lib/libHist.lib lib/libPhysics.lib \ + lib/libGed.lib lib/libEG.lib lib/libTree.lib \ + lib/libTreePlayer.lib lib/libRGL.lib lib/libRIO.lib \ + lib/libRint.lib else @@ -358,6 +369,9 @@ GDMLLIBEXTRA = -Llib -lGeom -lXMLIO -lHist -lRIO UNURANLIBEXTRA = -Llib -lHist MONALISALIBEXTRA = -Llib -lNet -lRIO THREADLIBEXTRA = -Llib -lRIO +EVELIBEXTRA = -Llib -lGeom -lGeomPainter -lGraf3d -lGui -lGpad \ + -lGraf -lHist -lPhysics -lGed -lEG -lTree \ + -lTreePlayer -lRGL -lRIO -lRint endif diff --git a/eve/Module.mk b/eve/Module.mk new file mode 100644 index 0000000000..297e37b1eb --- /dev/null +++ b/eve/Module.mk @@ -0,0 +1,71 @@ +# Module.mk for eve module +# Copyright (c) 2007 Rene Brun and Fons Rademakers +# +# Author: Fons Rademakers 26/11/2007 + +MODDIR := eve +MODDIRS := $(MODDIR)/src +MODDIRI := $(MODDIR)/inc + +EVEDIR := $(MODDIR) +EVEDIRS := $(EVEDIR)/src +EVEDIRI := $(EVEDIR)/inc + +##### libEve ##### +EVEL := $(MODDIRI)/LinkDef.h +EVEDS := $(MODDIRS)/G__Eve.cxx +EVEDO := $(EVEDS:.cxx=.o) +EVEDH := $(EVEDS:.cxx=.h) + +EVEH := $(filter-out $(MODDIRI)/LinkDef%,$(wildcard $(MODDIRI)/*.h)) +EVES := $(filter-out $(MODDIRS)/G__%,$(wildcard $(MODDIRS)/*.cxx)) +EVEO := $(EVES:.cxx=.o) + +EVEDEP := $(EVEO:.o=.d) $(EVEDO:.o=.d) + +EVELIB := $(LPATH)/libEve.$(SOEXT) +EVEMAP := $(EVELIB:.$(SOEXT)=.rootmap) + +# used in the main Makefile +ALLHDRS += $(patsubst $(MODDIRI)/%.h,include/%.h,$(EVEH)) +ALLLIBS += $(EVELIB) +ALLMAPS += $(EVEMAP) + +# include all dependency files +INCLUDEFILES += $(EVEDEP) + +##### local rules ##### +include/%.h: $(EVEDIRI)/%.h + cp $< $@ + +$(EVELIB): $(EVEO) $(EVEDO) $(ORDER_) $(MAINLIBS) $(EVELIBDEP) + @$(MAKELIB) $(PLATFORM) $(LD) "$(LDFLAGS)" \ + "$(SOFLAGS)" libEve.$(SOEXT) $@ "$(EVEO) $(EVEDO)" \ + "$(EVELIBEXTRA) $(FTGLLIBDIR) $(FTGLLIBS) $(GLLIBS)" + +$(EVEDS): $(EVEH) $(EVEL) $(ROOTCINTTMPEXE) + @echo "Generating dictionary $@..." + $(ROOTCINTTMP) -f $@ -c $(EVEH) $(EVEL) + +$(EVEMAP): $(RLIBMAP) $(MAKEFILEDEP) $(EVEL) + $(RLIBMAP) -o $(EVEMAP) -l $(EVELIB) \ + -d $(EVELIBDEPM) -c $(EVEL) + +all-eve: $(EVELIB) $(EVEMAP) + +clean-eve: + @rm -f $(EVEO) $(EVEDO) + +clean:: clean-eve + +distclean-eve: clean-eve + @rm -f $(EVEDEP) $(EVEDS) $(EVEDH) $(EVELIB) $(EVEMAP) + +distclean:: distclean-eve + +##### extra rules ###### +ifeq ($(ARCH),win32) +$(EVEO) $(EVEDO): CXXFLAGS += $(OPENGLINCDIR:%=-I%) $(FTGLINCDIR:%=-I%) +else +$(EVEO) $(EVEDO): CXXFLAGS += $(OPENGLINCDIR:%=-I%) $(FTGLINCDIR:%=-I%) +endif diff --git a/eve/inc/LinkDef.h b/eve/inc/LinkDef.h new file mode 100644 index 0000000000..ddbaf3b55b --- /dev/null +++ b/eve/inc/LinkDef.h @@ -0,0 +1,187 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#pragma link off all functions; +#pragma link off all globals; +#pragma link off all classes; + + +// Utilities +#pragma link C++ class TEveUtil+; +#pragma link C++ class TEveGLUtil+; + +// TEveManager +#pragma link C++ class TEveManager+; +#pragma link C++ global gEve; + +// Basic helper classes +#pragma link C++ class TEveException+; +#pragma link C++ class TEvePadHolder+; +#pragma link C++ class TEveGeoManagerHolder+; +#pragma link C++ class TEveRefCnt+; +#pragma link C++ class TEveRefBackPtr+; + +// TEveVSD structs +#pragma link C++ class TEveVector+; +#pragma link C++ class TEvePathMark+; +#pragma link C++ class TEveMCTrack+; +#pragma link C++ class TEveHit+; +#pragma link C++ class TEveCluster+; +#pragma link C++ class TEveRecTrack+; +#pragma link C++ class TEveRecKink+; +#pragma link C++ class TEveRecV0+; +#pragma link C++ class TEveMCRecCrossRef+; + +// TEveTrans +#pragma link C++ class TEveTrans-; +#pragma link C++ class TEveTransSubEditor+; +#pragma link C++ class TEveTransEditor+; + +// Stepper +#pragma link C++ class TEveGridStepper+; +#pragma link C++ class TEveGridStepperSubEditor+; +#pragma link C++ class TEveGridStepperEditor+; + +// TEveRGBAPalette +#pragma link C++ class TEveRGBAPalette+; +#pragma link C++ class TEveRGBAPaletteEditor+; +#pragma link C++ class TEveRGBAPaletteSubEditor+; + +// Plexes +#pragma link C++ class TEveChunkManager+; +#pragma link C++ class TEveChunkManager::iterator-; + +// TEveEventManager, VSDEvent, TEveVSD +#pragma link C++ class TEveEventManager+; +#pragma link C++ class TEveVSD+; + +// TTreeTools +#pragma link C++ class TEveSelectorToEventList+; +#pragma link C++ class TEvePointSelectorConsumer+; +#pragma link C++ class TEvePointSelector+; + +// TEveElement +#pragma link C++ class TEveElement+; +#pragma link C++ class TEveElement::TEveListTreeInfo+; +#pragma link C++ class TEveElementObjectPtr+; +#pragma link C++ class TEveElementList+; +#pragma link C++ class TEveElementEditor+; + +#pragma link C++ class std::list; +#pragma link C++ class std::list::iterator; +#pragma link C++ typedef TEveElement::List_t; +#pragma link C++ typedef TEveElement::List_i; + +// GL-interface +#pragma link C++ class TEveScene+; +#pragma link C++ class TEveSceneList+; +#pragma link C++ class TEveSceneInfo+; +#pragma link C++ class TEveViewer+; +#pragma link C++ class TEveViewerList+; + +// TEvePad +#pragma link C++ class TEvePad+; + +// TEveBrowser +#pragma link C++ class TEveGListTreeEditorFrame+; +#pragma link C++ class TEveBrowser+; + +// TEveGedEditor +#pragma link C++ class TEveGedEditor+; + +// TEveMacro +#pragma link C++ class TEveMacro+; + +// RGValuators +#pragma link C++ class TEveGValuatorBase+; +#pragma link C++ class TEveGValuator+; +#pragma link C++ class TEveGDoubleValuator+; +#pragma link C++ class TEveGTriVecValuator+; + +// TEveTrack +#pragma link C++ class TEveTrack+; +#pragma link C++ class TEveTrackGL+; +#pragma link C++ class TEveTrackEditor+; +#pragma link C++ class TEveTrackList+; +#pragma link C++ class TEveTrackListEditor+; +#pragma link C++ class TEveTrackPropagatorSubEditor+; +#pragma link C++ class TEveTrackPropagatorEditor+; +#pragma link C++ class TEveTrackPropagator+; +#pragma link C++ class TEveTrackCounter+; +#pragma link C++ class TEveTrackCounterEditor+; + +// TEvePointSet +#pragma link C++ class TEvePointSet+; +#pragma link C++ class TEvePointSetArray+; +#pragma link C++ class TEvePointSetArrayEditor+; + +// TEveLine +#pragma link C++ class TEveLine+; +#pragma link C++ class TEveLineEditor+; +#pragma link C++ class TEveLineGL+; + +// TEveFrameBox +#pragma link C++ class TEveFrameBox+; +#pragma link C++ class TEveFrameBoxGL+; + +// TEveDigitSet +#pragma link C++ class TEveDigitSet+; +#pragma link C++ class TEveDigitSetEditor+; + +// TEveQuadSet +#pragma link C++ class TEveQuadSet+; +#pragma link C++ class TEveQuadSetGL+; + +// TEveBoxSet +#pragma link C++ class TEveBoxSet+; +#pragma link C++ class TEveBoxSetGL+; + +// GeoNode +#pragma link C++ class TEveGeoNode+; +#pragma link C++ class TEveGeoTopNode+; +#pragma link C++ class TEveGeoNodeEditor+; +#pragma link C++ class TEveGeoTopNodeEditor+; + +#pragma link C++ class TEveGeoShapeExtract+; +#pragma link C++ class TEveGeoShape+; + +// TrianlgeSet +#pragma link C++ class TEveTriangleSet+; +#pragma link C++ class TEveTriangleSetEditor+; +#pragma link C++ class TEveTriangleSetGL+; + +// TEveStraightLineSet +#pragma link C++ class TEveStraightLineSet+; +#pragma link C++ class TEveStraightLineSetGL+; +#pragma link C++ class TEveStraightLineSetEditor+; +#pragma link C++ class TEveStraightLineSetProjected+; + +// Projections / non-linear transformations +#pragma link C++ class TEveProjectable+; +#pragma link C++ class TEveProjected+; +#pragma link C++ class TEveProjection+; +#pragma link C++ class TEveRhoZProjection+; +#pragma link C++ class TEveCircularFishEyeProjection+; + +#pragma link C++ class TEveProjectionManager+; +#pragma link C++ class TEveProjectionManagerEditor+; +#pragma link C++ class TEveProjectionManagerGL+; + +#pragma link C++ class TEveTrackProjected+; +#pragma link C++ class TEveTrackProjectedGL+; +#pragma link C++ class TEveTrackListProjected+; + +#pragma link C++ class TEvePolygonSetProjected+; +#pragma link C++ class TEvePolygonSetProjectedEditor+; +#pragma link C++ class TEvePolygonSetProjectedGL+; + +#pragma link C++ class TEvePointSetProjected+; +#pragma link C++ class TEvePointSetProjectedGL+; diff --git a/eve/inc/TEveBoxSet.h b/eve/inc/TEveBoxSet.h new file mode 100644 index 0000000000..9331c58692 --- /dev/null +++ b/eve/inc/TEveBoxSet.h @@ -0,0 +1,82 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveBoxSet +#define ROOT_TEveBoxSet + +#include + +class TGeoMatrix; +class TRandom; + +class TEveBoxSet: public TEveDigitSet +{ + friend class TEveBoxSetGL; + + TEveBoxSet(const TEveBoxSet&); // Not implemented + TEveBoxSet& operator=(const TEveBoxSet&); // Not implemented + +public: + enum BoxType_e + { + BT_Undef, // unknown-ignored + BT_FreeBox, // arbitrary box: specify 8*(x,y,z) box corners + BT_AABox, // axis-aligned box: specify (x,y,z) and (w, h, d) + BT_AABoxFixedDim // axis-aligned box w/ fixed dimensions: specify (x,y,z) + }; + +protected: + + struct BFreeBox : public DigitBase { Float_t fVertices[24]; }; + + struct BOrigin : public DigitBase { Float_t fA, fB, fC; }; + + struct BAABox : public BOrigin { Float_t fW, fH, fD; }; + + struct BAABoxFixedDim : public BOrigin {}; + +protected: + BoxType_e fBoxType; // Type of rendered box. + + Float_t fDefWidth; // Breadth assigned to first coordinate (A). + Float_t fDefHeight; // Breadth assigned to second coordinate (B). + Float_t fDefDepth; // Breadth assigned to third coordinate (C). + + static Int_t SizeofAtom(BoxType_e bt); + +public: + TEveBoxSet(const Text_t* n="TEveBoxSet", const Text_t* t=""); + virtual ~TEveBoxSet() {} + + void Reset(BoxType_e boxType, Bool_t valIsCol, Int_t chunkSize); + void Reset(); + + void AddBox(const Float_t* verts); + void AddBox(Float_t a, Float_t b, Float_t c, Float_t w, Float_t h, Float_t d); + void AddBox(Float_t a, Float_t b, Float_t c); + + virtual void ComputeBBox(); + // virtual void Paint(Option_t* option = ""); + + void Test(Int_t nboxes); + + Float_t GetDefWidth() const { return fDefWidth; } + Float_t GetDefHeight() const { return fDefHeight; } + Float_t GetDefDepth() const { return fDefDepth; } + + void SetDefWidth(Float_t v) { fDefWidth = v ; } + void SetDefHeight(Float_t v) { fDefHeight = v ; } + void SetDefDepth(Float_t v) { fDefDepth = v ; } + + ClassDef(TEveBoxSet, 1); // Collection of 3D primitives (fixed-size boxes, boxes of different sizes, or arbitrary sexto-epipeds); each primitive can be assigned a signal value and a TRef. +}; + +#endif diff --git a/eve/inc/TEveBoxSetGL.h b/eve/inc/TEveBoxSetGL.h new file mode 100644 index 0000000000..ed2220566a --- /dev/null +++ b/eve/inc/TEveBoxSetGL.h @@ -0,0 +1,55 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveBoxSetGL +#define ROOT_TEveBoxSetGL + +#include +#include + +class TEveBoxSetGL : public TGLObject +{ + TEveBoxSetGL(const TEveBoxSetGL&); // Not implemented + TEveBoxSetGL& operator=(const TEveBoxSetGL&); // Not implemented + +protected: + TEveBoxSet *fM; // Model object. + + mutable UInt_t fBoxDL; // Display-list id for a box atom. + + virtual void DirectDraw(TGLRnrCtx & rnrCtx) const; + + Int_t PrimitiveType() const; + Bool_t SetupColor(const TEveDigitSet::DigitBase& q) const; + void MakeOriginBox(Float_t p[24], Float_t dx, Float_t dy, Float_t dz) const; + void RenderBox(const Float_t p[24]) const; + void MakeDisplayList() const; + +public: + TEveBoxSetGL(); + virtual ~TEveBoxSetGL(); + + virtual Bool_t ShouldDLCache(const TGLRnrCtx & rnrCtx) const; + virtual void DLCacheDrop(); + virtual void DLCachePurge(); + + virtual Bool_t SetModel(TObject* obj, const Option_t* opt=0); + virtual void SetBBox(); + + virtual Bool_t SupportsSecondarySelect() const { return kTRUE; } + virtual void ProcessSelection(TGLRnrCtx & rnrCtx, TGLSelectRecord & rec); + + virtual void Render(TGLRnrCtx & rnrCtx); + + ClassDef(TEveBoxSetGL, 0); // GL-renderer for TEveBoxSet class. +}; + +#endif diff --git a/eve/inc/TEveBrowser.h b/eve/inc/TEveBrowser.h new file mode 100644 index 0000000000..52208c6605 --- /dev/null +++ b/eve/inc/TEveBrowser.h @@ -0,0 +1,93 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ +#ifndef ROOT_TEveBrowser +#define ROOT_TEveBrowser + +#include +#include + +#include + +class TGFileBrowser; +class TGSplitter; + +class TEveGedEditor; + +class TEveGListTreeEditorFrame : public TGMainFrame +{ + TEveGListTreeEditorFrame(const TEveGListTreeEditorFrame&); // Not implemented + TEveGListTreeEditorFrame& operator=(const TEveGListTreeEditorFrame&); // Not implemented + + friend class TEveManager; + +protected: + TGCompositeFrame *fFrame; + TGCompositeFrame *fLTFrame; + + TGCanvas *fLTCanvas; + TGListTree *fListTree; + TGSplitter *fSplitter; + TEveGedEditor *fEditor; + + TContextMenu *fCtxMenu; + + TGListTreeItem *fNewSelected; + + void ResetSelectedTimer(TGListTreeItem* lti); + +public: + TEveGListTreeEditorFrame(const Text_t* name, Int_t width=250, Int_t height=700); + virtual ~TEveGListTreeEditorFrame(); + + void ReconfToHorizontal(); + void ReconfToVertical(); + + TGListTree* GetListTree() { return fListTree; } + + void ItemChecked(TObject* obj, Bool_t state); + void ItemClicked(TGListTreeItem *entry, Int_t btn, Int_t x, Int_t y); + void ItemDblClicked(TGListTreeItem* item, Int_t btn); + void ItemKeyPress(TGListTreeItem *entry, UInt_t keysym, UInt_t mask); + + void ResetSelected(); + + ClassDef(TEveGListTreeEditorFrame, 0); // Composite GUI frame for parallel display of a TGListTree and TEveGedEditor. +}; + +// ---------------------------------------------------------------- + +class TEveBrowser : public TRootBrowser +{ + TEveBrowser(const TEveBrowser&); // Not implemented + TEveBrowser& operator=(const TEveBrowser&); // Not implemented + +protected: + void SetupCintExport(TClass* cl); + void CalculateReparentXY(TGObject* parent, Int_t& x, Int_t& y); + + TGFileBrowser *fFileBrowser; + TGPopupMenu *fRevePopup; + + public: + TEveBrowser(UInt_t w, UInt_t h); + virtual ~TEveBrowser() {} + + void InitPlugins(); + + TGFileBrowser* MakeFileBrowser(); + TGFileBrowser* GetFileBrowser() const { return fFileBrowser; } + + void ReveMenu(Int_t id); + + ClassDef(TEveBrowser, 0); // Specialization of TRootBrowser for Reve. +}; + +#endif diff --git a/eve/inc/TEveChunkManager.h b/eve/inc/TEveChunkManager.h new file mode 100644 index 0000000000..d1f34e47ed --- /dev/null +++ b/eve/inc/TEveChunkManager.h @@ -0,0 +1,149 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveChunkManager +#define ROOT_TEveChunkManager + +#include + +#include +#include + +#include + + +/******************************************************************************/ +// TEveChunkManager +/******************************************************************************/ + +class TEveChunkManager +{ +private: + TEveChunkManager(const TEveChunkManager&); // Not implemented + TEveChunkManager& operator=(const TEveChunkManager&); // Not implemented + +protected: + Int_t fS; // Size of atom + Int_t fN; // Number of atoms in a chunk + + Int_t fSize; // Size of container, number of atoms + Int_t fVecSize; // Number of allocated chunks + Int_t fCapacity; // Available capacity within the chunks + + std::vector fChunks; // Memory blocks + + void ReleaseChunks(); + +public: + TEveChunkManager(); + TEveChunkManager(Int_t atom_size, Int_t chunk_size); + virtual ~TEveChunkManager(); + + void Reset(Int_t atom_size, Int_t chunk_size); + void Refit(); + + Int_t S() const { return fS; } + Int_t N() const { return fN; } + + Int_t Size() const { return fSize; } + Int_t VecSize() const { return fVecSize; } + Int_t Capacity() const { return fCapacity; } + + Char_t* Atom(Int_t idx) const { return fChunks[idx/fN]->fArray + idx%fN*fS; } + Char_t* Chunk(Int_t chk) const { return fChunks[chk]->fArray; } + Int_t NAtoms(Int_t chk) const { return (chk < fVecSize-1) ? fN : (fSize-1)%fN + 1; } + + Char_t* NewAtom(); + Char_t* NewChunk(); + + + // Iterator + + struct iterator + { + TEveChunkManager *fPlex; + Char_t *fCurrent; + Int_t fAtomIndex; + Int_t fNextChunk; + Int_t fAtomsToGo; + + iterator(TEveChunkManager* p) : + fPlex(p), fCurrent(0), fAtomIndex(-1), fNextChunk(0), fAtomsToGo(0) {} + iterator(TEveChunkManager& p) : + fPlex(&p), fCurrent(0), fAtomIndex(-1), fNextChunk(0), fAtomsToGo(0) {} + + Bool_t next(); + void reset() { fCurrent = 0; fNextChunk = fAtomsToGo = 0; } + + Char_t* operator()() { return fCurrent; } + Char_t* operator*() { return fCurrent; } + Int_t index() { return fAtomIndex; } + }; + + ClassDef(TEveChunkManager, 1); // Vector-like container with chunked memory allocation. +}; + + +/******************************************************************************/ + +//______________________________________________________________________________ +inline Char_t* TEveChunkManager::NewAtom() +{ + Char_t *a = (fSize >= fCapacity) ? NewChunk() : Atom(fSize); + ++fSize; + return a; +} + +//______________________________________________________________________________ +inline Bool_t TEveChunkManager::iterator::next() +{ + if (fAtomsToGo <= 0) { + if (fNextChunk < fPlex->fVecSize) { + fCurrent = fPlex->Chunk(fNextChunk); + fAtomsToGo = fPlex->NAtoms(fNextChunk); + ++fNextChunk; + } else { + return kFALSE; + } + } else { + fCurrent += fPlex->fS; + } + ++fAtomIndex; + --fAtomsToGo; + return kTRUE; +} + + +/******************************************************************************/ +// Templated some-class TEveChunkVector +/******************************************************************************/ + +template +class TEveChunkVector : public TEveChunkManager +{ +private: + TEveChunkVector(const TEveChunkVector&); // Not implemented + TEveChunkVector& operator=(const TEveChunkVector&); // Not implemented + +public: + TEveChunkVector() : TEveChunkManager() {} + TEveChunkVector(Int_t chunk_size) : TEveChunkManager(sizeof(T), chunk_size) {} + virtual ~TEveChunkVector() {} + + void Reset(Int_t chunk_size) { Reset(sizeof(T), chunk_size); } + + T* At(Int_t idx) { return reinterpret_cast(Atom(idx)); } + T& Ref(Int_t idx) { return *At(idx); } + + ClassDef(TEveChunkVector, 1); // Templated class for specific atom classes (given as template argument). +}; + +#endif diff --git a/eve/inc/TEveDigitSet.h b/eve/inc/TEveDigitSet.h new file mode 100644 index 0000000000..19e39861bc --- /dev/null +++ b/eve/inc/TEveDigitSet.h @@ -0,0 +1,137 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveDigitSet +#define ROOT_TEveDigitSet + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +class TEveDigitSet : public TEveElement, + public TNamed, public TQObject, + public TAtt3D, + public TAttBBox +{ + friend class TEveDigitSetEditor; + + TEveDigitSet(const TEveDigitSet&); // Not implemented + TEveDigitSet& operator=(const TEveDigitSet&); // Not implemented + +public: + enum RenderMode_e { RM_AsIs, RM_TEveLine, RM_Fill }; + +protected: + struct DigitBase + { + // Base-class for digit representation classes. + + Int_t fValue; // signal value of a digit (can be direct RGBA color) + TRef fId; // external object reference + + DigitBase(Int_t v=0) : fValue(v), fId() {} + }; + + Int_t fDefaultValue; // Default signal value. + Bool_t fValueIsColor; // Interpret signal value as RGBA color. + Bool_t fOwnIds; // Flag specifying if id-objects are owned by the TEveDigitSet + TEveChunkManager fPlex; // Container of digit data. + DigitBase* fLastDigit; //! The last digit added to collection. + + TEveFrameBox* fFrame; // Pointer to frame structure. + TEveRGBAPalette* fPalette; // Pointer to signal-color palette. + RenderMode_e fRenderMode; // Render mode: as-is / line / filled. + Bool_t fDisableLigting; // Disable lighting for rendering. + Bool_t fEmitSignals; // Emit signals on secondary-select. + Bool_t fHistoButtons; // Show histogram buttons in object editor. + TEveTrans fHMTrans; // Overall transformation of whole collection. + + DigitBase* NewDigit(); + void ReleaseIds(); + +public: + TEveDigitSet(const Text_t* n="TEveDigitSet", const Text_t* t=""); + virtual ~TEveDigitSet(); + + virtual Bool_t CanEditMainColor() { return kTRUE; } + virtual void SetMainColor(Color_t color); + + // Implemented in sub-classes: + // virtual void Reset(QuadType_e quadType, Bool_t valIsCol, Int_t chunkSize); + + void RefitPlex(); + void ScanMinMaxValues(Int_t& min, Int_t& max); + + // -------------------------------- + + void DigitValue(Int_t value); + void DigitColor(Color_t ci); + void DigitColor(UChar_t r, UChar_t g, UChar_t b, UChar_t a=255); + void DigitColor(UChar_t* rgba); + + void DigitId(TObject* id); + + Bool_t GetOwnIds() const { return fOwnIds; } + void SetOwnIds(Bool_t o) { fOwnIds = o; } + + DigitBase* GetDigit(Int_t n) { return (DigitBase*) fPlex.Atom(n); } + TObject* GetId(Int_t n) { return GetDigit(n)->fId.GetObject(); } + + // -------------------------------- + + // Implemented in subclasses: + // virtual void ComputeBBox(); + + virtual void Paint(Option_t* option=""); + + virtual void DigitSelected(Int_t idx); + virtual void CtrlClicked(TEveDigitSet* qs, Int_t idx); // *SIGNAL* + + // -------------------------------- + + TEveChunkManager* GetPlex() { return &fPlex; } + + TEveFrameBox* GetFrame() const { return fFrame; } + void SetFrame(TEveFrameBox* b); + + Bool_t GetValueIsColor() const { return fValueIsColor; } + + TEveRGBAPalette* GetPalette() const { return fPalette; } + void SetPalette(TEveRGBAPalette* p); + TEveRGBAPalette* AssertPalette(); + + RenderMode_e GetRenderMode() const { return fRenderMode; } + void SetRenderMode(RenderMode_e rm) { fRenderMode = rm; } + + Bool_t GetEmitSignals() const { return fEmitSignals; } + void SetEmitSignals(Bool_t f) { fEmitSignals = f; } + + Bool_t GetHistoButtons() const { return fHistoButtons; } + void SetHistoButtons(Bool_t f) { fHistoButtons = f; } + + TEveTrans& RefHMTrans() { return fHMTrans; } + void SetTransMatrix(Double_t* carr) { fHMTrans.SetFrom(carr); } + void SetTransMatrix(const TGeoMatrix& mat) { fHMTrans.SetFrom(mat); } + + ClassDef(TEveDigitSet, 1); // Base-class for storage of digit collections; provides transformation matrix (TEveTrans), signal to color mapping (TEveRGBAPalette) and visual grouping (TEveFrameBox). +}; + +#endif diff --git a/eve/inc/TEveDigitSetEditor.h b/eve/inc/TEveDigitSetEditor.h new file mode 100644 index 0000000000..3a8f4f0f3f --- /dev/null +++ b/eve/inc/TEveDigitSetEditor.h @@ -0,0 +1,62 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveDigitSetEditor +#define ROOT_TEveDigitSetEditor + +#include + +class TGCheckButton; +class TGNumberEntry; +class TGColorSelect; + +class TEveDigitSet; + +class TEveGValuator; +class TEveGDoubleValuator; +class TEveTransSubEditor; + +// It would be also good to have button to change model to the palette +// object itself. +class TEveRGBAPaletteSubEditor; + +class TEveDigitSetEditor : public TGedFrame +{ +private: + TEveDigitSetEditor(const TEveDigitSetEditor&); // Not implemented + TEveDigitSetEditor& operator=(const TEveDigitSetEditor&); // Not implemented + + void CreateInfoTab(); +protected: + TEveDigitSet *fM; // Model object. + + TEveTransSubEditor *fHMTrans; // TEveTrans sub-editor. + TEveRGBAPaletteSubEditor *fPalette; // Palette sub-editor. + + TGHorizontalFrame *fHistoButtFrame; // Frame holding histogram display buttons. + TGVerticalFrame *fInfoFrame; // Frame displaying basic digit statistics. + +public: + TEveDigitSetEditor(const TGWindow* p=0, Int_t width=170, Int_t height=30, + UInt_t options = kChildFrame, Pixel_t back=GetDefaultFrameBackground()); + virtual ~TEveDigitSetEditor(); + + virtual void SetModel(TObject* obj); + + // Declare callback/slot methods + void DoHisto(); + void DoRangeHisto(); + void PlotHisto(Int_t min, Int_t max); + + ClassDef(TEveDigitSetEditor, 1); // Editor for TEveDigitSet class. +}; + +#endif diff --git a/eve/inc/TEveElement.h b/eve/inc/TEveElement.h new file mode 100644 index 0000000000..3ad053143d --- /dev/null +++ b/eve/inc/TEveElement.h @@ -0,0 +1,258 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveElement +#define ROOT_TEveElement + +#include + +#include +#include + +class TGListTree; +class TGListTreeItem; +class TGPicture; + +class TEveTrans; + +/******************************************************************************/ +// TEveElement +/******************************************************************************/ + +class TEveElement +{ + friend class TEveManager; + + TEveElement(const TEveElement&); // Not implemented + TEveElement& operator=(const TEveElement&); // Not implemented + +public: + class TEveListTreeInfo + { + public: + TGListTree* fTree; + TGListTreeItem* fItem; + + TEveListTreeInfo() : fTree(0), fItem(0) {} + TEveListTreeInfo(TGListTree* lt, TGListTreeItem* lti) : fTree(lt), fItem(lti) {} + TEveListTreeInfo(const TEveListTreeInfo& l) : fTree(l.fTree), fItem(l.fItem) {} + virtual ~TEveListTreeInfo() {} + + TEveListTreeInfo& operator=(const TEveListTreeInfo& l) + { fTree = l.fTree; fItem = l.fItem; return *this; } + + bool operator==(const TEveListTreeInfo& x) const + { return fTree == x.fTree && fItem == x.fItem; } + bool operator<(const TEveListTreeInfo& x) const + { return fTree == x.fTree ? fItem < x.fItem : fTree < x.fTree; } + + ClassDef(TEveListTreeInfo, 0); // Structure agregating data for a render element image in a list tree. + }; + + static const TGPicture* fgRnrIcons[4]; + static const TGPicture* fgListTreeIcons[8]; + + typedef std::set sLTI_t; + typedef sLTI_t::iterator sLTI_i; + typedef sLTI_t::reverse_iterator sLTI_ri; + + typedef std::list List_t; + typedef std::list::iterator List_i; + +protected: + // TRef fSource; + + Bool_t fRnrSelf; // Render this element. + Bool_t fRnrChildren; // Render children of this element. + Color_t* fMainColorPtr; // Pointer to main-color variable. + + sLTI_t fItems; // Set of list-tree-items. + List_t fParents; // List of parents. + + Bool_t fDestroyOnZeroRefCnt; // Auto-destruct when ref-count reaches zero. + Int_t fDenyDestroy; // Deny-destroy count. + + List_t fChildren; // List of children. + +public: + TEveElement(); + TEveElement(Color_t& main_color); + virtual ~TEveElement(); + + virtual void SetRnrElNameTitle(const Text_t* name, const Text_t* title); + virtual const Text_t* GetRnrElName() const; + virtual const Text_t* GetRnrElTitle() const; + + virtual void AddParent(TEveElement* re); + virtual void RemoveParent(TEveElement* re); + virtual void CheckReferenceCount(const TEveException& eh="TEveElement::CheckReferenceCount "); + virtual void CollectSceneParents(List_t& scenes); + virtual void CollectSceneParentsFromChildren(List_t& scenes, TEveElement* parent); + + List_i BeginParents() { return fParents.begin(); } + List_i EndParents() { return fParents.end(); } + Int_t GetNParents() const { return fParents.size(); } + + List_i BeginChildren() { return fChildren.begin(); } + List_i EndChildren() { return fChildren.end(); } + Int_t GetNChildren() const { return fChildren.size(); } + + void EnableListElements (Bool_t rnr_self=kTRUE, Bool_t rnr_children=kTRUE); // *MENU* + void DisableListElements(Bool_t rnr_self=kFALSE, Bool_t rnr_children=kFALSE); // *MENU* + + Bool_t GetDestroyOnZeroRefCnt() const { return fDestroyOnZeroRefCnt; } + void SetDestroyOnZeroRefCnt(Bool_t d) { fDestroyOnZeroRefCnt = d; } + + Int_t GetDenyDestroy() const { return fDenyDestroy; } + void IncDenyDestroy() { ++fDenyDestroy; } + void DecDenyDestroy() { if (--fDenyDestroy <= 0) CheckReferenceCount("TEveElement::DecDenyDestroy "); } + + virtual void PadPaint(Option_t* option); + + virtual TObject* GetObject(TEveException eh="TEveElement::GetObject ") const; + virtual TObject* GetEditorObject() const { return GetObject(); } + /* + TRef& GetSource() { return fSource; } + TObject* GetSourceObject() const { return fSource.GetObject(); } + void SetSourceObject(TObject* o) { fSource.SetObject(o); } + + void DumpSourceObject(); // *MENU* + void InspectSourceObject(); // *MENU* + */ + + // -------------------------------- + + virtual Int_t ExpandIntoListTree(TGListTree* ltree, TGListTreeItem* parent); + virtual Int_t DestroyListSubTree(TGListTree* ltree, TGListTreeItem* parent); + + virtual TGListTreeItem* AddIntoListTree(TGListTree* ltree, + TGListTreeItem* parent_lti); + virtual TGListTreeItem* AddIntoListTree(TGListTree* ltree, + TEveElement* parent); + virtual TGListTreeItem* AddIntoListTrees(TEveElement* parent); + + virtual Bool_t RemoveFromListTree(TGListTree* ltree, + TGListTreeItem* parent_lti); + virtual Int_t RemoveFromListTrees(TEveElement* parent); + + virtual sLTI_i FindItem(TGListTree* ltree); + virtual sLTI_i FindItem(TGListTree* ltree, + TGListTreeItem* parent_lti); + virtual TGListTreeItem* FindListTreeItem(TGListTree* ltree); + virtual TGListTreeItem* FindListTreeItem(TGListTree* ltree, + TGListTreeItem* parent_lti); + + virtual Int_t GetNItems() const { return fItems.size(); } + virtual void UpdateItems(); + + void SpawnEditor(); // *MENU* + virtual void ExportToCINT(Text_t* var_name); // *MENU* + + virtual Bool_t AcceptElement(TEveElement* /*el*/) { return kTRUE; } + + virtual TGListTreeItem* AddElement(TEveElement* el); + virtual void RemoveElement(TEveElement* el); + virtual void RemoveElementLocal(TEveElement* el); + virtual void RemoveElements(); + virtual void RemoveElementsLocal(); + + virtual void Destroy(); // *MENU* + virtual void DestroyElements(); // *MENU* + + virtual Bool_t HandleElementPaste(TEveElement* el); + virtual void ElementChanged(Bool_t update_scenes=kTRUE, Bool_t redraw=kFALSE); + + virtual Bool_t CanEditRnrElement() { return kTRUE; } + virtual Bool_t GetRnrSelf() const { return fRnrSelf; } + virtual Bool_t GetRnrChildren() const { return fRnrChildren; } + virtual void SetRnrSelf(Bool_t rnr); + virtual void SetRnrChildren(Bool_t rnr); + virtual void SetRnrState(Bool_t rnr); + + virtual Bool_t CanEditMainColor() { return kFALSE; } + Color_t* GetMainColorPtr() { return fMainColorPtr; } + void SetMainColorPtr(Color_t* color) { fMainColorPtr = color; } + + virtual Color_t GetMainColor() const { return fMainColorPtr ? *fMainColorPtr : 0; } + virtual void SetMainColor(Color_t color); + void SetMainColor(Pixel_t pixel); + + virtual Bool_t CanEditMainTransparency() { return kFALSE; } + virtual UChar_t GetMainTransparency() const { return 0; } + virtual void SetMainTransparency(UChar_t) {} + + virtual Bool_t CanEditMainHMTrans() { return kFALSE; } + virtual TEveTrans* PtrMainHMTrans() { return 0; } + + static const TGPicture* GetCheckBoxPicture(Bool_t rnrElement, Bool_t rnrDaughter); + virtual const TGPicture* GetListTreeIcon() { return fgListTreeIcons[0]; } + + ClassDef(TEveElement, 1); // Base class for TEveUtil visualization elements, providing hierarchy management, rendering control and list-tree item management. +}; + + +/******************************************************************************/ +// TEveElementObjectPtr +/******************************************************************************/ + +class TEveElementObjectPtr : public TEveElement, + public TObject +{ + TEveElementObjectPtr(const TEveElementObjectPtr&); // Not implemented + TEveElementObjectPtr& operator=(const TEveElementObjectPtr&); // Not implemented + +protected: + TObject* fObject; // External object holding the visual data. + Bool_t fOwnObject; // Is object owned / should be deleted on destruction. + +public: + TEveElementObjectPtr(TObject* obj, Bool_t own=kTRUE); + TEveElementObjectPtr(TObject* obj, Color_t& mainColor, Bool_t own=kTRUE); + virtual ~TEveElementObjectPtr(); + + virtual TObject* GetObject(TEveException eh="TEveElementObjectPtr::GetObject ") const; + virtual void ExportToCINT(Text_t* var_name); + + Bool_t GetOwnObject() const { return fOwnObject; } + void SetOwnObject(Bool_t o) { fOwnObject = o; } + + ClassDef(TEveElementObjectPtr, 1); // TEveElement with external TObject as a holder of visualization data. +}; + + +/******************************************************************************/ +// TEveElementList +/******************************************************************************/ + +class TEveElementList : public TEveElement, + public TNamed +{ +protected: + Color_t fColor; // Color of the object. + Bool_t fDoColor; // Should serve fColor as the main color of the object. + TClass *fChildClass; // Class of acceptable children, others are rejected. + +public: + TEveElementList(const Text_t* n="TEveElementList", const Text_t* t="", + Bool_t doColor=kFALSE); + virtual ~TEveElementList() {} + + virtual Bool_t CanEditMainColor() { return fDoColor; } + + TClass* GetChildClass() const { return fChildClass; } + void SetChildClass(TClass* c) { fChildClass = c; } + + virtual Bool_t AcceptElement(TEveElement* el); + + ClassDef(TEveElementList, 1); // List of TEveElement objects with a possibility to limit the class of accepted elements. +}; + +#endif diff --git a/eve/inc/TEveElementEditor.h b/eve/inc/TEveElementEditor.h new file mode 100644 index 0000000000..9666bdd381 --- /dev/null +++ b/eve/inc/TEveElementEditor.h @@ -0,0 +1,54 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveElementEditor +#define ROOT_TEveElementEditor + +#include + +class TGCheckButton; +class TGNumberEntry; +class TGColorSelect; + +class TEveElement; +class TEveTransSubEditor; + +class TEveElementEditor : public TGedFrame +{ + TEveElementEditor(const TEveElementEditor&); // Not implemented + TEveElementEditor& operator=(const TEveElementEditor&); // Not implemented + +protected: + TEveElement *fRE; // Model object. + + TGHorizontalFrame *fHFrame; + TGCheckButton *fRnrSelf; + TGCheckButton *fRnrChildren; + TGColorSelect *fMainColor; + TGNumberEntry *fTransparency; + TEveTransSubEditor *fHMTrans; + +public: + TEveElementEditor(const TGWindow* p=0, Int_t width=170, Int_t height=30, + UInt_t options=kChildFrame, Pixel_t back=GetDefaultFrameBackground()); + ~TEveElementEditor(); + + virtual void SetModel(TObject* obj); + + void DoRnrSelf(); + void DoRnrChildren(); + void DoMainColor(Pixel_t color); + void DoTransparency(); + + ClassDef(TEveElementEditor, 1); // Editor for TEveElement class. +}; + +#endif diff --git a/eve/inc/TEveEventManager.h b/eve/inc/TEveEventManager.h new file mode 100644 index 0000000000..736e04c0dc --- /dev/null +++ b/eve/inc/TEveEventManager.h @@ -0,0 +1,41 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveEventManager +#define ROOT_TEveEventManager + +#include +#include + +class TEveEventManager : public TEveElementList +{ +protected: + TList fNewEventCommands; + +public: + TEveEventManager(const Text_t* n="TEveEventManager", const Text_t* t=""); + virtual ~TEveEventManager() {} + + TList& GetNewEventCommands() { return fNewEventCommands; } + + virtual void Open() {} + virtual void GotoEvent(Int_t /*event*/) {} + virtual void NextEvent() {} + virtual void PrevEvent() {} + virtual void Close() {} + + virtual void AfterNewEventLoaded(); + virtual void AddNewEventCommand(const Text_t* cmd); + + ClassDef(TEveEventManager, 1); // Base class for event management and navigation. +}; + +#endif diff --git a/eve/inc/TEveFrameBox.h b/eve/inc/TEveFrameBox.h new file mode 100644 index 0000000000..658f2e630a --- /dev/null +++ b/eve/inc/TEveFrameBox.h @@ -0,0 +1,89 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveFrameBox +#define ROOT_TEveFrameBox + +#include +#include + +class TEveFrameBox : public TObject, public TEveRefBackPtr +{ + friend class TEveFrameBoxGL; + +public: + enum FrameType_e { FT_None, FT_Quad, FT_Box }; + +private: + TEveFrameBox(const TEveFrameBox&); // Not implemented + TEveFrameBox& operator=(const TEveFrameBox&); // Not implemented + +protected: + FrameType_e fFrameType; + Int_t fFrameSize; + Float_t *fFramePoints; //[fFrameSize] + + Float_t fFrameWidth; + Color_t fFrameColor; + Color_t fBackColor; + UChar_t fFrameRGBA[4]; + UChar_t fBackRGBA[4]; + Bool_t fFrameFill; + Bool_t fDrawBack; + +public: + TEveFrameBox(); + virtual ~TEveFrameBox(); + + void SetAAQuadXY(Float_t x, Float_t y, Float_t z, Float_t dx, Float_t dy); + void SetAAQuadXZ(Float_t x, Float_t y, Float_t z, Float_t dx, Float_t dz); + + void SetAABox(Float_t x, Float_t y, Float_t z, + Float_t dx, Float_t dy, Float_t dz); + + void SetAABoxCenterHalfSize(Float_t x, Float_t y, Float_t z, + Float_t dx, Float_t dy, Float_t dz); + + // ---------------------------------------------------------------- + + FrameType_e GetFrameType() const { return fFrameType; } + Int_t GetFrameSize() const { return fFrameSize; } + Float_t* GetFramePoints() const { return fFramePoints; } + + Float_t GetFrameWidth() const { return fFrameWidth; } + void SetFrameWidth(Float_t f) { fFrameWidth = f; } + + Color_t GetFrameColor() const { return fFrameColor; } + Color_t* PtrFrameColor() { return &fFrameColor; } + UChar_t* GetFrameRGBA() { return fFrameRGBA; } + + void SetFrameColor(Color_t ci); + void SetFrameColor(Pixel_t pix); + void SetFrameColor(UChar_t r, UChar_t g, UChar_t b, UChar_t a=255); + + Color_t GetBackColor() const { return fBackColor; } + Color_t* PtrBackColor() { return &fBackColor; } + UChar_t* GetBackRGBA() { return fBackRGBA; } + + void SetBackColor(Color_t ci); + void SetBackColor(Pixel_t pix); + void SetBackColor(UChar_t r, UChar_t g, UChar_t b, UChar_t a=255); + + Bool_t GetFrameFill() const { return fFrameFill; } + void SetFrameFill(Bool_t f) { fFrameFill = f; } + + Bool_t GetDrawBack() const { return fDrawBack; } + void SetDrawBack(Bool_t f) { fDrawBack = f; } + + ClassDef(TEveFrameBox, 1); // Description of a 2D or 3D frame that can be used to visually group a set of objects. +}; + +#endif diff --git a/eve/inc/TEveFrameBoxGL.h b/eve/inc/TEveFrameBoxGL.h new file mode 100644 index 0000000000..6d8ba3843f --- /dev/null +++ b/eve/inc/TEveFrameBoxGL.h @@ -0,0 +1,36 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveFrameBoxGL +#define ROOT_TEveFrameBoxGL + +#include + +class TEveFrameBox; + +class TEveFrameBoxGL +{ +private: + TEveFrameBoxGL(); // Not implemented + TEveFrameBoxGL(const TEveFrameBoxGL&); // Not implemented + TEveFrameBoxGL& operator=(const TEveFrameBoxGL&); // Not implemented + + static void RenderFrame(const TEveFrameBox& b, Bool_t fillp); + +public: + virtual ~TEveFrameBoxGL() {} + + static void Render(const TEveFrameBox* box); + + ClassDef(TEveFrameBoxGL, 0); // GL-renderer for TEveFrameBox class. +}; + +#endif diff --git a/eve/inc/TEveGLText.h b/eve/inc/TEveGLText.h new file mode 100644 index 0000000000..e5d2349ea2 --- /dev/null +++ b/eve/inc/TEveGLText.h @@ -0,0 +1,159 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveGLText +#define ROOT_TEveGLText + +// The following implementation is based on TexFont API, +// implementation and accompanying programs by Mark J. Kilgard. +// Original license: + +/* Copyright (c) Mark J. Kilgard, 1997. */ +/* This program is freely distributable without licensing fees and is + provided without guarantee or warrantee expressed or implied. This + program is -not- in the public domain. */ + +#ifndef __CINT__ + +#include +#include + +class TString; + +namespace TEveGLText { + +#define TXF_FORMAT_BYTE 0 +#define TXF_FORMAT_BITMAP 1 + +struct TexGlyphInfo { + unsigned short c; /* Potentially support 16-bit glyphs. */ + unsigned char width; + unsigned char height; + signed char xoffset; + signed char yoffset; + signed char advance; + char dummy; /* Space holder for alignment reasons. */ + short x; + short y; +}; + +struct TexGlyphVertexInfo { + GLfloat t0[2]; + GLshort v0[2]; + GLfloat t1[2]; + GLshort v1[2]; + GLfloat t2[2]; + GLshort v2[2]; + GLfloat t3[2]; + GLshort v3[2]; + GLfloat advance; +}; + +class TexFont : public TObject { +public: + GLuint texobj; + int tex_width; + int tex_height; + int max_ascent; + int max_descent; + int max_width; // max glyph width (MT) + int num_glyphs; + int min_glyph; + int range; + unsigned char *teximage; + TexGlyphInfo *tgi; + TexGlyphVertexInfo *tgvi; + TexGlyphVertexInfo **lut; + + int max_height() { return max_ascent + max_descent; } +}; + + +extern const char *txfErrorString(void); + +extern TexFont *txfLoadFont(const char *filename); + +extern void txfUnloadFont(TexFont* txf); + +extern GLuint txfEstablishTexture(TexFont* txf, GLuint texobj, + GLboolean setupMipmaps); + +extern void txfBindFontTexture(TexFont* txf); + +extern void txfGetStringMetrics(TexFont* txf, const char *TString, int len, + int &width, int &max_ascent, int &max_descent); + +extern void txfRenderGlyph(TexFont* txf, int c); +extern void txfRenderString(TexFont* txf, const char *TString, int len, + bool keep_pos=true); +extern void txfRenderString(TexFont* txf, const char *TString, int len, + GLfloat maxx, GLfloat fadew, + bool keep_pos=true); + +extern void txfRenderGlyphZW(TexFont* txf, int c, float z, float w); +extern void txfRenderStringZW(TexFont* txf, const char *TString, int len, + float z, float w, bool keep_pos=true); + +extern void txfRenderFancyString(TexFont* txf, char *TString, int len); + + +bool LoadDefaultFont(TString font_file); + +extern TexFont* fgDefaultFont; + +/******************************************************************************/ +// Here starts MT higher-level interface +/******************************************************************************/ +/* + struct BoxSpecs { + int lm, rm, tm, bm; + int lineskip; + char align; + TString pos; + + void _init() { align = 'l'; lineskip = 0; } + + BoxSpecs() + { lm = rm = 3; tm = 0; bm = 2; _init(); } + + BoxSpecs(int lr, int tb) + { lm = rm = lr; tm = bm = tb; _init(); } + + BoxSpecs(int l, int r, int t, int b) + { lm = l; rm = r; tm = t; bm = b; _init(); } + }; + struct TextLineData { + int width, ascent, descent, hfull; + TString text; + + TextLineData(TexFont *txf, TString line); + }; + + extern void RnrTextBar(RnrDriver* rd, const TString& text); + + extern void RnrTextBar(RnrDriver* rd, const TString& text, + BoxSpecs& bs, float zoffset=0); + + extern void RnrTextPoly(RnrDriver* rd, const TString& text); + + extern void RnrText(RnrDriver* rd, const TString& text, + int x, int y, float z, + const ZColor* front_col, const ZColor* back_col=0); + + extern void RnrTextAt(RnrDriver* rd, const TString& text, + int x, int yrow, float z, + const ZColor* front_col, const ZColor* back_col=0); +*/ + +} // namescape TEveGLText + +#endif // cint +#endif // Reve_GLTextNS_H diff --git a/eve/inc/TEveGLUtil.h b/eve/inc/TEveGLUtil.h new file mode 100644 index 0000000000..01ad82887f --- /dev/null +++ b/eve/inc/TEveGLUtil.h @@ -0,0 +1,91 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef Reve_TEveGLUtil +#define Reve_TEveGLUtil + +#ifndef __CINT__ +#include +#endif + +#include + +class TAttMarker; +class TAttLine; + +class TEveGLUtil +{ +public: + virtual ~TEveGLUtil() {} + +#ifndef __CINT__ + + class GL_Capability_Switch { + GLenum fWhat; + GLboolean fState; + bool fFlip; + + void set_state(GLboolean s) + { if(s) glEnable(fWhat); else glDisable(fWhat); } + + public: + GL_Capability_Switch(GLenum what, GLboolean state) : + fWhat(what), fState(kFALSE), fFlip(kFALSE) + { + fState = glIsEnabled(fWhat); + fFlip = (fState != state); + if(fFlip) set_state(state); + } + ~GL_Capability_Switch() + { if(fFlip) set_state(fState); } + }; + + class GL_Float_Holder + { + GL_Float_Holder(const GL_Float_Holder&); // Not implemented + GL_Float_Holder& operator=(const GL_Float_Holder&); // Not implemented + + GLenum fWhat; + GLfloat fState; + bool fFlip; + void (*fFoo)(GLfloat); + + public: + GL_Float_Holder(GLenum what, GLfloat state, void (*foo)(GLfloat)) : + fWhat(what), fState(kFALSE), fFlip(kFALSE), fFoo(foo) + { + glGetFloatv(fWhat, &fState); + fFlip = (fState != state); + if(fFlip) fFoo(state); + } + ~GL_Float_Holder() + { if(fFlip) fFoo(fState); } + }; + +#endif + + // Commonly used rendering primitives. + + static void RenderLine(const TAttLine& al, Float_t* p, Int_t n, + Bool_t selection=kFALSE, Bool_t sec_selection=kFALSE); + + static void RenderPolyMarkers(const TAttMarker& marker, Float_t* p, Int_t n, + Bool_t selection=kFALSE, Bool_t sec_selection=kFALSE); + + static void RenderPoints(const TAttMarker& marker, Float_t* p, Int_t n, + Bool_t selection=kFALSE, Bool_t sec_selection=kFALSE); + + static void RenderCrosses(const TAttMarker& marker, Float_t* p, Int_t n, Bool_t sec_selection=kFALSE); + + ClassDef(TEveGLUtil, 0); // Commonly used utilities for GL rendering. +}; + +#endif diff --git a/eve/inc/TEveGValuators.h b/eve/inc/TEveGValuators.h new file mode 100644 index 0000000000..ea30ff396c --- /dev/null +++ b/eve/inc/TEveGValuators.h @@ -0,0 +1,200 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveGValuators +#define ROOT_TEveGValuators + +#include + +class TGLabel; +class TGHSlider; +class TGDoubleHSlider; + +class TEveGValuatorBase: public TGCompositeFrame +{ + TEveGValuatorBase(const TEveGValuatorBase&); // Not implemented + TEveGValuatorBase& operator=(const TEveGValuatorBase&); // Not implemented + +protected: + UInt_t fLabelWidth; + Bool_t fAlignRight; + Bool_t fShowSlider; + + Int_t fNELength; // Number-entry length (in characters) + Int_t fNEHeight; // Number-entry height (in pixels) + + TGLabel* fLabel; + +public: + TEveGValuatorBase(const TGWindow *p, const char* title, UInt_t w, UInt_t h); + virtual ~TEveGValuatorBase() {} + + virtual void Build(Bool_t connect=kTRUE) = 0; + + void SetLabelWidth(Int_t w) { fLabelWidth = w; } + void SetAlignRight(Bool_t a) { fAlignRight = a; } + void SetShowSlider(Bool_t s=kTRUE) { fShowSlider = s; } + + void SetNELength(Int_t l) { fNELength = l; } + void SetNEHeight(Int_t h) { fNEHeight = h; } + + ClassDef(TEveGValuatorBase, 0); // Base class for composite GUI elements for setting of numeric values. +}; + + +/******************************************************************************/ + +class TEveGValuator: public TEveGValuatorBase +{ + TEveGValuator(const TEveGValuator&); // Not implemented + TEveGValuator& operator=(const TEveGValuator&); // Not implemented + +protected: + Float_t fValue; + Float_t fMin; + Float_t fMax; + + Bool_t fSliderNewLine; + Int_t fSliderDivs; + TGNumberEntry* fEntry; + TGHSlider* fSlider; + + Int_t CalcSliderPos(Float_t v); + +public: + TEveGValuator(const TGWindow *p, const char* title, UInt_t w, UInt_t h); + virtual ~TEveGValuator() {} + + virtual void Build(Bool_t connect=kTRUE); + + Float_t GetValue() const { return fValue; } + virtual void SetValue(Float_t v, Bool_t emit=kFALSE); + + void SliderCallback(); + void EntryCallback(); + void ValueSet(Double_t); //*SIGNAL* + + TGHSlider* GetSlider() { return fSlider; } + TGNumberEntry* GetEntry() { return fEntry; } + + void SetSliderNewLine(Bool_t nl) { fSliderNewLine = nl; } + + void GetLimits(Float_t& min, Float_t& max) const { min = fMin; max = fMax; } + Float_t GetLimitMin() const { return fMin; } + Float_t GetLimitMax() const { return fMax; } + void SetLimits(Int_t min, Int_t max); + void SetLimits(Float_t min, Float_t max, Int_t npos, + TGNumberFormat::EStyle nef=TGNumberFormat::kNESRealTwo); + + void SetToolTip(const Text_t* tip); + void SetEnabled(Bool_t state); + + ClassDef(TEveGValuator, 0); // Composite GUI element for single value selection (supports label, number-entry and slider). +}; + + +/******************************************************************************/ + +class TEveGDoubleValuator: public TEveGValuatorBase +{ + TEveGDoubleValuator(const TEveGDoubleValuator&); // Not implemented + TEveGDoubleValuator& operator=(const TEveGDoubleValuator&); // Not implemented + +protected: + TGNumberEntry* fMinEntry; + TGNumberEntry* fMaxEntry; + TGDoubleHSlider* fSlider; + +public: + TEveGDoubleValuator(const TGWindow *p, const char* title, UInt_t w, UInt_t h); + virtual ~TEveGDoubleValuator() {} + + virtual void Build(Bool_t connect=kTRUE); + + void MinEntryCallback(); + void MaxEntryCallback(); + void SliderCallback(); + void ValueSet(); //*SIGNAL* + + TGDoubleHSlider* GetSlider() { return fSlider; } + TGNumberEntry* GetMinEntry() { return fMinEntry; } + TGNumberEntry* GetMaxEntry() { return fMaxEntry; } + + void SetLimits(Int_t min, Int_t max); + void SetLimits(Float_t min, Float_t max, TGNumberFormat::EStyle nef=TGNumberFormat::kNESRealTwo); + void SetValues(Float_t min, Float_t max, Bool_t emit=kFALSE); + + void GetValues(Float_t& min, Float_t& max) const + { min = fMinEntry->GetNumber(); max = fMaxEntry->GetNumber(); } + Float_t GetMin() const { return fMinEntry->GetNumber(); } + Float_t GetMax() const { return fMaxEntry->GetNumber(); } + Float_t GetLimitMin() const { return fMinEntry->GetNumMin(); } + Float_t GetLimitMax() const { return fMaxEntry->GetNumMax(); } + + ClassDef(TEveGDoubleValuator, 0); // Composite GUI element for selection of range (label, two number-entries and double-slider). +}; + + +/******************************************************************************/ + +class TEveGTriVecValuator : public TGCompositeFrame +{ + TEveGTriVecValuator(const TEveGTriVecValuator&); // Not implemented + TEveGTriVecValuator& operator=(const TEveGTriVecValuator&); // Not implemented + +protected: + TEveGValuator* fVal[3]; + + // Weed-size vars from TEveGValuator; copied. + UInt_t fLabelWidth; + Int_t fNELength; // Number-entry length (in characters) + Int_t fNEHeight; // Number-entry height (in pixels) + +public: + TEveGTriVecValuator(const TGWindow *p, const char* name, UInt_t w, UInt_t h); + virtual ~TEveGTriVecValuator(); + + void Build(Bool_t vertical, const char* lab0, const char* lab1, const char* lab2); + + TEveGValuator* GetValuator(Int_t i) const { return fVal[i]; } + + Float_t GetValue(Int_t i) const { return fVal[i]->GetValue(); } + void SetValue(Int_t i, Float_t v) { fVal[i]->SetValue(v); } + + void GetValues(Float_t& v0, Float_t& v1, Float_t& v2) const + { v0 = GetValue(0); v1 = GetValue(1); v2 = GetValue(2); } + void GetValues(Float_t v[3]) const + { v[0] = GetValue(0); v[1] = GetValue(1); v[2] = GetValue(2); } + void GetValues(Double_t v[3]) const + { v[0] = GetValue(0); v[1] = GetValue(1); v[2] = GetValue(2); } + + void SetValues(Float_t v0, Float_t v1, Float_t v2) + { SetValue(0, v0); SetValue(1, v1); SetValue(2, v2); } + void SetValues(Float_t v[3]) + { SetValue(0, v[0]); SetValue(1, v[1]); SetValue(2, v[2]); } + void SetValues(Double_t v[3]) + { SetValue(0, v[0]); SetValue(1, v[1]); SetValue(2, v[2]); } + + void ValueSet(); //*SIGNAL* + + // Weed-size vars from TEveGValuator; copied. + void SetLabelWidth(Int_t w) { fLabelWidth = w; } + void SetNELength(Int_t l) { fNELength = l; } + void SetNEHeight(Int_t h) { fNEHeight = h; } + + void SetLimits(Int_t min, Int_t max); + void SetLimits(Float_t min, Float_t max, + TGNumberFormat::EStyle nef=TGNumberFormat::kNESRealTwo); + + ClassDef(TEveGTriVecValuator, 0); // Composite GUI element for setting three numerical values (label, three number-entries). +}; + +#endif diff --git a/eve/inc/TEveGedEditor.h b/eve/inc/TEveGedEditor.h new file mode 100644 index 0000000000..52494f07bc --- /dev/null +++ b/eve/inc/TEveGedEditor.h @@ -0,0 +1,45 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveGedEditor +#define ROOT_TEveGedEditor + +#include + +class TEveElement; + +class TEveGedEditor : public TGedEditor +{ + TEveGedEditor(const TEveGedEditor&); // Not implemented + TEveGedEditor& operator=(const TEveGedEditor&); // Not implemented + +protected: + TEveElement *fRnrElement; // Cached rnr-el pointer + TObject *fObject; // Cached tobj pointer + +public: + TEveGedEditor(TCanvas* canvas=0, Int_t width=250, Int_t height=400); + virtual ~TEveGedEditor() {} + + TEveElement* GetRnrElement() const; + + void DisplayElement(TEveElement* re); + void DisplayObject(TObject* obj); + + virtual void SetModel(TVirtualPad* pad, TObject* obj, Int_t event); + virtual void Update(TGedFrame* gframe=0); + + // virtual Bool_t HandleButton(Event_t *event); + + ClassDef(TEveGedEditor, 0); // Specialization of TGedEditor for proper update propagation to TEveManager. +}; + +#endif diff --git a/eve/inc/TEveGeoNode.h b/eve/inc/TEveGeoNode.h new file mode 100644 index 0000000000..82e3d11962 --- /dev/null +++ b/eve/inc/TEveGeoNode.h @@ -0,0 +1,166 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveGeoNode +#define ROOT_TEveGeoNode + +#include +#include +#include + +class TGeoVolume; +class TGeoNode; +class TGeoHMatrix; +class TGeoManager; + +class TGeoShape; +class TEveGeoShapeExtract; + +//---------------------------------------------------------------- + +class TEveGeoNode : public TEveElement, + public TObject +{ + friend class TEveGeoNodeEditor; + + TEveGeoNode(const TEveGeoNode&); // Not implemented + TEveGeoNode& operator=(const TEveGeoNode&); // Not implemented + +protected: + TGeoNode *fNode; + TEveGeoShapeExtract* DumpShapeTree(TEveGeoNode* geon, TEveGeoShapeExtract* parent = 0, Int_t level = 0); +public: + TEveGeoNode(TGeoNode* node); + + virtual const Text_t* GetName() const; + virtual const Text_t* GetTitle() const; + + TGeoNode* GetNode() const { return fNode; } + + virtual Int_t ExpandIntoListTree(TGListTree* ltree, TGListTreeItem* parent); + + virtual Bool_t CanEditRnrElement() { return false; } + virtual void SetRnrSelf(Bool_t rnr); + virtual void SetRnrChildren(Bool_t rnr); + virtual void SetRnrState(Bool_t rnr); + + virtual Bool_t CanEditMainColor() { return true; } + virtual void SetMainColor(Color_t color); + virtual void SetMainColor(Pixel_t pixel); + + void UpdateNode(TGeoNode* node); + void UpdateVolume(TGeoVolume* volume); + + void Save(const char* file, const char* name="Extract"); + + virtual void Draw(Option_t* option=""); + + ClassDef(TEveGeoNode, 1); // Wrapper for TGeoNode that allows it to be shown in GUI and controlled as a TEveElement. +}; + +//---------------------------------------------------------------- + +class TEveGeoTopNode : public TEveGeoNode +{ + TEveGeoTopNode(const TEveGeoTopNode&); // Not implemented + TEveGeoTopNode& operator=(const TEveGeoTopNode&); // Not implemented + +protected: + TGeoManager* fManager; + TEveTrans fGlobalTrans; + Int_t fVisOption; + Int_t fVisLevel; + +public: + TEveGeoTopNode(TGeoManager* manager, TGeoNode* node, Int_t visopt=1, Int_t vislvl=3); + virtual ~TEveGeoTopNode(); + + virtual Bool_t CanEditMainHMTrans() { return kTRUE; } + virtual TEveTrans* PtrMainHMTrans() { return &fGlobalTrans; } + + TEveTrans& RefGlobalTrans() { return fGlobalTrans; } + void SetGlobalTrans(const TGeoHMatrix* m); + void UseNodeTrans(); + + Int_t GetVisOption() const { return fVisOption; } + void SetVisOption(Int_t visopt); + Int_t GetVisLevel() const { return fVisLevel; } + void SetVisLevel(Int_t vislvl); + + virtual Bool_t CanEditRnrElement() { return true; } + virtual void SetRnrSelf(Bool_t rnr); + + virtual void Draw(Option_t* option=""); + virtual void Paint(Option_t* option=""); + + // Signals from GeoManager. + // These are not available any more ... colors in list-tree not refreshed + // properly. + void VolumeVisChanged(TGeoVolume* volume); + void VolumeColChanged(TGeoVolume* volume); + void NodeVisChanged(TGeoNode* node); + + ClassDef(TEveGeoTopNode, 1); // Top-level TEveGeoNode with a pointer to TGeoManager and controls for steering of TGeoPainter. +}; + + +//---------------------------------------------------------------- +//---------------------------------------------------------------- + +class TEveGeoShape : public TEveElement, + public TNamed, + public TEveProjectable +{ + TEveGeoShape(const TEveGeoShape&); // Not implemented + TEveGeoShape& operator=(const TEveGeoShape&); // Not implemented + +protected: + TEveTrans fHMTrans; + Color_t fColor; + UChar_t fTransparency; + TGeoShape* fShape; + + static TEveGeoShape* SubImportShapeExtract(TEveGeoShapeExtract* gse, TEveElement* parent); + TEveGeoShapeExtract* DumpShapeTree(TEveGeoShape* geon, TEveGeoShapeExtract* parent = 0); + +public: + TEveGeoShape(const Text_t* name="TEveGeoShape", const Text_t* title=0); + virtual ~TEveGeoShape(); + + virtual Bool_t CanEditMainColor() { return kTRUE; } + + virtual Bool_t CanEditMainTransparency() { return kTRUE; } + virtual UChar_t GetMainTransparency() const { return fTransparency; } + virtual void SetMainTransparency(UChar_t t) { fTransparency = t; } + + virtual Bool_t CanEditMainHMTrans() { return kTRUE; } + virtual TEveTrans* PtrMainHMTrans() { return &fHMTrans; } + + TEveTrans& RefHMTrans() { return fHMTrans; } + void SetTransMatrix(Double_t* carr) { fHMTrans.SetFrom(carr); } + void SetTransMatrix(const TGeoMatrix& mat) { fHMTrans.SetFrom(mat); } + + Color_t GetColor() { return fColor; } + TGeoShape* GetShape() { return fShape; } + + virtual void Paint(Option_t* option=""); + + void Save(const char* file, const char* name="Extract"); + static TEveGeoShape* ImportShapeExtract(TEveGeoShapeExtract* gse, TEveElement* parent); + + // NLTGeoProjectable + virtual TBuffer3D* MakeBuffer3D(); + virtual TClass* ProjectedClass() const; + + ClassDef(TEveGeoShape, 1); // Wrapper for TGeoShape with absolute positioning and color attributes allowing display of extracted TGeoShape's (without an active TGeoManager) and simplified geometries (needed for NLT projections). +}; + +#endif diff --git a/eve/inc/TEveGeoNodeEditor.h b/eve/inc/TEveGeoNodeEditor.h new file mode 100644 index 0000000000..5d49e8f21f --- /dev/null +++ b/eve/inc/TEveGeoNodeEditor.h @@ -0,0 +1,84 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveGeoNodeEditor +#define ROOT_TEveGeoNodeEditor + +#include + +class TGCheckButton; +class TGNumberEntry; +class TGColorSelect; + +class TEveGeoNode; +class TEveGeoTopNode; + +class TEveGValuator; + +class TEveGeoNodeEditor : public TGedFrame +{ + TEveGeoNodeEditor(const TEveGeoNodeEditor&); // Not implemented + TEveGeoNodeEditor& operator=(const TEveGeoNodeEditor&); // Not implemented + +protected: + TEveGeoNode* fNodeRE; + + TGCheckButton* fVizNode; + TGCheckButton* fVizNodeDaughters; + TGCheckButton* fVizVolume; + TGCheckButton* fVizVolumeDaughters; + + TGNumberEntry* fTransparency; + +public: + TEveGeoNodeEditor(const TGWindow* p=0, Int_t width=170, Int_t height=30, + UInt_t options=kChildFrame, Pixel_t back=GetDefaultFrameBackground()); + virtual ~TEveGeoNodeEditor() {} + + virtual void SetModel(TObject* obj); + + void DoVizNode(); + void DoVizNodeDaughters(); + void DoVizVolume(); + void DoVizVolumeDaughters(); + + void DoTransparency(); + + ClassDef(TEveGeoNodeEditor, 1); // Editor for TEveGeoNode class. +}; + +/******************************************************************************/ + +class TEveGeoTopNodeEditor : public TGedFrame +{ + TEveGeoTopNodeEditor(const TEveGeoTopNodeEditor&); // Not implemented + TEveGeoTopNodeEditor& operator=(const TEveGeoTopNodeEditor&); // Not implemented + +protected: + TEveGeoTopNode* fTopNodeRE; + + TEveGValuator* fVisOption; + TEveGValuator* fVisLevel; + +public: + TEveGeoTopNodeEditor(const TGWindow* p=0, Int_t width=170, Int_t height=30, + UInt_t options=kChildFrame, Pixel_t back=GetDefaultFrameBackground()); + virtual ~TEveGeoTopNodeEditor() {} + + virtual void SetModel(TObject* obj); + + void DoVisOption(); + void DoVisLevel(); + + ClassDef(TEveGeoTopNodeEditor, 1); // Editor for TEveGeoTopNode class. +}; + +#endif diff --git a/eve/inc/TEveGeoShapeExtract.h b/eve/inc/TEveGeoShapeExtract.h new file mode 100644 index 0000000000..2df797322f --- /dev/null +++ b/eve/inc/TEveGeoShapeExtract.h @@ -0,0 +1,59 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveGeoShapeExtract +#define ROOT_TEveGeoShapeExtract + +#include + +class TList; +class TGeoShape; + +class TEveGeoShapeExtract : public TNamed +{ + friend class ZGeoRepacker; + + TEveGeoShapeExtract(const TEveGeoShapeExtract&); // Not implemented + TEveGeoShapeExtract& operator=(const TEveGeoShapeExtract&); // Not implemented + +protected: + Double_t mTrans[16]; + Float_t mRGBA[4]; + Bool_t mRnrSelf; + Bool_t mRnrElements; + TGeoShape* mShape; + TList* mElements; + +public: + TEveGeoShapeExtract(const Text_t* n="TEveGeoShapeExtract", const Text_t* t=0); + ~TEveGeoShapeExtract(); + + Bool_t HasElements(); + void AddElement(TEveGeoShapeExtract* gse); + + void SetTrans(const Double_t arr[16]); + void SetRGBA (const Float_t arr[4]); + void SetRnrSelf(Bool_t r) { mRnrSelf = r; } + void SetRnrElements(Bool_t r) { mRnrElements = r; } + void SetShape(TGeoShape* s) { mShape = s; } + void SetElements(TList* e) { mElements = e; } + + Double_t* GetTrans() { return mTrans; } + Float_t* GetRGBA() { return mRGBA; } + Bool_t GetRnrSelf() { return mRnrSelf; } + Bool_t GetRnrElements() { return mRnrElements; } + TGeoShape* GetShape() { return mShape; } + TList* GetElements() { return mElements; } + + ClassDef(TEveGeoShapeExtract, 1); // Globally positioned TGeoShape with rendering attributes and an optional list of daughter shape-extracts. +}; + +#endif diff --git a/eve/inc/TEveGridStepper.h b/eve/inc/TEveGridStepper.h new file mode 100644 index 0000000000..301064ce1a --- /dev/null +++ b/eve/inc/TEveGridStepper.h @@ -0,0 +1,60 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveGridStepper +#define ROOT_TEveGridStepper + +#include + +#include + +class TEveTrans; + +class TEveGridStepper : public TObject +{ +private: + Int_t *ls[3], *ns[3]; //! Internal traversal variables. + + TEveGridStepper(const TEveGridStepper&); // Not implemented + TEveGridStepper& operator=(const TEveGridStepper&); // Not implemented + +public: + enum StepMode_e { SM_XYZ, SM_YXZ, SM_XZY }; + StepMode_e Mode; // Stepping mode, order of filling. + + Int_t nx, ny, nz; // Current positions during filling / traversal. + Int_t Nx, Ny, Nz; // Number of slots in eaxh direction. + Float_t Dx, Dy, Dz; // Step size in each direction. + Float_t Ox, Oy, Oz; // Initial offset for each direction. + + TEveGridStepper(Int_t sm=SM_XYZ); + virtual ~TEveGridStepper() {} + + void Reset(); + void Subtract(TEveGridStepper& s); + void SetNs(Int_t nx, Int_t ny, Int_t nz=1) + { Nx = nx; Ny = ny; Nz = nz; } + void SetDs(Float_t dx, Float_t dy, Float_t dz=0) + { Dx = dx; Dy = dy; Dz = dz; } + void SetOs(Float_t ox, Float_t oy, Float_t oz=0) + { Ox = ox; Oy = oy; Oz = oz; } + + Bool_t Step(); + + void GetPosition(Float_t* p); + + void SetTrans(TEveTrans* mx); + void SetTransAdvance(TEveTrans* mx); + + ClassDef(TEveGridStepper, 1); // Provide discrete position coordinates for placement of objects on regular grids. +}; // end class TEveGridStepper + +#endif diff --git a/eve/inc/TEveGridStepperEditor.h b/eve/inc/TEveGridStepperEditor.h new file mode 100644 index 0000000000..5cd71c923d --- /dev/null +++ b/eve/inc/TEveGridStepperEditor.h @@ -0,0 +1,75 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveGridStepperEditor +#define ROOT_TEveGridStepperEditor + +#include + +class TGButton; +class TGCheckButton; +class TGNumberEntry; +class TGColorSelect; + +class TEveGridStepper; +class TEveGValuator; + +class TEveGridStepperSubEditor : public TGVerticalFrame +{ +private: + TEveGridStepperSubEditor(const TEveGridStepperSubEditor&); // Not implemented + TEveGridStepperSubEditor& operator=(const TEveGridStepperSubEditor&); // Not implemented + +protected: + TEveGridStepper *fM; // Model object. + + TEveGValuator *fNx; // Number of slots along x. + TEveGValuator *fNy; // Number of slots along y. + TEveGValuator *fNz; // Number of slots along z. + TEveGValuator *fDx; // Step in the x direction. + TEveGValuator *fDy; // Step in the y direction. + TEveGValuator *fDz; // Step in the z direction. + +public: + TEveGridStepperSubEditor(const TGWindow* p); + virtual ~TEveGridStepperSubEditor() {} + + void SetModel(TEveGridStepper* m); + + void Changed(); //*SIGNAL* + + void DoNs(); + void DoDs(); + + ClassDef(TEveGridStepperSubEditor, 0); // Sub-editor for TEveGridStepper class. +}; + + +class TEveGridStepperEditor : public TGedFrame +{ +private: + TEveGridStepperEditor(const TEveGridStepperEditor&); // Not implemented + TEveGridStepperEditor& operator=(const TEveGridStepperEditor&); // Not implemented + +protected: + TEveGridStepper *fM; // Model object. + TEveGridStepperSubEditor *fSE; // Sub-editor containg GUI controls. + +public: + TEveGridStepperEditor(const TGWindow* p=0, Int_t width=170, Int_t height=30, UInt_t options=kChildFrame, Pixel_t back=GetDefaultFrameBackground()); + virtual ~TEveGridStepperEditor() {} + + virtual void SetModel(TObject* obj); + + ClassDef(TEveGridStepperEditor, 0); // Editor for TEveGridStepper class. +}; + +#endif diff --git a/eve/inc/TEveLine.h b/eve/inc/TEveLine.h new file mode 100644 index 0000000000..060d5b7b92 --- /dev/null +++ b/eve/inc/TEveLine.h @@ -0,0 +1,52 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveLine +#define ROOT_TEveLine + +#include +#include + +#include + +class TEveLine : public TEvePointSet, + public TAttLine +{ + friend class TEveLineEditor; + friend class TEveLineGL; + +private: + TEveLine(const TEveLine&); // Not implemented + TEveLine& operator=(const TEveLine&); // Not implemented + +protected: + Bool_t fRnrLine; + Bool_t fRnrPoints; + +public: + TEveLine(Int_t n_points=0, TreeVarType_e tv_type=TVT_XYZ); + TEveLine(const Text_t* name, Int_t n_points=0, TreeVarType_e tv_type=TVT_XYZ); + virtual ~TEveLine(); + + virtual void SetMarkerColor(Color_t col) + { TAttMarker::SetMarkerColor(col); } + virtual void SetLineColor(Color_t col) + { SetMainColor(col); } + + Bool_t GetRnrLine() const { return fRnrLine; } + void SetRnrLine(Bool_t r) { fRnrLine = r; } + Bool_t GetRnrPoints() const { return fRnrPoints; } + void SetRnrPoints(Bool_t r) { fRnrPoints = r; } + + ClassDef(TEveLine, 1); // An arbitrary polyline with fixed line and marker attributes. +}; + +#endif diff --git a/eve/inc/TEveLineEditor.h b/eve/inc/TEveLineEditor.h new file mode 100644 index 0000000000..4a4b9cb44c --- /dev/null +++ b/eve/inc/TEveLineEditor.h @@ -0,0 +1,47 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveLineEditor +#define ROOT_TEveLineEditor + +#include + +class TGCheckButton; +class TGNumberEntry; +class TGColorSelect; + +class TEveLine; + +class TEveLineEditor : public TGedFrame +{ +private: + TEveLineEditor(const TEveLineEditor&); // Not implemented + TEveLineEditor& operator=(const TEveLineEditor&); // Not implemented + +protected: + TEveLine *fM; // Model object. + + TGCheckButton *fRnrLine; // Checkbox for line-rendering. + TGCheckButton *fRnrPoints; // Checkbox for point-rendering. + +public: + TEveLineEditor(const TGWindow* p=0, Int_t width=170, Int_t height=30, UInt_t options = kChildFrame, Pixel_t back=GetDefaultFrameBackground()); + virtual ~TEveLineEditor(); + + virtual void SetModel(TObject* obj); + + void DoRnrLine(); + void DoRnrPoints(); + + ClassDef(TEveLineEditor, 1); // Editor for TEveLine class. +}; + +#endif diff --git a/eve/inc/TEveLineGL.h b/eve/inc/TEveLineGL.h new file mode 100644 index 0000000000..f6576534cb --- /dev/null +++ b/eve/inc/TEveLineGL.h @@ -0,0 +1,47 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveLineGL +#define ROOT_TEveLineGL + +#include +#include + +class TGLViewer; +class TGLScene; + +class TEveLine; + +class TEveLineGL : public TPointSet3DGL +{ +private: + TEveLineGL(const TEveLineGL&); // Not implemented + TEveLineGL& operator=(const TEveLineGL&); // Not implemented + +protected: + TEveLine* fM; // fModel dynamic-casted to TEveLineGL + + virtual void DirectDraw(TGLRnrCtx & rnrCtx) const; + +public: + TEveLineGL(); + virtual ~TEveLineGL(); + + virtual Bool_t SetModel(TObject* obj, const Option_t* opt=0); + + // To support two-level selection + // virtual Bool_t SupportsSecondarySelect() const { return kTRUE; } + // virtual void ProcessSelection(UInt_t* ptr, TGLViewer*, TGLScene*); + + ClassDef(TEveLineGL, 0); // GL-renderer for TEveLine class. +}; + +#endif diff --git a/eve/inc/TEveMacro.h b/eve/inc/TEveMacro.h new file mode 100644 index 0000000000..04d6d48ead --- /dev/null +++ b/eve/inc/TEveMacro.h @@ -0,0 +1,36 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveMacro +#define ROOT_TEveMacro + +#include + +#include + +class TEveMacro : public TMacro +{ +protected: + +public: + TEveMacro(); + TEveMacro(const TEveMacro&); + TEveMacro(const char* name); + virtual ~TEveMacro() {} + + virtual Long_t Exec(const char* params = "0", Int_t* error = 0); + + void ResetRoot(); + + ClassDef(TEveMacro, 1); // TMacro wrapper (attempting to fix issues with different macro loading and execution schemes). +}; + +#endif diff --git a/eve/inc/TEveManager.h b/eve/inc/TEveManager.h new file mode 100644 index 0000000000..4ae51080b7 --- /dev/null +++ b/eve/inc/TEveManager.h @@ -0,0 +1,181 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveManager +#define ROOT_TEveManager + +#include +#include +#include +#include +#include + +#include +#include + +class TMacro; +class TFolder; +class TCanvas; + +class TGTab; +class TGStatusBar; +class TGListTree; +class TGListTreeItem; +class TGStatusBar; +class TGWindow; + +class TGLViewer; + +class TEveGListTreeEditorFrame; +class TEveBrowser; +class TEveGedEditor; + +class TEveElement; +class PadPrimitive; + +class TEveViewer; class TEveViewerList; +class TEveScene; class TEveSceneList; + +class TEveEventManager; + + +class TEveManager +{ + TEveManager(const TEveManager&); // Not implemented + TEveManager& operator=(const TEveManager&); // Not implemented + +public: + class RedrawDisabler + { + private: + RedrawDisabler(const RedrawDisabler&); // Not implemented + RedrawDisabler& operator=(const RedrawDisabler&); // Not implemented + + TEveManager* fFrame; + public: + RedrawDisabler(TEveManager* f) : fFrame(f) + { if (fFrame) fFrame->DisableRedraw(); } + ~RedrawDisabler() + { if (fFrame) fFrame->EnableRedraw(); } + }; + +private: + + TEveBrowser *fBrowser; + TEveGListTreeEditorFrame *fLTEFrame; + TEveGedEditor *fEditor; + TGStatusBar *fStatusBar; + + TFolder *fMacroFolder; + + TEveViewerList *fViewers; + TEveSceneList *fScenes; + + TEveViewer *fViewer; // First / default gl-viewer. + TEveScene *fGlobalScene; + TEveScene *fEventScene; + TEveEventManager *fCurrentEvent; + + Int_t fRedrawDisabled; + Bool_t fFullRedraw; + Bool_t fResetCameras; + Bool_t fDropLogicals; + Bool_t fKeepEmptyCont; + Bool_t fTimerActive; + TTimer fRedrawTimer; + +protected: + std::map fGeometries; + +public: + TEveManager(UInt_t w, UInt_t h); + virtual ~TEveManager(); + + TEveBrowser* GetBrowser() const { return fBrowser; } + TEveGListTreeEditorFrame* GetLTEFrame() const { return fLTEFrame; } + TEveGedEditor* GetEditor() const { return fEditor; } + TGStatusBar* GetStatusBar() const { return fStatusBar; } + + TEveSceneList* GetScenes() const { return fScenes; } + TEveViewerList* GetViewers() const { return fViewers; } + + TEveViewer* GetDefViewer() const { return fViewer; } + TEveScene* GetGlobalScene() const { return fGlobalScene; } + TEveScene* GetEventScene() const { return fEventScene; } + TEveEventManager* GetCurrentEvent() const { return fCurrentEvent; } + + TCanvas* AddCanvasTab(const char* name); + TGWindow* GetMainWindow() const; + TGLViewer* GetGLViewer() const; + TEveViewer* SpawnNewViewer(const Text_t* name, const Text_t* title="", Bool_t embed=kTRUE); + TEveScene* SpawnNewScene(const Text_t* name, const Text_t* title=""); + + TFolder* GetMacroFolder() const { return fMacroFolder; } + TMacro* GetMacro(const Text_t* name) const; + + void EditElement(TEveElement* rnr_element); + + void DisableRedraw() { ++fRedrawDisabled; } + void EnableRedraw() { --fRedrawDisabled; if(fRedrawDisabled <= 0) Redraw3D(); } + + void Redraw3D(Bool_t resetCameras=kFALSE, Bool_t dropLogicals=kFALSE) + { + if(fRedrawDisabled <= 0 && !fTimerActive) RegisterRedraw3D(); + if(resetCameras) fResetCameras = kTRUE; + if(dropLogicals) fDropLogicals = kTRUE; + } + void RegisterRedraw3D(); + void DoRedraw3D(); + void FullRedraw3D(Bool_t resetCameras=kFALSE, Bool_t dropLogicals=kFALSE); + + Bool_t GetKeepEmptyCont() const { return fKeepEmptyCont; } + void SetKeepEmptyCont(Bool_t k) { fKeepEmptyCont = k; } + + + void ElementChanged(TEveElement* rnr_element); + void ScenesChanged(std::list& scenes); + + static int SpawnGuiAndRun(int argc, char **argv); + static void SpawnGui(); + + // These are more like TEveManager stuff. + TGListTree* GetListTree() const; + TGListTreeItem* AddToListTree(TEveElement* re, Bool_t open, TGListTree* lt=0); + void RemoveFromListTree(TEveElement* re, TGListTree* lt, TGListTreeItem* lti); + + TGListTreeItem* AddEvent(TEveEventManager* event); + TGListTreeItem* AddElement(TEveElement* rnr_element, + TEveElement* parent=0); + TGListTreeItem* AddGlobalElement(TEveElement* rnr_element, + TEveElement* parent=0); + + void RemoveElement(TEveElement* rnr_element, TEveElement* parent); + void PreDeleteElement(TEveElement* rnr_element); + + void ElementSelect(TEveElement* rnr_element); + Bool_t ElementPaste(TEveElement* rnr_element); + void ElementChecked(TEveElement* rnrEl, Bool_t state); + + void NotifyBrowser(TGListTreeItem* parent_lti=0); + void NotifyBrowser(TEveElement* parent); + + // Hmmph ... geometry management? + TGeoManager* GetGeometry(const TString& filename); + + void SetStatusLine(const char* text); + void ThrowException(const char* text="foo"); + + ClassDef(TEveManager, 0); // Reve application manager. +}; + +extern TEveManager* gEve; + +#endif diff --git a/eve/inc/TEvePad.h b/eve/inc/TEvePad.h new file mode 100644 index 0000000000..fcd5132df8 --- /dev/null +++ b/eve/inc/TEvePad.h @@ -0,0 +1,36 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEvePad +#define ROOT_TEvePad + +#include + +class TEvePad : public TPad +{ +public: + TEvePad(); + TEvePad(const char* name, const char* title, + Double_t xlow, Double_t ylow, Double_t xup, Double_t yup, + Color_t color = -1, Short_t bordersize = -1, Short_t bordermode = -2); + virtual ~TEvePad() {} + + virtual Bool_t IsBatch() const { return kTRUE; } + + virtual void Update() { PaintModified(); } + + virtual TVirtualViewer3D *GetViewer3D(Option_t * /*type*/ = "") + { return fViewer3D; } + + ClassDef(TEvePad, 1); // Internal TEveUtil pad class (sub-class of TPad) overriding handling of updates and 3D-viewers. +}; + +#endif diff --git a/eve/inc/TEvePointSet.h b/eve/inc/TEvePointSet.h new file mode 100644 index 0000000000..b19557b028 --- /dev/null +++ b/eve/inc/TEvePointSet.h @@ -0,0 +1,170 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEvePointSet +#define ROOT_TEvePointSet + +#include +#include +#include +#include + +#include +#include + +class TTree; +class TF3; +class TGListTreeItem; + +/******************************************************************************/ +// TEvePointSet +/******************************************************************************/ + +class TEvePointSet : public TEveElement, + public TPointSet3D, + public TEvePointSelectorConsumer, + public TEveProjectable +{ + friend class TEvePointSetArray; + +protected: + TString fTitle; // Title/tooltip of the TEvePointSet. + TArrayI *fIntIds; // Optional array of integer ideices. + Int_t fIntIdsPerPoint; // Number of integer indices assigned to each point. + + void AssertIntIdsSize(); + +public: + TEvePointSet(Int_t n_points=0, TreeVarType_e tv_type=TVT_XYZ); + TEvePointSet(const Text_t* name, Int_t n_points=0, TreeVarType_e tv_type=TVT_XYZ); + virtual ~TEvePointSet(); + + virtual void ComputeBBox(); + + void Reset(Int_t n_points=0, Int_t n_int_ids=0); + Int_t GrowFor(Int_t n_points); + + virtual const Text_t* GetTitle() const { return fTitle; } + virtual void SetTitle(const Text_t* t) { fTitle = t; } + + Int_t GetIntIdsPerPoint() const { return fIntIdsPerPoint; } + Int_t* GetPointIntIds(Int_t p) const; + Int_t GetPointIntId(Int_t p, Int_t i) const; + + void SetPointIntIds(Int_t* ids); + void SetPointIntIds(Int_t n, Int_t* ids); + + virtual void SetRnrElNameTitle(const Text_t* name, const Text_t* title); + + virtual void SetMarkerColor(Color_t col) + { SetMainColor(col); } + + virtual void Paint(Option_t* option=""); + + virtual void InitFill(Int_t subIdNum); + virtual void TakeAction(TEvePointSelector*); + + virtual const TGPicture* GetListTreeIcon() { return TEveElement::fgListTreeIcons[3]; } + + virtual TClass* ProjectedClass() const; + + ClassDef(TEvePointSet, 1); // Set of 3D points with same marker attributes; optionally each point can be assigned an external TRef or a number of integer indices. +}; + + +/******************************************************************************/ +// TEvePointSetArray +/******************************************************************************/ + +class TEvePointSetArray : public TEveElement, + public TNamed, + public TAttMarker, + public TEvePointSelectorConsumer +{ + friend class TEvePointSetArrayEditor; + + TEvePointSetArray(const TEvePointSetArray&); // Not implemented + TEvePointSetArray& operator=(const TEvePointSetArray&); // Not implemented + +protected: + TEvePointSet** fBins; // Pointers to subjugated TEvePointSet's. + Int_t fDefPointSetCapacity; // Default capacity of subjugated TEvePointSet's. + Int_t fNBins; // Number of subjugated TEvePointSet's. + Int_t fLastBin; //! Index of the last filled TEvePointSet. + Double_t fMin, fCurMin; // Overall and current minimum value of the separating quantity. + Double_t fMax, fCurMax; // Overall and current maximum value of the separating quantity. + Double_t fBinWidth; // Separating quantity bin-width. + TString fQuantName; // Name of the separating quantity. + +public: + TEvePointSetArray(const Text_t* name="TEvePointSetArray", const Text_t* title=""); + virtual ~TEvePointSetArray(); + + virtual void RemoveElementLocal(TEveElement* el); + virtual void RemoveElementsLocal(); + + virtual void Paint(Option_t* option=""); + + virtual void SetMarkerColor(Color_t tcolor=1); + virtual void SetMarkerStyle(Style_t mstyle=1); + virtual void SetMarkerSize(Size_t msize=1); + + virtual void TakeAction(TEvePointSelector*); + + + void InitBins(const Text_t* quant_name, Int_t nbins, Double_t min, Double_t max, + Bool_t addRe=kTRUE); + void Fill(Double_t x, Double_t y, Double_t z, Double_t quant); + void SetPointId(TObject* id); + void CloseBins(); + + void SetOwnIds(Bool_t o); + + Int_t GetDefPointSetCapacity() const { return fDefPointSetCapacity; } + void SetDefPointSetCapacity(Int_t c) { fDefPointSetCapacity = c; } + + Int_t GetNBins() const { return fNBins; } + TEvePointSet* GetBin(Int_t bin) const { return fBins[bin]; } + + Double_t GetMin() const { return fMin; } + Double_t GetCurMin() const { return fCurMin; } + Double_t GetMax() const { return fMax; } + Double_t GetCurMax() const { return fCurMax; } + + void SetRange(Double_t min, Double_t max); + + ClassDef(TEvePointSetArray, 1); // Array of TEvePointSet's filled via a common point-source; range of displayed TEvePointSet's can be controlled, based on a separating quantity provided on fill-time by a user. +}; + + +/******************************************************************************/ +// TEvePointSetProjected +/******************************************************************************/ + +class TEvePointSetProjected : public TEvePointSet, + public TEveProjected +{ +private: + TEvePointSetProjected(const TEvePointSetProjected&); // Not implemented + TEvePointSetProjected& operator=(const TEvePointSetProjected&); // Not implemented + +public: + TEvePointSetProjected(); + virtual ~TEvePointSetProjected() {} + + virtual void SetProjection(TEveProjectionManager* proj, TEveProjectable* model); + + virtual void UpdateProjection(); + + ClassDef(TEvePointSetProjected, 1); // Projected copy of a TEvePointSet. +}; + +#endif diff --git a/eve/inc/TEvePointSetArrayEditor.h b/eve/inc/TEvePointSetArrayEditor.h new file mode 100644 index 0000000000..b6fe21fb18 --- /dev/null +++ b/eve/inc/TEvePointSetArrayEditor.h @@ -0,0 +1,48 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEvePointSetArrayEditor +#define ROOT_TEvePointSetArrayEditor + +#include + +class TGCheckButton; +class TGNumberEntry; +class TGColorSelect; + +class TEveGValuator; +class TEveGDoubleValuator; + +class TEvePointSetArray; + +class TEvePointSetArrayEditor : public TGedFrame +{ + TEvePointSetArrayEditor(const TEvePointSetArrayEditor&); // Not implemented + TEvePointSetArrayEditor& operator=(const TEvePointSetArrayEditor&); // Not implemented + +protected: + TEvePointSetArray *fM; // Model object. + + TEveGDoubleValuator *fRange; // Control for displayed range of the separating quantity. + +public: + TEvePointSetArrayEditor(const TGWindow* p=0, Int_t width=170, Int_t height=30, + UInt_t options=kChildFrame, Pixel_t back=GetDefaultFrameBackground()); + ~TEvePointSetArrayEditor(); + + virtual void SetModel(TObject* obj); + + void DoRange(); + + ClassDef(TEvePointSetArrayEditor, 1); // Editor for TEvePointSetArray class. +}; + +#endif diff --git a/eve/inc/TEvePointSetProjectedGL.h b/eve/inc/TEvePointSetProjectedGL.h new file mode 100644 index 0000000000..0a01c4ddd1 --- /dev/null +++ b/eve/inc/TEvePointSetProjectedGL.h @@ -0,0 +1,38 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEvePointSetProjectedGL +#define ROOT_TEvePointSetProjectedGL + +#include + +class TGLViewer; +class TGLScene; + + +class TEvePointSetProjected; + +class TEvePointSetProjectedGL : public TPointSet3DGL +{ +private: + TEvePointSetProjectedGL(const TEvePointSetProjectedGL&); // Not implemented + TEvePointSetProjectedGL& operator=(const TEvePointSetProjectedGL&); // Not implemented + +protected: + +public: + TEvePointSetProjectedGL(); + virtual ~TEvePointSetProjectedGL(); + + ClassDef(TEvePointSetProjectedGL, 0); // GL-renderer for TEvePointSetProjected class. +}; + +#endif diff --git a/eve/inc/TEvePolygonSetProjected.h b/eve/inc/TEvePolygonSetProjected.h new file mode 100644 index 0000000000..fb67b581e8 --- /dev/null +++ b/eve/inc/TEvePolygonSetProjected.h @@ -0,0 +1,131 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEvePolygonSetProjected +#define ROOT_TEvePolygonSetProjected + +#include +#include + +#include "TNamed.h" +#include "TAtt3D.h" +#include "TAttBBox.h" +#include "TColor.h" +#include + +class TBuffer3D; + +namespace std +{ +template class allocator; +template class list; +} + +class TEveVector; + + + + +class TEvePolygonSetProjected : public TEveElementList, + public TEveProjected, + public TAtt3D, + public TAttBBox +{ + friend class TEvePolygonSetProjectedGL; + friend class TEvePolygonSetProjectedEditor; +private: + TEvePolygonSetProjected(const TEvePolygonSetProjected&); // Not implemented + TEvePolygonSetProjected& operator=(const TEvePolygonSetProjected&); // Not implemented + +protected: + struct Polygon_t + { + Int_t fNPnts; + Int_t* fPnts; + + Polygon_t() : fNPnts(0), fPnts(0) {} + Polygon_t(Int_t n, Int_t* p) : fNPnts(n), fPnts(p) {} + Polygon_t(const Polygon_t& x) : fNPnts(x.fNPnts), fPnts(x.fPnts) {} + virtual ~Polygon_t() {} + + Polygon_t& operator=(const Polygon_t& x) + { fNPnts = x.fNPnts; fPnts = x.fPnts; return *this; } + + Int_t FindPoint(Int_t pi) + { for (Int_t i=0; i vpPolygon_t; + typedef vpPolygon_t::iterator vpPolygon_i; + typedef vpPolygon_t::const_iterator vpPolygon_ci; + +private: + TBuffer3D* fBuff; + Int_t* fIdxMap; // map from original to projected and reduced point needed oly for geometry + + Bool_t IsFirstIdxHead(Int_t s0, Int_t s1); + void AddPolygon(std::list >& pp, std::list >& p); + + void ProjectAndReducePoints(); + void MakePolygonsFromBP(); + void MakePolygonsFromBS(); + void ClearPolygonSet(); + +protected: + vpPolygon_t fPols; // NLT polygons + vpPolygon_t fPolsBS; // NLT polygons build freom TBuffer3D segments + vpPolygon_t fPolsBP; // NLT polygons build freom TBuffer3D polygond + Float_t fSurf; // sum of surface of polygons + + Int_t fNPnts; // number of reduced and projected points + TEveVector* fPnts; // reduced and projected points + + Color_t fFillColor; + Color_t fLineColor; + Float_t fLineWidth; + + UChar_t fTransparency; + +public: + TEvePolygonSetProjected(const Text_t* n="TEvePolygonSetProjected", const Text_t* t=""); + virtual ~TEvePolygonSetProjected(); + + virtual void SetProjection(TEveProjectionManager* proj, TEveProjectable* model); + virtual void UpdateProjection(); + + void ProjectBuffer3D(); + + virtual void ComputeBBox(); + virtual void Paint(Option_t* option = ""); + + virtual void DumpPolys() const; + void DumpBuffer3D(); + + //rendering + virtual Bool_t CanEditMainColor() { return kTRUE; } + virtual Color_t GetLineColor() const { return fLineColor; } + + virtual Bool_t CanEditMainTransparency() { return kTRUE; } + virtual UChar_t GetMainTransparency() const { return fTransparency; } + virtual void SetMainTransparency(UChar_t t) { fTransparency = t; } + + virtual void SetFillColor(Pixel_t pixel) { fFillColor = Color_t(TColor::GetColor(pixel));} + virtual void SetLineColor(Pixel_t pixel) { fLineColor = Color_t(TColor::GetColor(pixel));} + + virtual void SetFillColor(Color_t c) { fFillColor = c; } + virtual void SetLineColor(Color_t c) { fLineColor = c; } + virtual void SetLineWidth(Double_t lw) {fLineWidth = lw;} + + ClassDef(TEvePolygonSetProjected,0); // Set of projected polygons with outline; typically produced from a TBuffer3D. + +}; + +#endif diff --git a/eve/inc/TEvePolygonSetProjectedEditor.h b/eve/inc/TEvePolygonSetProjectedEditor.h new file mode 100644 index 0000000000..963f71de01 --- /dev/null +++ b/eve/inc/TEvePolygonSetProjectedEditor.h @@ -0,0 +1,46 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEvePolygonSetProjectedEditor +#define ROOT_TEvePolygonSetProjectedEditor + +#include + +class TGNumberEntry; +class TGColorSelect; + +class TEvePolygonSetProjected; + +class TEvePolygonSetProjectedEditor : public TGedFrame +{ + TEvePolygonSetProjectedEditor(const TEvePolygonSetProjectedEditor&); // Not implemented + TEvePolygonSetProjectedEditor& operator=(const TEvePolygonSetProjectedEditor&); // Not implemented + +protected: + TEvePolygonSetProjected *fPS; // Model object. + + TGNumberEntry *fLineWidth; // TEveLine width widget. + TGColorSelect *fLineColor; // TEveLine color widget. + +public: + TEvePolygonSetProjectedEditor(const TGWindow* p=0, Int_t width=170, Int_t height=30, + UInt_t options=kChildFrame, Pixel_t back=GetDefaultFrameBackground()); + ~TEvePolygonSetProjectedEditor(); + + virtual void SetModel(TObject* obj); + + virtual void DoLineWidth(); + virtual void DoLineColor(Pixel_t color); + + ClassDef(TEvePolygonSetProjectedEditor, 0); // Editor for TEvePolygonSetProjected class. +}; + +#endif diff --git a/eve/inc/TEvePolygonSetProjectedGL.h b/eve/inc/TEvePolygonSetProjectedGL.h new file mode 100644 index 0000000000..ab43c00cd2 --- /dev/null +++ b/eve/inc/TEvePolygonSetProjectedGL.h @@ -0,0 +1,33 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEvePolygonSetProjectedGL +#define ROOT_TEvePolygonSetProjectedGL + +#include + +class TEvePolygonSetProjectedGL : public TGLObject +{ +protected: + virtual void DirectDraw(TGLRnrCtx & rnrCtx) const; + +public: + TEvePolygonSetProjectedGL(); + virtual ~TEvePolygonSetProjectedGL(); + + virtual Bool_t SetModel(TObject* obj, const Option_t* opt=0); + virtual Bool_t IgnoreSizeForOfInterest() const { return kTRUE; } + virtual void SetBBox(); + + ClassDef(TEvePolygonSetProjectedGL,0); // GL-renderer for TEvePolygonSetProjected class. +}; + +#endif diff --git a/eve/inc/TEveProjectionBases.h b/eve/inc/TEveProjectionBases.h new file mode 100644 index 0000000000..89b17c13de --- /dev/null +++ b/eve/inc/TEveProjectionBases.h @@ -0,0 +1,87 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveProjectionBases +#define ROOT_TEveProjectionBases + +#include + +#include + +class TBuffer3D; + +class TEveProjected; +class TEveProjectionManager; + +//////////////////////////////////////////////////////////////// +// // +// TEveProjectable // +// // +// Abstract base class for non-linear projectable objects. // +// // +//////////////////////////////////////////////////////////////// + +class TEveProjectable +{ +private: + TEveProjectable(const TEveProjectable&); // Not implemented + TEveProjectable& operator=(const TEveProjectable&); // Not implemented + +protected: + std::list fProjectedList; // references to projected instances. + +public: + TEveProjectable(); + virtual ~TEveProjectable(); + + virtual TClass* ProjectedClass() const = 0; + + virtual void AddProjected(TEveProjected* p) { fProjectedList.push_back(p); } + virtual void RemoveProjected(TEveProjected* p) { fProjectedList.remove(p); } + + ClassDef(TEveProjectable, 0); // Abstract base class for classes that can be transformed with non-linear projections. +}; + + +//////////////////////////////////////////////////////////////// +// // +// TEveProjected // +// // +// Abstract base class for non-linear projected objects. // +// // +//////////////////////////////////////////////////////////////// + +class TEveProjected +{ +private: + TEveProjected(const TEveProjected&); // Not implemented + TEveProjected& operator=(const TEveProjected&); // Not implemented + +protected: + TEveProjectionManager *fProjector; // manager + TEveProjectable *fProjectable; // link to original object + Float_t fDepth; // z coordinate + +public: + TEveProjected(); + virtual ~TEveProjected(); + + virtual void SetProjection(TEveProjectionManager* proj, TEveProjectable* model); + virtual void UnRefProjectable(TEveProjectable* assumed_parent); + + virtual void SetDepth(Float_t d) { fDepth = d; } + + virtual void UpdateProjection() = 0; + + ClassDef(TEveProjected, 0); // Abstract base class for classes that hold results of a non-linear projection transformation. +}; + +#endif diff --git a/eve/inc/TEveProjectionManager.h b/eve/inc/TEveProjectionManager.h new file mode 100644 index 0000000000..8c5b253e80 --- /dev/null +++ b/eve/inc/TEveProjectionManager.h @@ -0,0 +1,83 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveProjectionManager +#define ROOT_TEveProjectionManager + +#include +#include + +#include +#include +#include + +class TEveProjectionManager : public TEveElementList, + public TAttBBox, + public TAtt3D +{ +private: + TEveProjectionManager(const TEveProjectionManager&); // Not implemented + TEveProjectionManager& operator=(const TEveProjectionManager&); // Not implemented + + TEveProjection* fProjection; // projection + + Bool_t fDrawCenter; // draw center of distortion + Bool_t fDrawOrigin; // draw origin + TEveVector fCenter; // center of distortion + + Int_t fSplitInfoMode; // tick-mark position + Int_t fSplitInfoLevel; // tick-mark density + Color_t fAxisColor; // color of axis + + Float_t fCurrentDepth; // z depth of object being projected + + virtual Bool_t ShouldImport(TEveElement* rnr_el); + +public: + TEveProjectionManager(); + virtual ~TEveProjectionManager(); + + void SetProjection(TEveProjection::PType_e type, Float_t distort=0); + TEveProjection* GetProjection() { return fProjection; } + + virtual void UpdateName(); + + void SetAxisColor(Color_t col) { fAxisColor = col; } + Color_t GetAxisColor() const { return fAxisColor; } + void SetSplitInfoMode(Int_t x) { fSplitInfoMode = x; } + Int_t GetSplitInfoMode() const { return fSplitInfoMode; } + void SetSplitInfoLevel(Int_t x) { fSplitInfoLevel = x; } + Int_t GetSplitInfoLevel() const { return fSplitInfoLevel; } + + void SetDrawCenter(Bool_t x){ fDrawCenter = x; } + Bool_t GetDrawCenter(){ return fDrawCenter; } + void SetDrawOrigin(Bool_t x){ fDrawOrigin = x; } + Bool_t GetDrawOrigin(){ return fDrawOrigin; } + + void SetCenter(Float_t x, Float_t y, Float_t z); + TEveVector& GetCenter(){return fCenter;} + + void SetCurrentDepth(Float_t d) { fCurrentDepth = d; } + Float_t GetCurrentDepth() const { return fCurrentDepth; } + + virtual Bool_t HandleElementPaste(TEveElement* el); + virtual void ImportElementsRecurse(TEveElement* rnr_el, TEveElement* parent); + virtual void ImportElements(TEveElement* rnr_el); + virtual void ProjectChildren(); + virtual void ProjectChildrenRecurse(TEveElement* rnr_el); + + virtual void ComputeBBox(); + virtual void Paint(Option_t* option = ""); + + ClassDef(TEveProjectionManager, 0); // Manager class for steering of projections and managing projected objects. +}; + +#endif diff --git a/eve/inc/TEveProjectionManagerEditor.h b/eve/inc/TEveProjectionManagerEditor.h new file mode 100644 index 0000000000..f5c0f2f505 --- /dev/null +++ b/eve/inc/TEveProjectionManagerEditor.h @@ -0,0 +1,76 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveProjectionManagerEditor +#define ROOT_TEveProjectionManagerEditor + +#include + +class TGComboBox; +class TGCheckButton; +class TGNumberEntry; +class TGColorSelect; + +class TEveProjectionManager; +class TEveGValuator; + +class TEveProjectionManagerEditor : public TGedFrame +{ +private: + TEveProjectionManagerEditor(const TEveProjectionManagerEditor&); // Not implemented + TEveProjectionManagerEditor& operator=(const TEveProjectionManagerEditor&); // Not implemented + +protected: + TEveProjectionManager *fM; // Model object. + + // projection + TGComboBox *fType; + TEveGValuator *fDistortion; + TEveGValuator *fFixedRadius; + TEveGValuator *fCurrentDepth; + + // center + TGVerticalFrame *fCenterFrame; // Parent frame for projection center interface. + TGCheckButton *fDrawCenter; + TGCheckButton *fDrawOrigin; + TEveGValuator *fCenterX; + TEveGValuator *fCenterY; + TEveGValuator *fCenterZ; + + // axis + TGColorSelect *fAxisColor; + TGComboBox *fSIMode; + TGNumberEntry *fSILevel; + +public: + TEveProjectionManagerEditor(const TGWindow* p=0, Int_t width=170, Int_t height=30, UInt_t options = kChildFrame, Pixel_t back=GetDefaultFrameBackground()); + virtual ~TEveProjectionManagerEditor(){} + + virtual void SetModel(TObject* obj); + + // Declare callback/slot methods + + void DoSplitInfoMode(Int_t type); + void DoSplitInfoLevel(); + void DoAxisColor(Pixel_t pixel); + + void DoType(Int_t type); + void DoDistortion(); + void DoFixedRadius(); + void DoCurrentDepth(); + void DoDrawCenter(); + void DoDrawOrigin(); + void DoCenter(); + + ClassDef(TEveProjectionManagerEditor, 0); // Editor for TEveProjectionManager class. +}; + +#endif diff --git a/eve/inc/TEveProjectionManagerGL.h b/eve/inc/TEveProjectionManagerGL.h new file mode 100644 index 0000000000..8cb4a3f0c8 --- /dev/null +++ b/eve/inc/TEveProjectionManagerGL.h @@ -0,0 +1,69 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveProjectionManagerGL +#define ROOT_TEveProjectionManagerGL + +#include +#include + +class TGLViewer; +class TGLScene; +class TGLText; + +class TEveProjectionManager; + +class TEveProjectionManagerGL : public TGLObject +{ +public: + typedef std::list TMList_t; + +private: + TEveProjectionManagerGL(const TEveProjectionManagerGL&); // Not implemented + TEveProjectionManagerGL& operator=(const TEveProjectionManagerGL&); // Not implemented + + mutable TMList_t fPos; + mutable TMList_t fVals; + + mutable Float_t fRange; + Float_t fLabelSize; + Float_t fLabelOff; + Float_t fTMSize; + + void DrawTickMarks(Float_t tms) const; + void DrawHInfo() const; + void DrawVInfo() const; + const char* GetText(Float_t) const; + + void SplitInterval(Int_t axis) const; + void SplitIntervalByPos(Float_t min, Float_t max, Int_t axis, Int_t level)const; + void SplitIntervalByVal(Float_t min, Float_t max, Int_t axis, Int_t level)const; + + void SetRange(Float_t val, Int_t axis) const; + +protected: + TEveProjectionManager *fM; // Model object. + TGLText *fText; // Text renderer for axis labels. + + virtual void DirectDraw(TGLRnrCtx & rnrCtx) const; + +public: + TEveProjectionManagerGL(); + virtual ~TEveProjectionManagerGL(); + + virtual Bool_t SetModel(TObject* obj, const Option_t* opt=0); + virtual void SetBBox(); + Bool_t IgnoreSizeForOfInterest() const { return kTRUE;} + + ClassDef(TEveProjectionManagerGL, 0); // GL-renderer for TEveProjectionManager. +}; + +#endif diff --git a/eve/inc/TEveProjections.h b/eve/inc/TEveProjections.h new file mode 100644 index 0000000000..05323d9be1 --- /dev/null +++ b/eve/inc/TEveProjections.h @@ -0,0 +1,127 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveProjections +#define ROOT_TEveProjections + +#include + +//////////////////////////////////////////////////////////////// +// // +// TEveProjection // +// // +//////////////////////////////////////////////////////////////// + +class TEveProjection +{ +public: + enum PType_e { PT_Unknown, PT_CFishEye, PT_RhoZ }; // type + enum PProc_e { PP_Plane, PP_Distort, PP_Full }; // procedure + enum GeoMode_e { GM_Unknown, GM_Polygons, GM_Segments }; // reconstruction of geometry + +protected: + PType_e fType; // type + GeoMode_e fGeoMode; // way of polygon reconstruction + const char* fName; // name + + TEveVector fCenter; // center of distortion + TEveVector fZeroPosVal; // projected origin (0, 0, 0) + + Float_t fDistortion; // distortion + Float_t fFixedRadius; // projected radius independent of distortion + Float_t fScale; // scale factor to keep projected radius fixed + TEveVector fUpLimit; // convergence of point +infinity + TEveVector fLowLimit; // convergence of point -infinity + +public: + TEveProjection(TEveVector& center); + virtual ~TEveProjection(){} + + virtual void ProjectPoint(Float_t&, Float_t&, Float_t&, PProc_e p = PP_Full ) = 0; + virtual void ProjectPointFv(Float_t* v){ ProjectPoint(v[0], v[1], v[2]); } + virtual void ProjectVector(TEveVector& v); + + const char* GetName(){return fName;} + void SetName(const char* txt){ fName = txt; } + + virtual void SetCenter(TEveVector& v){ fCenter = v; UpdateLimit();} + virtual Float_t* GetProjectedCenter() { return fCenter.c_vec(); } + + void SetType(PType_e t){fType = t;} + PType_e GetType(){return fType;} + + void SetGeoMode(GeoMode_e m){fGeoMode = m;} + GeoMode_e GetGeoMode(){return fGeoMode;} + + void UpdateLimit(); + void SetDistortion(Float_t d); + Float_t GetDistortion(){return fDistortion;} + void SetFixedRadius(Float_t x); + Float_t GetFixedRadius(){return fFixedRadius;} + + virtual Bool_t AcceptSegment(TEveVector&, TEveVector&, Float_t /*tolerance*/) { return kTRUE; } + virtual void SetDirectionalVector(Int_t screenAxis, TEveVector& vec); + + // utils to draw axis + virtual Float_t GetValForScreenPos(Int_t ax, Float_t value); + virtual Float_t GetScreenVal(Int_t ax, Float_t value); + Float_t GetLimit(Int_t i, Bool_t pos) { return pos ? fUpLimit[i] : fLowLimit[i]; } + + static Float_t fgEps; // resolution of projected points + + ClassDef(TEveProjection, 0); // Base for specific classes that implement non-linear projections. +}; + + +//////////////////////////////////////////////////////////////// +// // +// TEveRhoZProjection // +// // +//////////////////////////////////////////////////////////////// + +class TEveRhoZProjection: public TEveProjection +{ +private: + TEveVector fProjectedCenter; // projected center of distortion. + +public: + TEveRhoZProjection(TEveVector& center) : TEveProjection(center) { fType = PT_RhoZ; fName="RhoZ"; } + virtual ~TEveRhoZProjection() {} + + virtual Bool_t AcceptSegment(TEveVector& v1, TEveVector& v2, Float_t tolerance); + virtual void ProjectPoint(Float_t& x, Float_t& y, Float_t& z, PProc_e proc = PP_Full); + virtual void SetDirectionalVector(Int_t screenAxis, TEveVector& vec); + + virtual void SetCenter(TEveVector& center); + virtual Float_t* GetProjectedCenter() { return fProjectedCenter.c_vec(); } + + ClassDef(TEveRhoZProjection, 0); // Rho/Z non-linear projection. +}; + + +//////////////////////////////////////////////////////////////// +// // +// TEveCircularFishEyeProjection // +// // +//////////////////////////////////////////////////////////////// + +class TEveCircularFishEyeProjection : public TEveProjection +{ +public: + TEveCircularFishEyeProjection(TEveVector& center):TEveProjection(center) { fType = PT_CFishEye; fGeoMode = GM_Polygons; fName="CircularFishEye"; } + virtual ~TEveCircularFishEyeProjection() {} + + virtual void ProjectPoint(Float_t& x, Float_t& y, Float_t& z, PProc_e proc = PP_Full); + + ClassDef(TEveCircularFishEyeProjection, 0); // XY non-linear projection. +}; + +#endif diff --git a/eve/inc/TEveQuadSet.h b/eve/inc/TEveQuadSet.h new file mode 100644 index 0000000000..b6710e31b0 --- /dev/null +++ b/eve/inc/TEveQuadSet.h @@ -0,0 +1,131 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveQuadSet +#define ROOT_TEveQuadSet + +#include + +class TRandom; + +class TEveQuadSet : public TEveDigitSet +{ + friend class TEveQuadSetGL; + + TEveQuadSet(const TEveQuadSet&); // Not implemented + TEveQuadSet& operator=(const TEveQuadSet&); // Not implemented + +public: + enum QuadType_e + { + QT_Undef, // unknown-ignored + QT_FreeQuad, // arbitrary quad: specify 4*(x,y,z) quad corners + QT_RectangleXY, // rectangle in x-y plane: specify x, y, z, w, h + QT_RectangleXZ, // rectangle in x-z plane: specify x, y, z, w, h + QT_RectangleYZ, // rectangle in y-z plane: specify x, y, z, w, h + QT_RectangleXYFixedDim, // rectangle in x-y plane: specify x, y, z; w, h taken from fDefWidth/Height + QT_RectangleXYFixedZ, // rectangle in x-y plane: specify x, y, w, h; z taken from fDefCoord + QT_RectangleXZFixedY, // rectangle in x-z plane: specify x, z, w, h; y taken from fDefCoord + QT_RectangleYZFixedX, // rectangle in y-z plane: specify y, z, w, h; x taken from fDefWidth/Height/Coord + QT_RectangleXYFixedDimZ, // rectangle in x-y plane: specify x, y; w, h, z taken from fDefWidth/Height/Coord + QT_RectangleXZFixedDimY, // rectangle in x-z plane: specify x, z; w, h, y taken from fDefWidth/Height/Coord + QT_RectangleYZFixedDimX, // rectangle in y-z plane: specify y, z; w, h, x taken from fDefWidth/Height/Coord + QT_Rectangle_End, + // line modes (needed for uniform handling of silicon-strip digits) + QT_LineXYFixedZ, // line in x-y plane: specify x, y, w(dx), h(dy); z taken from fDefCoord + QT_LineXZFixedY, // line in x-z plane: specify x, z, w(dx), h(dz); y taken from fDefCoord + QT_Line_End, + // hexagon modes + QT_HexagonXY, // horizontal hexagon: specify x, y, z, r + QT_HexagonYX, // vertical hexagon: specify x, y, z, r + QT_Hexagon_End + // circle modes: + // QT_CircleXY, // specify r, z + // QT_CircleXYFixedZ, // specify r + // QT_CircleXYFixedR, // specify z + }; + + enum RenderMode_e { RM_AsIs, RM_TEveLine, RM_Fill }; + +protected: + + struct QFreeQuad : public DigitBase { Float_t fVertices[12]; }; + + struct QOrigin : public DigitBase { Float_t fA, fB; }; + + struct QRectFixDimC : public QOrigin { }; + + struct QRectFixDim : public QRectFixDimC { Float_t fC; }; + + struct QRectFixC : public QRectFixDimC { Float_t fW, fH; }; + + struct QRect : public QRectFixDim { Float_t fW, fH; }; + + struct QLineFixC : public QOrigin { Float_t fDx, fDy; }; + + struct QHex : public QOrigin { Float_t fC, fR; }; + +protected: + QuadType_e fQuadType; + + Float_t fDefWidth; // Breadth assigned to first coordinate (A) + Float_t fDefHeight; // Breadth assigned to second coordinate (B) + Float_t fDefCoord; // Default value for third coordinate (C) + + static Int_t SizeofAtom(QuadType_e qt); + +public: + TEveQuadSet(const Text_t* n="TEveQuadSet", const Text_t* t=""); + TEveQuadSet(QuadType_e quadType, Bool_t valIsCol, Int_t chunkSize, + const Text_t* n="TEveQuadSet", const Text_t* t=""); + virtual ~TEveQuadSet(); + + void Reset(QuadType_e quadType, Bool_t valIsCol, Int_t chunkSize); + + Float_t GetDefWidth() const { return fDefWidth; } + Float_t GetDefHeight() const { return fDefHeight; } + Float_t GetDefCoord() const { return fDefCoord; } + + void SetDefWidth(Float_t v) { fDefWidth = v ; } + void SetDefHeight(Float_t v) { fDefHeight = v ; } + void SetDefCoord(Float_t v) { fDefCoord = v ; } + + // -------------------------------- + + void AddQuad(Float_t* verts); + + void AddQuad(Float_t a, Float_t b); + void AddQuad(Float_t a, Float_t b, Float_t c); + void AddQuad(Float_t a, Float_t b, Float_t w, Float_t h); + void AddQuad(Float_t a, Float_t b, Float_t c, Float_t w, Float_t h); + + void AddLine(Float_t a, Float_t b, Float_t w, Float_t h); + + void AddHexagon(Float_t a, Float_t b, Float_t z, Float_t r); + + // Wrappers to make transition to TEveDigitSet as base easier + void QuadValue(Int_t value) { DigitValue(value); } + void QuadColor(Color_t ci) { DigitColor(ci); } + void QuadColor(UChar_t r, UChar_t g, UChar_t b, UChar_t a=255) { DigitColor(r, g, b, a); } + void QuadId(TObject* id) { DigitId(id); } + + // -------------------------------- + + // void Test(Int_t nquads); + + virtual void ComputeBBox(); + + // virtual void Paint(Option_t* option=""); + + ClassDef(TEveQuadSet, 1); // Collection of 2D primitives (rectangles, hexagons, or lines); each primitive can be assigned a signal value and a TRef. +}; + +#endif diff --git a/eve/inc/TEveQuadSetGL.h b/eve/inc/TEveQuadSetGL.h new file mode 100644 index 0000000000..24c21660ea --- /dev/null +++ b/eve/inc/TEveQuadSetGL.h @@ -0,0 +1,51 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveQuadSetGL +#define ROOT_TEveQuadSetGL + +#include +#include + +class TEveQuadSetGL : public TGLObject +{ + TEveQuadSetGL(const TEveQuadSetGL&); // Not implemented + TEveQuadSetGL& operator=(const TEveQuadSetGL&); // Not implemented + +protected: + TEveQuadSet* fM; + + virtual void DirectDraw(TGLRnrCtx & rnrCtx) const; + + Bool_t SetupColor(const TEveDigitSet::DigitBase& q) const; + + void RenderQuads(TGLRnrCtx & rnrCtx) const; + void RenderLines(TGLRnrCtx & rnrCtx) const; + void RenderHexagons(TGLRnrCtx & rnrCtx) const; + +public: + TEveQuadSetGL(); + virtual ~TEveQuadSetGL(); + + virtual Bool_t ShouldDLCache(const TGLRnrCtx & rnrCtx) const; + + virtual Bool_t SetModel(TObject* obj, const Option_t* opt=0); + virtual void SetBBox(); + + virtual Bool_t IgnoreSizeForOfInterest() const { return kTRUE; } + + virtual Bool_t SupportsSecondarySelect() const { return kTRUE; } + virtual void ProcessSelection(TGLRnrCtx & rnrCtx, TGLSelectRecord & rec); + + ClassDef(TEveQuadSetGL, 0); // GL-renderer for TEveQuadSet class. +}; + +#endif diff --git a/eve/inc/TEveRGBAPalette.h b/eve/inc/TEveRGBAPalette.h new file mode 100644 index 0000000000..05b302e442 --- /dev/null +++ b/eve/inc/TEveRGBAPalette.h @@ -0,0 +1,207 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveRGBAPalette +#define ROOT_TEveRGBAPalette + +#include + +#include + +class TEveRGBAPalette : public TObject, public TEveRefCnt +{ + friend class TEveRGBAPaletteEditor; + friend class TEveRGBAPaletteSubEditor; + +public: + enum LimitAction_e { LA_Cut, LA_Mark, LA_Clip, LA_Wrap }; + +private: + TEveRGBAPalette(const TEveRGBAPalette&); // Not implemented + TEveRGBAPalette& operator=(const TEveRGBAPalette&); // Not implemented + +protected: + Int_t fLowLimit; // Low limit for Min/Max values (used by editor) + Int_t fHighLimit; // High limit for Min/Max values (used by editor) + Int_t fMinVal; + Int_t fMaxVal; + Int_t fNBins; + + Bool_t fInterpolate; + Bool_t fShowDefValue; + Int_t fUnderflowAction; + Int_t fOverflowAction; + + Color_t fDefaultColor; // Color for when value is not specified + UChar_t fDefaultRGBA[4]; + Color_t fUnderColor; // Underflow color + UChar_t fUnderRGBA[4]; + Color_t fOverColor; // Overflow color + UChar_t fOverRGBA[4]; + + mutable UChar_t* fColorArray; //[4*fNBins] + + void SetupColor(Int_t val, UChar_t* pix) const; + + static TEveRGBAPalette* fgDefaultPalette; + +public: + TEveRGBAPalette(); + TEveRGBAPalette(Int_t min, Int_t max, Bool_t interp=kFALSE, Bool_t showdef=kTRUE); + virtual ~TEveRGBAPalette(); + + void SetupColorArray() const; + void ClearColorArray(); + + Bool_t WithinVisibleRange(Int_t val) const; + const UChar_t* ColorFromValue(Int_t val) const; + void ColorFromValue(Int_t val, UChar_t* pix, Bool_t alpha=kTRUE) const; + Bool_t ColorFromValue(Int_t val, Int_t defVal, UChar_t* pix, Bool_t alpha=kTRUE) const; + + Int_t GetMinVal() const { return fMinVal; } + Int_t GetMaxVal() const { return fMaxVal; } + + void SetLimits(Int_t low, Int_t high); + void SetLimitsScaleMinMax(Int_t low, Int_t high); + void SetMinMax(Int_t min, Int_t max); + void SetMin(Int_t min); + void SetMax(Int_t max); + + Int_t GetLowLimit() const { return fLowLimit; } + Int_t GetHighLimit() const { return fHighLimit; } + + // ================================================================ + + Bool_t GetInterpolate() const { return fInterpolate; } + void SetInterpolate(Bool_t b); + + Bool_t GetShowDefValue() const { return fShowDefValue; } + void SetShowDefValue(Bool_t v) { fShowDefValue = v; } + + Int_t GetUnderflowAction() const { return fUnderflowAction; } + Int_t GetOverflowAction() const { return fOverflowAction; } + void SetUnderflowAction(Int_t a) { fUnderflowAction = a; } + void SetOverflowAction(Int_t a) { fOverflowAction = a; } + + // ================================================================ + + Color_t GetDefaultColor() const { return fDefaultColor; } + Color_t* PtrDefaultColor() { return &fDefaultColor; } + UChar_t* GetDefaultRGBA() { return fDefaultRGBA; } + const UChar_t* GetDefaultRGBA() const { return fDefaultRGBA; } + + void SetDefaultColor(Color_t ci); + void SetDefaultColor(Pixel_t pix); + void SetDefaultColor(UChar_t r, UChar_t g, UChar_t b, UChar_t a=255); + + // ---------------------------------------------------------------- + + Color_t GetUnderColor() const { return fUnderColor; } + Color_t* PtrUnderColor() { return &fUnderColor; } + UChar_t* GetUnderRGBA() { return fUnderRGBA; } + const UChar_t* GetUnderRGBA() const { return fUnderRGBA; } + + void SetUnderColor(Color_t ci); + void SetUnderColor(Pixel_t pix); + void SetUnderColor(UChar_t r, UChar_t g, UChar_t b, UChar_t a=255); + + // ---------------------------------------------------------------- + + Color_t GetOverColor() const { return fOverColor; } + Color_t* PtrOverColor() { return &fOverColor; } + UChar_t* GetOverRGBA() { return fOverRGBA; } + const UChar_t* GetOverRGBA() const { return fOverRGBA; } + + void SetOverColor(Color_t ci); + void SetOverColor(Pixel_t pix); + void SetOverColor(UChar_t r, UChar_t g, UChar_t b, UChar_t a=255); + + // ================================================================ + + // ?? Should we emit some *SIGNALS* ?? + // ?? Should we have a RendererTimeStamp ?? + + ClassDef(TEveRGBAPalette, 1); // A generic, speed-optimised mapping from value to RGBA color supporting different wrapping and range truncation modes. +}; + + +/******************************************************************************/ +// Inlines for TEveRGBAPalette +/******************************************************************************/ + +//______________________________________________________________________________ +inline Bool_t TEveRGBAPalette::WithinVisibleRange(Int_t val) const +{ + if ((val < fMinVal && fUnderflowAction == LA_Cut) || + (val > fMaxVal && fOverflowAction == LA_Cut)) + return kFALSE; + else + return kTRUE; +} + +//______________________________________________________________________________ +inline const UChar_t* TEveRGBAPalette::ColorFromValue(Int_t val) const +{ + // Here we expect that LA_Cut has been checked; we further check + // for LA_Wrap and LA_Clip otherwise we proceed as for LA_Mark. + + if (!fColorArray) SetupColorArray(); + if (val < fMinVal) { + if (fUnderflowAction == LA_Wrap) + val = (val+1-fMinVal)%fNBins + fMaxVal; + else if (fUnderflowAction == LA_Clip) + val = fMinVal; + else + return fUnderRGBA; + } + else if(val > fMaxVal) { + if (fOverflowAction == LA_Wrap) + val = (val-1-fMaxVal)%fNBins + fMinVal; + else if (fOverflowAction == LA_Clip) + val = fMaxVal; + else + return fOverRGBA; + } + return fColorArray + 4 * (val - fMinVal); +} + +//______________________________________________________________________________ +inline void TEveRGBAPalette::ColorFromValue(Int_t val, UChar_t* pix, Bool_t alpha) const +{ + const UChar_t* c = ColorFromValue(val); + pix[0] = c[0]; pix[1] = c[1]; pix[2] = c[2]; + if (alpha) pix[3] = c[3]; +} + +//______________________________________________________________________________ +inline Bool_t TEveRGBAPalette::ColorFromValue(Int_t val, Int_t defVal, UChar_t* pix, Bool_t alpha) const +{ + if (val == defVal) { + if (fShowDefValue) { + pix[0] = fDefaultRGBA[0]; + pix[1] = fDefaultRGBA[1]; + pix[2] = fDefaultRGBA[2]; + if (alpha) pix[3] = fDefaultRGBA[3]; + return kTRUE; + } else { + return kFALSE; + } + } + + if (WithinVisibleRange(val)) { + ColorFromValue(val, pix, alpha); + return kTRUE; + } else { + return kFALSE; + } +} + +#endif diff --git a/eve/inc/TEveRGBAPaletteEditor.h b/eve/inc/TEveRGBAPaletteEditor.h new file mode 100644 index 0000000000..b426611ac8 --- /dev/null +++ b/eve/inc/TEveRGBAPaletteEditor.h @@ -0,0 +1,89 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveRGBAPaletteEditor +#define ROOT_TEveRGBAPaletteEditor + +#include + +class TGCheckButton; +class TGColorSelect; +class TGComboBox; + +class TEveRGBAPalette; +class TEveGValuator; +class TEveGDoubleValuator; + +class TEveRGBAPaletteSubEditor : public TGVerticalFrame +{ +private: + TEveRGBAPaletteSubEditor(const TEveRGBAPaletteSubEditor&); // Not implemented + TEveRGBAPaletteSubEditor& operator=(const TEveRGBAPaletteSubEditor&); // Not implemented + +protected: + TEveRGBAPalette* fM; + + TGComboBox* fUnderflowAction; + TGColorSelect* fUnderColor; + TGComboBox* fOverflowAction; + TGColorSelect* fOverColor; + + TEveGDoubleValuator* fMinMax; + + TGCheckButton* fInterpolate; + TGCheckButton* fShowDefValue; + TGColorSelect* fDefaultColor; + +public: + TEveRGBAPaletteSubEditor(const TGWindow* p); + virtual ~TEveRGBAPaletteSubEditor() {} + + void SetModel(TEveRGBAPalette* p); + + void Changed(); //*SIGNAL* + + void DoMinMax(); + + void DoInterpolate(); + void DoShowDefValue(); + void DoDefaultColor(Pixel_t color); + void DoUnderColor(Pixel_t color); + void DoOverColor(Pixel_t color); + void DoUnderflowAction(Int_t mode); + void DoOverflowAction(Int_t mode); + + ClassDef(TEveRGBAPaletteSubEditor, 1); // Sub-editor for TEveRGBAPalette class. +}; + + +/******************************************************************************/ +/******************************************************************************/ + +class TEveRGBAPaletteEditor : public TGedFrame +{ +private: + TEveRGBAPaletteEditor(const TEveRGBAPaletteEditor&); // Not implemented + TEveRGBAPaletteEditor& operator=(const TEveRGBAPaletteEditor&); // Not implemented + +protected: + TEveRGBAPalette* fM; + TEveRGBAPaletteSubEditor* fSE; + +public: + TEveRGBAPaletteEditor(const TGWindow* p=0, Int_t width=170, Int_t height=30, UInt_t options = kChildFrame, Pixel_t back=GetDefaultFrameBackground()); + virtual ~TEveRGBAPaletteEditor(); + + virtual void SetModel(TObject* obj); + + ClassDef(TEveRGBAPaletteEditor, 1); // Editor for TEveRGBAPalette class. +}; + +#endif diff --git a/eve/inc/TEveScene.h b/eve/inc/TEveScene.h new file mode 100644 index 0000000000..9f2129a90b --- /dev/null +++ b/eve/inc/TEveScene.h @@ -0,0 +1,82 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveScene +#define ROOT_TEveScene + +#include +#include + +class TGLScenePad; + + +/******************************************************************************/ +// TEveScene +/******************************************************************************/ + +class TEveScene : public TEveElementList +{ +private: + TEveScene(const TEveScene&); // Not implemented + TEveScene& operator=(const TEveScene&); // Not implemented + +protected: + TEvePad *fPad; + TGLScenePad *fGLScene; + + Bool_t fChanged; + Bool_t fSmartRefresh; + +public: + TEveScene(const Text_t* n="TEveScene", const Text_t* t=""); + virtual ~TEveScene(); + + virtual void CollectSceneParents(List_t& scenes); + + void Changed() { fChanged = kTRUE; } + Bool_t IsChanged() const { return fChanged; } + void Repaint(); + + TGLScenePad* GetGLScene() const { return fGLScene; } + void SetGLScene(TGLScenePad* s) { fGLScene = s; } + + virtual void SetName(const Text_t* n); + virtual void Paint(Option_t* option = ""); + + virtual const TGPicture* GetListTreeIcon() { return TEveElement::fgListTreeIcons[2]; } + + ClassDef(TEveScene, 0); // Reve representation of TGLScene. +}; + + +/******************************************************************************/ +// TEveSceneList +/******************************************************************************/ + +class TEveSceneList : public TEveElementList +{ +private: + TEveSceneList(const TEveSceneList&); // Not implemented + TEveSceneList& operator=(const TEveSceneList&); // Not implemented + +protected: + +public: + TEveSceneList(const Text_t* n="TEveSceneList", const Text_t* t=""); + virtual ~TEveSceneList(); + + void RepaintChangedScenes(); + void RepaintAllScenes(); + + ClassDef(TEveSceneList, 0); // List of Scenes providing common operations on TEveScene collections. +}; + +#endif diff --git a/eve/inc/TEveSceneInfo.h b/eve/inc/TEveSceneInfo.h new file mode 100644 index 0000000000..9f4183f7bd --- /dev/null +++ b/eve/inc/TEveSceneInfo.h @@ -0,0 +1,53 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveSceneInfo +#define ROOT_TEveSceneInfo + +#include + +class TGLSceneBase; +class TGLSceneInfo; + +class TEveViewer; +class TEveScene; + +class TEveSceneInfo : public TEveElement, + public TNamed +{ +private: + TEveSceneInfo(const TEveSceneInfo&); // Not implemented + TEveSceneInfo& operator=(const TEveSceneInfo&); // Not implemented + +protected: + TEveViewer *fViewer; + TEveScene *fScene; + TGLSceneInfo *fGLSceneInfo; + +public: + TEveSceneInfo(TEveViewer* viewer, TEveScene* scene, TGLSceneInfo* sinfo); + virtual ~TEveSceneInfo(); + + TEveViewer * GetViewer() const { return fViewer; } + TEveScene * GetScene() const { return fScene; } + TGLSceneInfo * GetGLSceneInfo() const { return fGLSceneInfo; } + TGLSceneBase * GetGLScene() const; + + virtual void SetRnrSelf(Bool_t rnr); + virtual void SetRnrState(Bool_t rnr); + + virtual Bool_t AcceptElement(TEveElement* el); + virtual Bool_t HandleElementPaste(TEveElement* el); + + ClassDef(TEveSceneInfo, 0); // TEveUtil representation of TGLSceneInfo. +}; + +#endif diff --git a/eve/inc/TEveStraightLineSet.h b/eve/inc/TEveStraightLineSet.h new file mode 100644 index 0000000000..04d076f7d5 --- /dev/null +++ b/eve/inc/TEveStraightLineSet.h @@ -0,0 +1,141 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveStraightLineSet +#define ROOT_TEveStraightLineSet + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +class TRandom; + +class TEveStraightLineSet : public TEveElement, + public TEveProjectable, + public TNamed, + public TQObject, + public TAtt3D, + public TAttLine, + public TAttMarker, + public TAttBBox +{ +private: + TEveStraightLineSet(const TEveStraightLineSet&); // Not implemented + TEveStraightLineSet& operator=(const TEveStraightLineSet&); // Not implemented + +public: + struct TEveLine + { + Float_t fV1[3]; + Float_t fV2[3]; + TRef fRef; + + TEveLine(Float_t x1, Float_t y1, Float_t z1,Float_t x2, Float_t y2, Float_t z2) + { + fV1[0] = x1, fV1[1] = y1, fV1[2] = z1; + fV2[0] = x2, fV2[1] = y2, fV2[2] = z2; + } + }; + + struct Marker + { + Int_t fLineID; + Float_t fPos; + TRef fRef; + + Marker(Int_t lineID, Float_t pos) : fLineID(lineID), fPos(pos) {}; + }; + +protected: + TEveChunkManager fLinePlex; + TEveChunkManager fMarkerPlex; + + Bool_t fOwnLinesIds; //Flag specifying if id-objects are owned by the TEveQuadSet + Bool_t fOwnMarkersIds; //Flag specifying if id-objects are owned by the TEveQuadSet + + Bool_t fRnrMarkers; + Bool_t fRnrLines; + + TEveLine* fLastLine; //! + + Bool_t fTrans; + TEveTrans fHMTrans; +public: + TEveStraightLineSet(const Text_t* n="StraightLine", const Text_t* t=""); + virtual ~TEveStraightLineSet() {} + + virtual Bool_t CanEditMainHMTrans() { return kTRUE; } + virtual TEveTrans* PtrMainHMTrans() { return &fHMTrans; } + + TEveTrans& RefHMTrans() { return fHMTrans; } + void SetTransMatrix(Double_t* carr) { fHMTrans.SetFrom(carr); } + void SetTransMatrix(const TGeoMatrix& mat) { fHMTrans.SetFrom(mat); } + + + virtual void SetLineColor(Color_t col) { SetMainColor(col); } + + + void AddLine(Float_t x1, Float_t y1, Float_t z1, Float_t x2, Float_t y2, Float_t z2); + void AddMarker(Int_t lineID, Float_t pos); + + TEveChunkManager& GetLinePlex() { return fLinePlex; } + TEveChunkManager& GetMarkerPlex() { return fMarkerPlex; } + + virtual void ComputeBBox(); + virtual void Paint(Option_t* option=""); + + virtual void SetRnrMarkers(Bool_t x) {fRnrMarkers = x;} + virtual Bool_t GetRnrMarkers(){return fRnrMarkers;} + + virtual void SetRnrLines(Bool_t x) {fRnrLines = x;} + virtual Bool_t GetRnrLines(){return fRnrLines;} + + virtual TClass* ProjectedClass() const; + + ClassDef(TEveStraightLineSet, 1); // Set of straight lines with optional markers along the lines. +}; + + +/******************************************************************************/ + +class TEveStraightLineSetProjected : public TEveStraightLineSet, + public TEveProjected +{ +private: + TEveStraightLineSetProjected(const TEveStraightLineSetProjected&); // Not implemented + TEveStraightLineSetProjected& operator=(const TEveStraightLineSetProjected&); // Not implemented + +public: + TEveStraightLineSetProjected(); + virtual ~TEveStraightLineSetProjected() {} + + virtual Bool_t CanEditMainHMTrans() { return kFALSE; } + + virtual void SetProjection(TEveProjectionManager* proj, TEveProjectable* model); + + virtual void UpdateProjection(); + + ClassDef(TEveStraightLineSetProjected, 1); // Projected copy of a TEveStraightLineSet. +}; + +#endif diff --git a/eve/inc/TEveStraightLineSetEditor.h b/eve/inc/TEveStraightLineSetEditor.h new file mode 100644 index 0000000000..b6884e79b6 --- /dev/null +++ b/eve/inc/TEveStraightLineSetEditor.h @@ -0,0 +1,49 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveStraightLineSetEditor +#define ROOT_TEveStraightLineSetEditor + +#include + +class TGCheckButton; +class TGNumberEntry; +class TGColorSelect; + +class TEveStraightLineSet; + +class TEveStraightLineSetEditor : public TGedFrame +{ +private: + TEveStraightLineSetEditor(const TEveStraightLineSetEditor&); // Not implemented + TEveStraightLineSetEditor& operator=(const TEveStraightLineSetEditor&); // Not implemented + +protected: + TEveStraightLineSet* fM; // fModel dynamic-casted to TEveStraightLineSetEditor + + // Declare widgets + TGCheckButton* fRnrMarkers; + TGCheckButton* fRnrLines; + +public: + TEveStraightLineSetEditor(const TGWindow* p=0, Int_t width=170, Int_t height=30, UInt_t options = kChildFrame, Pixel_t back=GetDefaultFrameBackground()); + virtual ~TEveStraightLineSetEditor(); + + virtual void SetModel(TObject* obj); + + // Declare callback/slot methods + void DoRnrMarkers(); + void DoRnrLines(); + + ClassDef(TEveStraightLineSetEditor, 1); // Editor for TEveStraightLineSet class. +}; + +#endif diff --git a/eve/inc/TEveStraightLineSetGL.h b/eve/inc/TEveStraightLineSetGL.h new file mode 100644 index 0000000000..bee2b0ede7 --- /dev/null +++ b/eve/inc/TEveStraightLineSetGL.h @@ -0,0 +1,50 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveStraightLineSetGL +#define ROOT_TEveStraightLineSetGL + +#include + +class TGLViewer; +class TGLScene; + +class TEveStraightLineSet; + +class TEveStraightLineSetGL : public TGLObject +{ +private: + TEveStraightLineSetGL(const TEveStraightLineSetGL&); // Not implemented + TEveStraightLineSetGL& operator=(const TEveStraightLineSetGL&); // Not implemented + +protected: + TEveStraightLineSet* fM; // fModel dynamic-casted to TEveStraightLineSetGL + + virtual void DirectDraw(TGLRnrCtx & rnrCtx) const; + +public: + TEveStraightLineSetGL(); + virtual ~TEveStraightLineSetGL(); + + virtual Bool_t SetModel(TObject* obj, const Option_t* opt=0); + virtual void SetBBox(); + + // To support two-level selectionvirtual + Bool_t IgnoreSizeForOfInterest() const { return kTRUE; } + + virtual Bool_t ShouldCache(TGLRnrCtx & rnrCtx) const; + virtual Bool_t SupportsSecondarySelect() const { return kTRUE; } + virtual void ProcessSelection(TGLRnrCtx & rnrCtx, TGLSelectRecord & rec); + + ClassDef(TEveStraightLineSetGL, 0); // GL-renderer for TEveStraightLineSet class. +}; + +#endif diff --git a/eve/inc/TEveTrack.h b/eve/inc/TEveTrack.h new file mode 100644 index 0000000000..a6d85ee26c --- /dev/null +++ b/eve/inc/TEveTrack.h @@ -0,0 +1,245 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveTrack +#define ROOT_TEveTrack + +#include + +#include +#include +#include + +#include +#include +#include + +class TEveTrackPropagator; +class TEveTrackList; + +class TEveTrack : public TEveLine, + public TQObject +{ + friend class TEveTrackPropagator; + friend class TEveTrackList; + friend class TEveTrackCounter; + friend class TEveTrackGL; + +public: + typedef std::vector vpPathMark_t; + typedef std::vector::iterator vpPathMark_i; + +protected: + TEveVector fV; // Starting vertex + TEveVector fP; // Starting momentum + Double_t fBeta; // Relativistic beta factor + Int_t fPdg; // PDG code + Int_t fCharge; // Charge in units of e0 + Int_t fLabel; // Simulation label + Int_t fIndex; // Reconstruction index + vpPathMark_t fPathMarks; // TEveVector of known points along the track + + TEveTrackPropagator *fPropagator; // Pointer to shared render-style + +public: + TEveTrack(); + TEveTrack(TParticle* t, Int_t label, TEveTrackPropagator* rs); + TEveTrack(TEveMCTrack* t, TEveTrackPropagator* rs); + TEveTrack(TEveRecTrack* t, TEveTrackPropagator* rs); + TEveTrack(const TEveTrack& t); + virtual ~TEveTrack(); + + virtual void SetStdTitle(); + + virtual void SetTrackParams(const TEveTrack& t); + virtual void SetPathMarks (const TEveTrack& t); + + virtual void MakeTrack(Bool_t recurse=kTRUE); + + TEveTrackPropagator* GetPropagator() const { return fPropagator; } + void SetPropagator(TEveTrackPropagator* rs); + void SetAttLineAttMarker(TEveTrackList* tl); + + Int_t GetPdg() const { return fPdg; } + void SetPdg(Int_t pdg) { fPdg = pdg; } + Int_t GetCharge() const { return fCharge; } + void SetCharge(Int_t chg) { fCharge = chg; } + Int_t GetLabel() const { return fLabel; } + void SetLabel(Int_t lbl) { fLabel = lbl; } + Int_t GetIndex() const { return fIndex; } + void SetIndex(Int_t idx) { fIndex = idx; } + + void AddPathMark(TEvePathMark* pm) { fPathMarks.push_back(pm); } + vpPathMark_t& GetPathMarksRef() { return fPathMarks; } + const vpPathMark_t& GetPathMarksRef() const { return fPathMarks; } + void SortPathMarksByTime(); + + //-------------------------------- + + void ImportHits(); // *MENU* + void ImportClusters(); // *MENU* + void ImportClustersFromIndex(); // *MENU* + void ImportKine(); // *MENU* + void ImportKineWithArgs(Bool_t importMother=kTRUE, Bool_t impDaugters=kTRUE, + Bool_t colorPdg =kTRUE, Bool_t recurse =kTRUE); // *MENU* + void PrintKineStack(); // *MENU* + void PrintPathMarks(); // *MENU* + + //-------------------------------- + + virtual void CtrlClicked(TEveTrack*); // *SIGNAL* + virtual void SetLineStyle(Style_t lstyle); + + virtual const TGPicture* GetListTreeIcon() { return fgListTreeIcons[4]; }; + + virtual TClass* ProjectedClass() const; + + ClassDef(TEveTrack, 1); // Track with given vertex, momentum and optional referece-points (path-marks) along its path. +}; + +/******************************************************************************/ +// TEveTrackList +/******************************************************************************/ + +class TEveTrackList : public TEveElementList, + public TEveProjectable, + public TAttMarker, + public TAttLine +{ + friend class TEveTrackListEditor; + +private: + TEveTrackList(const TEveTrackList&); // Not implemented + TEveTrackList& operator=(const TEveTrackList&); // Not implemented + + Bool_t fRecurse; // Recurse when propagating marker/line attributes to tracks. + +protected: + TEveTrackPropagator* fPropagator; // Basic track rendering parameters, not enforced to elements. + + Bool_t fRnrLine; // Render track as line. + Bool_t fRnrPoints; // Render track as points. + + Float_t fMinPt; // Minimum track pT for display selection. + Float_t fMaxPt; // Maximum track pT for display selection. + Float_t fLimPt; // Highest track pT in the container. + Float_t fMinP; // Minimum track p for display selection. + Float_t fMaxP; // Maximum track p for display selection. + Float_t fLimP; // Highest track p in the container. + + Float_t RoundMomentumLimit(Float_t x); + +public: + TEveTrackList(TEveTrackPropagator* rs=0); + TEveTrackList(const Text_t* name, TEveTrackPropagator* rs=0); + virtual ~TEveTrackList(); + + void MakeTracks(Bool_t recurse=kTRUE); + void FindMomentumLimits(TEveElement* el, Bool_t recurse); + + void SetPropagator(TEveTrackPropagator* rs); + TEveTrackPropagator* GetPropagator(){return fPropagator;} + + //-------------------------------- + + virtual void SetMainColor(Color_t c); + virtual void SetLineColor(Color_t c){SetMainColor(c);} + virtual void SetLineColor(Color_t c, TEveElement* el); + virtual void SetLineWidth(Width_t w); + virtual void SetLineWidth(Width_t w, TEveElement* el); + virtual void SetLineStyle(Style_t s); + virtual void SetLineStyle(Style_t s, TEveElement* el); + + virtual void SetMarkerColor(Color_t c); + virtual void SetMarkerColor(Color_t c, TEveElement* el); + virtual void SetMarkerSize(Size_t s); + virtual void SetMarkerSize(Size_t s, TEveElement* el); + virtual void SetMarkerStyle(Style_t s); + virtual void SetMarkerStyle(Style_t s, TEveElement* el); + + void SetRnrLine(Bool_t rnr); + void SetRnrLine(Bool_t rnr, TEveElement* el); + Bool_t GetRnrLine(){return fRnrLine;} + + void SetRnrPoints(Bool_t r); + void SetRnrPoints(Bool_t r, TEveElement* el); + Bool_t GetRnrPoints(){return fRnrPoints;} + + void SelectByPt(Float_t min_pt, Float_t max_pt); + void SelectByPt(Float_t min_pt, Float_t max_pt, TEveElement* el); + void SelectByP (Float_t min_p, Float_t max_p); + void SelectByP (Float_t min_p, Float_t max_p, TEveElement* el); + + //-------------------------------- + + TEveTrack* FindTrackByLabel(Int_t label); // *MENU* + TEveTrack* FindTrackByIndex(Int_t index); // *MENU* + + void ImportHits(); // *MENU* + void ImportClusters(); // *MENU* + + virtual TClass* ProjectedClass() const; + + ClassDef(TEveTrackList, 1); // A list of tracks supporting change of common attributes and selection based on track parameters. +}; + + +/******************************************************************************/ +// TEveTrackCounter +/******************************************************************************/ + +class TEveTrackCounter : public TEveElement, public TNamed +{ + friend class TEveTrackCounterEditor; + +public: + enum ClickAction_e { CA_PrintTrackInfo, CA_ToggleTrack }; + +private: + TEveTrackCounter(const TEveTrackCounter&); // Not implemented + TEveTrackCounter& operator=(const TEveTrackCounter&); // Not implemented + +protected: + Int_t fBadLineStyle; // TEveLine-style used for secondary/bad tracks. + Int_t fClickAction; // Action to take when a track is ctrl-clicked. + + Int_t fEventId; // Current event-id. + + Int_t fAllTracks; // Counter of all tracks. + Int_t fGoodTracks; // Counter of good tracks. + + TList fTrackLists; // List of TrackLists registered for management. + +public: + TEveTrackCounter(const Text_t* name="TEveTrackCounter", const Text_t* title=""); + virtual ~TEveTrackCounter(); + + Int_t GetEventId() const { return fEventId; } + void SetEventId(Int_t id) { fEventId = id; } + + void Reset(); + + void RegisterTracks(TEveTrackList* tlist, Bool_t goodTracks); + + void DoTrackAction(TEveTrack* track); + + Int_t GetClickAction() const { return fClickAction; } + void SetClickAction(Int_t a) { fClickAction = a; } + + void OutputEventTracks(FILE* out=0); + + static TEveTrackCounter* fgInstance; + + ClassDef(TEveTrackCounter, 1); // Class for selection of good/primary tracks with basic processing functionality. +}; + + +#endif diff --git a/eve/inc/TEveTrackEditor.h b/eve/inc/TEveTrackEditor.h new file mode 100644 index 0000000000..a77d90bdf2 --- /dev/null +++ b/eve/inc/TEveTrackEditor.h @@ -0,0 +1,141 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveTrackEditors +#define ROOT_TEveTrackEditors + +#include + +class TGButton; +class TGCheckButton; +class TGNumberEntry; +class TGColorSelect; +class TGComboBox; + +class TEveGValuator; +class TEveGDoubleValuator; +class TEveTrackPropagatorSubEditor; +class TEveTrack; +class TEveTrackList; + + +/******************************************************************************/ +// TEveTrackEditor +/******************************************************************************/ + +class TEveTrackEditor : public TGedFrame +{ +private: + TEveTrackEditor(const TEveTrackEditor&); // Not implemented + TEveTrackEditor& operator=(const TEveTrackEditor&); // Not implemented + +protected: + TEveTrack *fM; + TGTextButton *fRSEditor; +public: + TEveTrackEditor(const TGWindow* p=0, Int_t width=170, Int_t height=30, + UInt_t options=kChildFrame, Pixel_t back=GetDefaultFrameBackground()); + ~TEveTrackEditor(){} + + virtual void SetModel(TObject* obj); + void DoEditPropagator(); + + ClassDef(TEveTrackEditor, 0); // Editor for TEveTrack class. +}; + + +/******************************************************************************/ +// TEveTrackListEditor +/******************************************************************************/ + +class TEveTrackListEditor : public TGedFrame +{ +private: + TEveTrackListEditor(const TEveTrackListEditor&); // Not implemented + TEveTrackListEditor& operator=(const TEveTrackListEditor&); // Not implemented + + void CreateRefTab(); +protected: + TGVerticalFrame *fRefs; + + TEveTrackList *fTC; // fModel dynamic-casted to TEveTrackListEditor + + TGCheckButton *fRnrLine; + TGCheckButton *fRnrPoints; + + TEveGDoubleValuator *fPtRange; + TEveGDoubleValuator *fPRange; + + TEveTrackPropagatorSubEditor *fRSSubEditor; + +public: + TEveTrackListEditor(const TGWindow* p=0, Int_t width=170, Int_t height=30, + UInt_t options=kChildFrame, Pixel_t back=GetDefaultFrameBackground()); + ~TEveTrackListEditor(); + + void CreateRefsTab(); + virtual void SetModel(TObject* obj); + + void DoRnrLine(); + void DoRnrPoints(); + + void DoPtRange(); + void DoPRange(); + + ClassDef(TEveTrackListEditor, 0); // Editor for TEveTrackList class. +}; + + +/******************************************************************************/ +// TEveTrackCounterEditor +/******************************************************************************/ + +class TEveTrackCounter; + +class TEveTrackCounterEditor : public TGedFrame +{ +private: + TEveTrackCounterEditor(const TEveTrackCounterEditor&); // Not implemented + TEveTrackCounterEditor& operator=(const TEveTrackCounterEditor&); // Not implemented + +protected: + TEveTrackCounter *fM; // Model object. + + // Declare widgets + TGComboBox *fClickAction; + TGLabel *fInfoLabel; + TGNumberEntry *fEventId; + +public: + TEveTrackCounterEditor(const TGWindow* p=0, Int_t width=170, Int_t height=30, + UInt_t options = kChildFrame, Pixel_t back=GetDefaultFrameBackground()); + virtual ~TEveTrackCounterEditor(); + + virtual void SetModel(TObject* obj); + + void DoOrtoXY(); + void DoOrtoZY(); + void DoPersp(); + + void DoPrev(); + void DoNext(); + void DoSetEvent(); + + void DoPrintReport(); + void DoFileReport(); + void DoShowHistos(); + + void DoClickAction(Int_t); + + ClassDef(TEveTrackCounterEditor, 0); // Editor for TEveTrackCounter class. +}; + +#endif diff --git a/eve/inc/TEveTrackGL.h b/eve/inc/TEveTrackGL.h new file mode 100644 index 0000000000..08aa836165 --- /dev/null +++ b/eve/inc/TEveTrackGL.h @@ -0,0 +1,46 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveTrackGL +#define ROOT_TEveTrackGL + +#include + +class TGLViewer; +class TGLScene; + +class TEveTrack; + +class TEveTrackGL : public TEveLineGL +{ +private: + TEveTrackGL(const TEveTrackGL&); // Not implemented + TEveTrackGL& operator=(const TEveTrackGL&); // Not implemented + +protected: + TEveTrack* fTrack; // Model object. + + virtual void DirectDraw(TGLRnrCtx & rnrCtx) const; + +public: + TEveTrackGL(); + virtual ~TEveTrackGL(); + + virtual Bool_t SetModel(TObject* obj, const Option_t* opt=0); + + // To support two-level selection + virtual Bool_t SupportsSecondarySelect() const { return kTRUE; } + virtual void ProcessSelection(TGLRnrCtx & rnrCtx, TGLSelectRecord & rec); + + ClassDef(TEveTrackGL, 0); // GL-renderer for TEveTrack class. +}; + +#endif diff --git a/eve/inc/TEveTrackProjected.h b/eve/inc/TEveTrackProjected.h new file mode 100644 index 0000000000..3d777bc4a9 --- /dev/null +++ b/eve/inc/TEveTrackProjected.h @@ -0,0 +1,76 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveTrackProjected +#define ROOT_TEveTrackProjected + +#include +#include + +class TEveProjection; + +class TEveTrackProjected : public TEveTrack, + public TEveProjected +{ + friend class TEveTrackProjectedGL; + +private: + TEveTrackProjected(const TEveTrackProjected&); // Not implemented + TEveTrackProjected& operator=(const TEveTrackProjected&); // Not implemented + + Int_t GetBreakPointIdx(Int_t start); + void GetBreakPoint(Int_t N, Bool_t back, Float_t& x, Float_t& y, Float_t& z); + + TEveVector* fOrigPnts; + +protected: + std::vector fBreakPoints; + TEveProjection *fProjection; + +public: + TEveTrackProjected(); + virtual ~TEveTrackProjected(); + + virtual void SetProjection(TEveProjectionManager* proj, TEveProjectable* model); + + virtual void UpdateProjection(); + virtual void MakeTrack(Bool_t recurse=kTRUE); + + void PrintLineSegments(); + + virtual void CtrlClicked(TEveTrack*); // marked as signal in TEveTrack + + ClassDef(TEveTrackProjected, 1); // Projected copy of a TEveTrack. +}; + + +/******************************************************************************/ +// TEveTrackListProjected +/******************************************************************************/ + +class TEveTrackListProjected : public TEveTrackList, + public TEveProjected +{ +private: + TEveTrackListProjected(const TEveTrackListProjected&); // Not implemented + TEveTrackListProjected& operator=(const TEveTrackListProjected&); // Not implemented + +public: + TEveTrackListProjected(); + virtual ~TEveTrackListProjected() {} + + virtual void SetProjection(TEveProjectionManager* proj, TEveProjectable* model); + virtual void UpdateProjection(){}; + + ClassDef(TEveTrackListProjected, 1); // Specialization of TEveTrackList for holding TEveTrackProjected objects. +}; + +#endif diff --git a/eve/inc/TEveTrackProjectedGL.h b/eve/inc/TEveTrackProjectedGL.h new file mode 100644 index 0000000000..fcc19d398f --- /dev/null +++ b/eve/inc/TEveTrackProjectedGL.h @@ -0,0 +1,42 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveTrackProjectedGL +#define ROOT_TEveTrackProjectedGL + +#include + +class TGLViewer; +class TGLScene; + +class TEveTrackProjected; + +class TEveTrackProjectedGL : public TEveTrackGL +{ +private: + TEveTrackProjectedGL(const TEveTrackProjectedGL&); // Not implemented + TEveTrackProjectedGL& operator=(const TEveTrackProjectedGL&); // Not implemented + +protected: + TEveTrackProjected* fM; // Model object. + + virtual void DirectDraw(TGLRnrCtx & rnrCtx) const; + +public: + TEveTrackProjectedGL(); + virtual ~TEveTrackProjectedGL(); + + virtual Bool_t SetModel(TObject* obj, const Option_t* opt=0); + + ClassDef(TEveTrackProjectedGL, 0); // GL-renderer for TEveTrackProjected class. +}; + +#endif diff --git a/eve/inc/TEveTrackPropagator.h b/eve/inc/TEveTrackPropagator.h new file mode 100644 index 0000000000..59e663f99a --- /dev/null +++ b/eve/inc/TEveTrackPropagator.h @@ -0,0 +1,169 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveTrackPropagator +#define ROOT_TEveTrackPropagator + +#include +#include +#include +#include + +#include + +class TEvePointSet; + +class TEveTrackPropagator: public TObject, + public TEveRefBackPtr +{ +protected: + struct Vertex4D + { + Float_t x, y, z, t; + + Vertex4D() : x(0), y(0), z(0), t(0) {} + Vertex4D(Float_t _x, Float_t _y, Float_t _z, Float_t _t=0) : + x(_x), y(_y), z(_z), t(_t) {} + + Float_t Mag() const { return TMath::Sqrt(x*x+y*y+z*z);} + Float_t Mag2() const { return x*x+y*y+z*z;} + + Float_t Perp() const { return TMath::Sqrt(x*x+y*y);} + Float_t Perp2() const { return x*x+y*y;} + Float_t R() const { return Perp(); } + + Vertex4D operator + (const Vertex4D & b) + { return Vertex4D(x + b.x, y + b.y, z + b.z, t + b.t); } + + Vertex4D operator - (const Vertex4D & b) + { return Vertex4D(x - b.x, y - b.y, z - b.z, t - b.t); } + + Vertex4D operator * (Float_t a) + { return Vertex4D(a*x, a*y, a*z, a*t); } + + Vertex4D& operator += (const Vertex4D & b) + { x += b.x; y += b.y; z += b.z; t += b.t; return *this; } + }; + + struct Helix + { + Float_t fA; // contains charge and magnetic field data + Float_t fLam; // momentum ratio pT/pZ + Float_t fR; // a/pT + Float_t fPhiStep; // step size in xy projection, dependent of RnrMode and momentum + Float_t fTimeStep; // time step + Float_t fSin, fCos; // current sin, cos + Float_t fXoff, fYoff; // offset for fitting daughters + + Helix() : + fLam (0), fR (0), fPhiStep (0), fTimeStep (0) , + fSin (0), fCos (0), + fXoff (0), fYoff (0) + {} + + void Step(Vertex4D& v, TEveVector& p); + void StepVertex(Vertex4D& v, TEveVector& p, Vertex4D& forw); + }; + +private: + TEveTrackPropagator(const TEveTrackPropagator&); // Not implemented + TEveTrackPropagator& operator=(const TEveTrackPropagator&); // Not implemented + +public: + //------------------------- + // rendering configaration + + Float_t fMagField; // Constant magnetic field along z. + + // TEveTrack limits + Float_t fMaxR; // Max radius for track extrapolation + Float_t fMaxZ; // Max z-coordinate for track extrapolation. + // Helix limits + Float_t fMaxOrbs; // Maximal angular path of tracks' orbits (1 ~ 2Pi). + Float_t fMinAng; // Minimal angular step between two helix points. + Float_t fDelta; // Maximal error at the mid-point of the line connecting to helix points. + + // Path-mark control + Bool_t fEditPathMarks; // Show widgets for path-mark control in GUI editor. + TMarker fPMAtt; // Marker attributes for rendering of path-marks. + + Bool_t fFitDaughters; // Pass through daughter creation points when extrapolating a track. + Bool_t fFitReferences; // Pass through given track-references when extrapolating a track. + Bool_t fFitDecay; // Pass through decay point when extrapolating a track. + + Bool_t fRnrDaughters; // Render daughter path-marks. + Bool_t fRnrReferences; // Render track-reference path-marks. + Bool_t fRnrDecay; // Render decay path-marks. + + // First vertex control + Bool_t fRnrFV; // Render first vertex. + TMarker fFVAtt; // Marker attributes for fits vertex. + +protected: + //------------------------------------ + // propagation, state of current track + + Int_t fCharge; // particle charge + Float_t fVelocity; // particle velocity + std::vector fPoints; // calculated point + Vertex4D fV; // current vertex + Int_t fN; // current step number; + Int_t fNLast; // last step + Int_t fNMax; // max steps + Helix fH; // helix + + void RebuildTracks(); + + void InitHelix(); + void SetNumOfSteps(); + Bool_t HelixToVertex(TEveVector& v, TEveVector& p); + void HelixToBounds(TEveVector& p); + + Bool_t LineToVertex (TEveVector& v); + void LineToBounds (TEveVector& p); + +public: + TEveTrackPropagator(); + virtual ~TEveTrackPropagator() {} + + // propagation + void InitTrack(TEveVector &v, TEveVector &p, Float_t beta, Int_t charge); + void ResetTrack(); + void GoToBounds(TEveVector& p); + Bool_t GoToVertex(TEveVector& v, TEveVector& p); + void FillPointSet(TEvePointSet* ps) const; + + // callbacks + void SetEditPathMarks(Bool_t x) { fEditPathMarks = x; } + void SetRnrDaughters(Bool_t x); + void SetRnrReferences(Bool_t x); + void SetRnrDecay(Bool_t x); + + void SetRnrFV(Bool_t x){ fRnrFV = x;} + + void SetFitDaughters(Bool_t x); + void SetFitReferences(Bool_t x); + void SetFitDecay(Bool_t x); + + void SetMaxR(Float_t x); + void SetMaxZ(Float_t x); + void SetMaxOrbs(Float_t x); + void SetMinAng(Float_t x); + void SetDelta(Float_t x); + + static Float_t fgDefMagField; // Default value for constant solenoid magnetic field. + static const Float_t fgkB2C; // Constant for conversion of momentum to curvature. + static TEveTrackPropagator fgDefStyle; // Default track render-style. + + ClassDef(TEveTrackPropagator, 0); // Calculates path of a particle taking into account special path-marks and imposed boundaries. +}; + +#endif diff --git a/eve/inc/TEveTrackPropagatorEditor.h b/eve/inc/TEveTrackPropagatorEditor.h new file mode 100644 index 0000000000..fcd287c2e3 --- /dev/null +++ b/eve/inc/TEveTrackPropagatorEditor.h @@ -0,0 +1,115 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveTrackPropagatorEditor +#define ROOT_TEveTrackPropagatorEditor + +#include + +class TGButton; +class TGCheckButton; +class TGNumberEntry; +class TGColorSelect; +class TGComboBox; +class TGLineWidthComboBox; +class TGLineStyleComboBox; + +class TAttMarkerEditor; + +class TEveTrackPropagator; + +class TEveGValuator; +class TEveGDoubleValuator; +class TEveTrackPropagatorSubEditor; + +class TEveTrackPropagatorSubEditor : public TGVerticalFrame +{ + friend class TEveTrackPropagatorEditor; + friend class TEveTrackListEditor; + +private: + TEveTrackPropagatorSubEditor(const TEveTrackPropagatorSubEditor&); // Not implemented + TEveTrackPropagatorSubEditor& operator=(const TEveTrackPropagatorSubEditor&); // Not implemented + +protected: + TEveTrackPropagator *fM; + + TEveGValuator *fMaxR; + TEveGValuator *fMaxZ; + TEveGValuator *fMaxOrbits; + TEveGValuator *fMinAng; + TEveGValuator *fDelta; + + TGCheckButton *fRnrFV; + + TGCompositeFrame *fPMFrame; + TGButton *fFitDaughters; + TGButton *fFitReferences; + TGButton *fFitDecay; + TGButton *fRnrDaughters; + TGButton *fRnrReferences; + TGButton *fRnrDecay; + + TGCompositeFrame *fRefsCont; + + TAttMarkerEditor *fPMAtt; + TAttMarkerEditor *fFVAtt; + +public: + TEveTrackPropagatorSubEditor(const TGWindow* p); + virtual ~TEveTrackPropagatorSubEditor() {} + + void SetModel(TEveTrackPropagator* m); + + void Changed(); //*SIGNAL* + + void DoMaxR(); + void DoMaxZ(); + void DoMaxOrbits(); + void DoMinAng(); + void DoDelta(); + + void DoFitPM(); + void DoRnrPM(); + + void DoRnrFV(); + + void CreateRefsContainer(TGVerticalFrame* p); + + ClassDef(TEveTrackPropagatorSubEditor, 0) // Sub-editor for TEveTrackPropagator class. +}; + +/******************************************************************************/ +// TEveTrackPropagatorEditor +/******************************************************************************/ + +class TEveTrackPropagatorEditor : public TGedFrame +{ +private: + TEveTrackPropagatorEditor(const TEveTrackPropagatorEditor&); // Not implemented + TEveTrackPropagatorEditor& operator=(const TEveTrackPropagatorEditor&); // Not implemented + + void CreateRefTab(); +protected: + TEveTrackPropagator *fM; // Model object. + TEveTrackPropagatorSubEditor *fRSSubEditor; // Render-style sub-editor. + +public: + TEveTrackPropagatorEditor(const TGWindow* p=0, Int_t width=170, Int_t height=30, + UInt_t options=kChildFrame, Pixel_t back=GetDefaultFrameBackground()); + ~TEveTrackPropagatorEditor(); + + virtual void SetModel(TObject* obj); + + ClassDef(TEveTrackPropagatorEditor, 1); // Editor for TEveTrackPropagator class. +}; + +#endif diff --git a/eve/inc/TEveTrans.h b/eve/inc/TEveTrans.h new file mode 100644 index 0000000000..20ba6e0e96 --- /dev/null +++ b/eve/inc/TEveTrans.h @@ -0,0 +1,169 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveTrans +#define ROOT_TEveTrans + +#include + +class TGeoMatrix; +class TGeoHMatrix; +class TBuffer3D; + +/******************************************************************************/ +// TEveTrans -- 3D transformation in generalised coordinates +/******************************************************************************/ + +class TEveTrans : public TObject +{ + friend class TEveTransSubEditor; + friend class TEveTransEditor; + +protected: + Double32_t M[16]; + + mutable Float_t mA1; //! + mutable Float_t mA2; //! + mutable Float_t mA3; //! + mutable Bool_t bAsOK; //! + + // TEveUtil + Bool_t fUseTrans; + Bool_t fEditTrans; + + Double_t norm3_column(Int_t col); + Double_t orto3_column(Int_t col, Int_t ref); + +public: + TEveTrans(); + TEveTrans(const TEveTrans& t); + TEveTrans(const Double_t arr[16]); + TEveTrans(const Float_t arr[16]); + virtual ~TEveTrans() {} + + // General operations + + void UnitTrans(); + void UnitRot(); + void SetTrans(const TEveTrans& t, Bool_t copyAngles=kTRUE); + void SetFromArray(const Double_t arr[16]); + void SetFromArray(const Float_t arr[16]); + TEveTrans& operator=(const TEveTrans& t) { SetTrans(t); return *this; } + void SetupRotation(Int_t i, Int_t j, Double_t f); + + void OrtoNorm3(); + Double_t Invert(); + + void MultLeft(const TEveTrans& t); + void MultRight(const TEveTrans& t); + void operator*=(const TEveTrans& t) { MultRight(t); } + + void TransposeRotationPart(); + + TEveTrans operator*(const TEveTrans& t); + + // Move & Rotate + + void MoveLF(Int_t ai, Double_t amount); + void Move3LF(Double_t x, Double_t y, Double_t z); + void RotateLF(Int_t i1, Int_t i2, Double_t amount); + + void MovePF(Int_t ai, Double_t amount); + void Move3PF(Double_t x, Double_t y, Double_t z); + void RotatePF(Int_t i1, Int_t i2, Double_t amount); + + void Move(const TEveTrans& a, Int_t ai, Double_t amount); + void Move3(const TEveTrans& a, Double_t x, Double_t y, Double_t z); + void Rotate(const TEveTrans& a, Int_t i1, Int_t i2, Double_t amount); + + // Element access + + Double_t* Array() { return M; } const Double_t* Array() const { return M; } + Double_t* ArrX() { return M; } const Double_t* ArrX() const { return M; } + Double_t* ArrY() { return M + 4; } const Double_t* ArrY() const { return M + 4; } + Double_t* ArrZ() { return M + 8; } const Double_t* ArrZ() const { return M + 8; } + Double_t* ArrT() { return M + 12; } const Double_t* ArrT() const { return M + 12; } + + Double_t operator[](Int_t i) const { return M[i]; } + Double_t& operator[](Int_t i) { return M[i]; } + + Double_t CM(Int_t i, Int_t j) const { return M[4*j + i]; } + Double_t& CM(Int_t i, Int_t j) { return M[4*j + i]; } + + Double_t operator()(Int_t i, Int_t j) const { return M[4*j + i - 5]; } + Double_t& operator()(Int_t i, Int_t j) { return M[4*j + i - 5]; } + + // Base-vector interface + + void SetBaseVec(Int_t b, Double_t x, Double_t y, Double_t z); + void SetBaseVec(Int_t b, const TVector3& v); + + TVector3 GetBaseVec(Int_t b) const; + void GetBaseVec(Int_t b, TVector3& v) const; + + // Position interface + + void SetPos(Double_t x, Double_t y, Double_t z); + void SetPos(Double_t* x); + void SetPos(Float_t * x); + void SetPos(const TEveTrans& t); + + void GetPos(Double_t& x, Double_t& y, Double_t& z) const; + void GetPos(Double_t* x) const; + void GetPos(Float_t * x) const; + void GetPos(TVector3& v) const; + TVector3 GetPos() const; + + // Cardan angle interface + + void SetRotByAngles(Float_t a1, Float_t a2, Float_t a3); + void SetRotByAnyAngles(Float_t a1, Float_t a2, Float_t a3, const Text_t* pat); + void GetRotAngles(Float_t* x) const; + + // Scaling + + void Scale(Double_t sx, Double_t sy, Double_t sz); + void GetScale(Double_t& sx, Double_t& sy, Double_t& sz) const; + void Unscale(Double_t& sx, Double_t& sy, Double_t& sz); + Double_t Unscale(); + + // Operations on vectors + + void MultiplyIP(TVector3& v, Double_t w=1) const; + void MultiplyIP(Double_t* v, Double_t w=1) const; + void MultiplyIP(Float_t* v, Double_t w=1) const; + TVector3 Multiply(const TVector3& v, Double_t w=1) const; + void Multiply(const Double_t *vin, Double_t* vout, Double_t w=1) const; + void RotateIP(TVector3& v) const; + TVector3 Rotate(const TVector3& v) const; + + virtual void Print(Option_t* option = "") const; + + // TEveUtil stuff + + void SetFrom(Double_t* carr); + void SetFrom(const TGeoMatrix& mat); + void SetGeoHMatrix(TGeoHMatrix& mat); + void SetBuffer3D(TBuffer3D& buff); + + Bool_t GetUseTrans() const { return fUseTrans; } + void SetUseTrans(Bool_t v) { fUseTrans = v; } + Bool_t GetEditTrans() const { return fEditTrans; } + void SetEditTrans(Bool_t v) { fEditTrans = v; } + + Bool_t IsScale(Double_t low=0.9, Double_t high=1.1) const; + + ClassDef(TEveTrans, 1); // Column-major 4x4 transforamtion matrix for homogeneous coordinates. +}; + +ostream& operator<<(ostream& s, const TEveTrans& t); + +#endif diff --git a/eve/inc/TEveTransEditor.h b/eve/inc/TEveTransEditor.h new file mode 100644 index 0000000000..ebdbfa0d14 --- /dev/null +++ b/eve/inc/TEveTransEditor.h @@ -0,0 +1,82 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveTransEditor +#define ROOT_TEveTransEditor + +#include + +class TGCheckButton; +class TGTextButton; + +class TEveTrans; +class TEveGTriVecValuator; + + +class TEveTransSubEditor : public TGVerticalFrame +{ + TEveTransSubEditor(const TEveTransSubEditor&); // Not implemented + TEveTransSubEditor& operator=(const TEveTransSubEditor&); // Not implemented + +protected: + TEveTrans *fTrans; + + TGHorizontalFrame *fTopHorFrame; + + TGCheckButton *fUseTrans; + TGCheckButton *fEditTrans; + + TGVerticalFrame *fEditTransFrame; + + TEveGTriVecValuator *fPos; + TEveGTriVecValuator *fRot; + TEveGTriVecValuator *fScale; + + TGCheckButton *fAutoUpdate; + TGTextButton *fUpdate; + +public: + TEveTransSubEditor(TGWindow* p); + virtual ~TEveTransSubEditor() {} + + void SetDataFromTrans(TEveTrans* t); + void SetTransFromData(); + + void UseTrans(); //*SIGNAL* + void TransChanged(); //*SIGNAL* + + void DoUseTrans(); + void DoEditTrans(); + void DoTransChanged(); + + ClassDef(TEveTransSubEditor, 0); // Sub-editor for TEveTrans class. +}; + + +class TEveTransEditor : public TGedFrame +{ +private: + TEveTransEditor(const TEveTransEditor&); // Not implemented + TEveTransEditor& operator=(const TEveTransEditor&); // Not implemented + +protected: + TEveTrans* fM; // Model object. + +public: + TEveTransEditor(const TGWindow* p=0, Int_t width=170, Int_t height=30, UInt_t options = kChildFrame, Pixel_t back=GetDefaultFrameBackground()); + virtual ~TEveTransEditor(); + + virtual void SetModel(TObject* obj); + + ClassDef(TEveTransEditor, 1); // Editor for TEveTrans class. +}; + +#endif diff --git a/eve/inc/TEveTreeTools.h b/eve/inc/TEveTreeTools.h new file mode 100644 index 0000000000..a367bba9d0 --- /dev/null +++ b/eve/inc/TEveTreeTools.h @@ -0,0 +1,113 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveTreeTools +#define ROOT_TEveTreeTools + +#include +#include + +/******************************************************************************/ +// TEveSelectorToEventList +/******************************************************************************/ + +class TEveSelectorToEventList : public TSelectorDraw +{ + TEveSelectorToEventList(const TEveSelectorToEventList&); // Not implemented + TEveSelectorToEventList& operator=(const TEveSelectorToEventList&); // Not implemented + +protected: + TEventList* fEvList; + TList fInput; +public: + TEveSelectorToEventList(TEventList* evl, const Text_t* sel); + + virtual Int_t Version() const { return 1; } + virtual Bool_t Process(Long64_t entry); + + ClassDef(TEveSelectorToEventList, 1); // TSelector that stores entry numbers of matching TTree entries into an event-list. +}; + +/******************************************************************************/ +// TEvePointSelectorConsumer, TEvePointSelector +/******************************************************************************/ + +class TEvePointSelector; + +class TEvePointSelectorConsumer +{ +public: + enum TreeVarType_e { TVT_XYZ, TVT_RPhiZ }; + +protected: + TreeVarType_e fSourceCS; // Coordinate-System of the source tree variables + +public: + TEvePointSelectorConsumer(TreeVarType_e cs=TVT_XYZ) :fSourceCS(cs) {} + virtual ~TEvePointSelectorConsumer() {} + + virtual void InitFill(Int_t /*subIdNum*/) {} + virtual void TakeAction(TEvePointSelector*) = 0; + + TreeVarType_e GetSourceCS() const { return fSourceCS; } + void SetSourceCS(TreeVarType_e cs) { fSourceCS = cs; } + + ClassDef(TEvePointSelectorConsumer, 1); // Virtual base for classes that can be filled from TTree data via the TEvePointSelector class. +}; + +class TEvePointSelector : public TSelectorDraw +{ + TEvePointSelector(const TEvePointSelector&); // Not implemented + TEvePointSelector& operator=(const TEvePointSelector&); // Not implemented + +protected: + TTree *fTree; + TEvePointSelectorConsumer *fConsumer; + + TString fVarexp; + TString fSelection; + + TString fSubIdExp; + Int_t fSubIdNum; + + TList fInput; + +public: + TEvePointSelector(TTree* t=0, TEvePointSelectorConsumer* c=0, + const Text_t* vexp="", const Text_t* sel=""); + virtual ~TEvePointSelector() {} + + virtual Long64_t Select(const Text_t* selection=0); + virtual Long64_t Select(TTree* t, const Text_t* selection=0); + virtual void TakeAction(); + + + TTree* GetTree() const { return fTree; } + void SetTree(TTree* t) { fTree = t; } + + TEvePointSelectorConsumer* GetConsumer() const { return fConsumer; } + void SetConsumer(TEvePointSelectorConsumer* c) { fConsumer = c; } + + const Text_t* GetVarexp() const { return fVarexp; } + void SetVarexp(const Text_t* v) { fVarexp = v; } + + const Text_t* GetSelection() const { return fSelection; } + void SetSelection(const Text_t* s) { fSelection = s; } + + const Text_t* GetSubIdExp() const { return fSubIdExp; } + void SetSubIdExp(const Text_t* s) { fSubIdExp = s; } + + Int_t GetSubIdNum() const { return fSubIdNum; } + + ClassDef(TEvePointSelector, 1); // TSelector for direct extraction of point-like data from a Tree. +}; + +#endif diff --git a/eve/inc/TEveTriangleSet.h b/eve/inc/TEveTriangleSet.h new file mode 100644 index 0000000000..69ed80930f --- /dev/null +++ b/eve/inc/TEveTriangleSet.h @@ -0,0 +1,95 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveTriangleSet +#define ROOT_TEveTriangleSet + +#include +#include +#include +#include + +#include + +class TGeoMatrix; + +class TEveTriangleSet : public TEveElement, + public TNamed, + public TAttBBox, + public TAtt3D +{ + friend class TEveTriangleSetEditor; + friend class TEveTriangleSetGL; + + TEveTriangleSet(const TEveTriangleSet&); // Not implemented + TEveTriangleSet& operator=(const TEveTriangleSet&); // Not implemented + +protected: + + // Vertex data + Int_t fNVerts; + Float_t* fVerts; //[3*fNVerts] + + // Triangle data + Int_t fNTrings; + Int_t* fTrings; //[3*fNTrings] + Float_t* fTringNorms; //[3*fNTrings] + UChar_t* fTringCols; //[3*fNTrings] + + // -------------------------------------------------------------- + + Color_t fColor; + UShort_t fTransp; + TEveTrans fHMTrans; + +public: + + TEveTriangleSet(Int_t nv, Int_t nt, Bool_t norms=false, Bool_t cols=false); + ~TEveTriangleSet(); + + virtual Bool_t CanEditMainColor() { return kTRUE; } + + Float_t* Vertex(Int_t i) { return &(fVerts[3*i]); } + Int_t* Triangle(Int_t i) { return &(fTrings[3*i]); } + Float_t* TriangleNormal(Int_t i) { return &(fTringNorms[3*i]); } + UChar_t* TriangleColor(Int_t i) { return &(fTringCols[3*i]); } + + void SetVertex(Int_t i, Float_t x, Float_t y, Float_t z) + { Float_t* v = Vertex(i); v[0] = x; v[1] = y; v[2] = z; } + void SetTriangle(Int_t i, Int_t v0, Int_t v1, Int_t v2) + { Int_t* t = Triangle(i); t[0] = v0; t[1] = v1; t[2] = v2; } + void SetTriangleColor(Int_t i, UChar_t r, UChar_t g, UChar_t b, UChar_t a=255) + { UChar_t* c = TriangleColor(i); c[0] = r; c[1] = g; c[2] = b; c[3] = a; } + + void GenerateTriangleNormals(); + void GenerateRandomColors(); + void GenerateZNormalColors(Float_t fac=20, Int_t min=-20, Int_t max=20, + Bool_t interp=kFALSE, Bool_t wrap=kFALSE); + + virtual void ComputeBBox(); + virtual void Paint(Option_t* = ""); + + Color_t GetColor() const { return fColor; } + void SetColor(Color_t c) { fColor = c; } + + UShort_t GetTransparency() const { return fTransp; } + void SetTransparency(UShort_t tr) { fTransp = tr; } // *MENU* + + TEveTrans& RefHMTrans() { return fHMTrans; } + void SetTransMatrix(Double_t* carr) { fHMTrans.SetFrom(carr); } + void SetTransMatrix(const TGeoMatrix& mat) { fHMTrans.SetFrom(mat); } + + static TEveTriangleSet* ReadTrivialFile(const char* file); + + ClassDef(TEveTriangleSet, 0); // Generic mesh or soup of triangles with per-triangle normals and colors. +}; + +#endif diff --git a/eve/inc/TEveTriangleSetEditor.h b/eve/inc/TEveTriangleSetEditor.h new file mode 100644 index 0000000000..fe30f31012 --- /dev/null +++ b/eve/inc/TEveTriangleSetEditor.h @@ -0,0 +1,44 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveTriangleSetEditor +#define ROOT_TEveTriangleSetEditor + +#include + +class TGCheckButton; +class TGNumberEntry; +class TGColorSelect; + +class TEveTransSubEditor; +class TEveTriangleSet; + +class TEveTriangleSetEditor : public TGedFrame +{ +private: + TEveTriangleSetEditor(const TEveTriangleSetEditor&); // Not implemented + TEveTriangleSetEditor& operator=(const TEveTriangleSetEditor&); // Not implemented + +protected: + TEveTriangleSet *fM; // Model object. + + TEveTransSubEditor *fHMTrans; // Sub-editor of transforamtion matrix. + +public: + TEveTriangleSetEditor(const TGWindow* p=0, Int_t width=170, Int_t height=30, UInt_t options = kChildFrame, Pixel_t back=GetDefaultFrameBackground()); + virtual ~TEveTriangleSetEditor(); + + virtual void SetModel(TObject* obj); + + ClassDef(TEveTriangleSetEditor, 1); // Editor for TEveTriangleSet class. +}; + +#endif diff --git a/eve/inc/TEveTriangleSetGL.h b/eve/inc/TEveTriangleSetGL.h new file mode 100644 index 0000000000..7d905334b8 --- /dev/null +++ b/eve/inc/TEveTriangleSetGL.h @@ -0,0 +1,46 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveTriangleSetGL +#define ROOT_TEveTriangleSetGL + +#include + +class TGLRnrCtx; + +class TEveTriangleSet; + +class TEveTriangleSetGL : public TGLObject +{ +private: + TEveTriangleSetGL(const TEveTriangleSetGL&); // Not implemented + TEveTriangleSetGL& operator=(const TEveTriangleSetGL&); // Not implemented + +protected: + TEveTriangleSet* fM; // Model object. + + virtual void DirectDraw(TGLRnrCtx & rnrCtx) const; + +public: + TEveTriangleSetGL(); + virtual ~TEveTriangleSetGL(); + + virtual Bool_t SetModel(TObject* obj, const Option_t* opt=0); + virtual void SetBBox(); + + // To support two-level selection + // virtual Bool_t SupportsSecondarySelect() const { return kTRUE; } + // virtual void ProcessSelection(UInt_t* ptr, TGLViewer*, TGLScene*); + + ClassDef(TEveTriangleSetGL, 0); // GL-renderer for TEveTriangleSet class. +}; + +#endif diff --git a/eve/inc/TEveUtil.h b/eve/inc/TEveUtil.h new file mode 100644 index 0000000000..f09453b036 --- /dev/null +++ b/eve/inc/TEveUtil.h @@ -0,0 +1,170 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveUtil +#define ROOT_TEveUtil + +#include +#include +#include + +#include +#include +#include +#include +#include + +class TVirtualPad; +class TGeoManager; + +class TEveElement; + +/******************************************************************************/ +// TEveUtil +/******************************************************************************/ + +class TEveUtil +{ +public: + virtual ~TEveUtil() {} + + // Environment, Macro functions + + static void SetupEnvironment(); + static void SetupGUI(); + + static Bool_t CheckMacro(const Text_t* mac); + static void AssertMacro(const Text_t* mac); + static void Macro(const Text_t* mac); + static void LoadMacro(const Text_t* mac); + + // Color management + + static void ColorFromIdx(Color_t ci, UChar_t col[4], Bool_t alpha=kTRUE); + static void ColorFromIdx(Float_t f1, Color_t c1, Float_t f2, Color_t c2, + UChar_t col[4], Bool_t alpha=kTRUE); + static Color_t* FindColorVar(TObject* obj, const Text_t* varname); + + ClassDef(TEveUtil, 0); // Standard utility functions for Reve. +}; + + +/******************************************************************************/ +// Exceptions, string functions +/******************************************************************************/ + +bool operator==(const TString& t, const std::string& s); +bool operator==(const std::string& s, const TString& t); + +class TEveException : public std::exception, public TString +{ +public: + TEveException() {} + TEveException(const TString& s) : TString(s) {} + TEveException(const char* s) : TString(s) {} + TEveException(const std::string& s); + + virtual ~TEveException() throw () {} + + virtual const char* what() const throw () { return Data(); } + + ClassDef(TEveException, 1); // Exception-type thrown by TEveUtil functions and classes. +}; + +TEveException operator+(const TEveException &s1, const std::string &s2); +TEveException operator+(const TEveException &s1, const TString &s2); +TEveException operator+(const TEveException &s1, const char *s2); + + +/******************************************************************************/ +// Exception-safe global variable holders +/******************************************************************************/ + +class TEvePadHolder +{ +private: + TVirtualPad *fOldPad; + Bool_t fModifyUpdateP; + +public: + TEvePadHolder(Bool_t modify_update_p, TVirtualPad* new_pad=0, Int_t subpad=0); + virtual ~TEvePadHolder(); + + ClassDef(TEvePadHolder, 0); // Exception-safe wrapper for temporary setting of gPad variable. +}; + +class TEveGeoManagerHolder +{ +private: + TGeoManager* fManager; + + TEveGeoManagerHolder(const TEveGeoManagerHolder&); // Not implemented + TEveGeoManagerHolder& operator=(const TEveGeoManagerHolder&); // Not implemented + +public: + TEveGeoManagerHolder(TGeoManager* new_gmgr=0); + virtual ~TEveGeoManagerHolder(); + + ClassDef(TEveGeoManagerHolder, 0); // Exception-safe wrapper for temporary setting of gGeoManager variable. +}; + + +/******************************************************************************/ +// TEveRefCnt base-class (interface) +/******************************************************************************/ + +class TEveRefCnt +{ +protected: + Int_t fRefCount; + +public: + TEveRefCnt() : fRefCount(0) {} + virtual ~TEveRefCnt() {} + + TEveRefCnt(const TEveRefCnt&) : fRefCount(0) {} + TEveRefCnt& operator=(const TEveRefCnt&) { return *this; } + + void IncRefCount() { ++fRefCount; } + void DecRefCount() { if(--fRefCount <= 0) OnZeroRefCount(); } + + virtual void OnZeroRefCount() { delete this; } + + ClassDef(TEveRefCnt, 0); // Base-class for reference-counted objects. +}; + +/******************************************************************************/ +// TEveRefBackPtr reference-count with back pointers +/******************************************************************************/ + +class TEveRefBackPtr : public TEveRefCnt +{ +protected: + std::list fBackRefs; + +public: + TEveRefBackPtr(); + virtual ~TEveRefBackPtr(); + + TEveRefBackPtr(const TEveRefBackPtr&); + TEveRefBackPtr& operator=(const TEveRefBackPtr&); + + using TEveRefCnt::IncRefCount; + using TEveRefCnt::DecRefCount; + virtual void IncRefCount(TEveElement* re); + virtual void DecRefCount(TEveElement* re); + + virtual void UpdateBackPtrItems(); + + ClassDef(TEveRefBackPtr, 0); // Base-class for reference-counted objects with reverse references to TEveElement objects. +}; + +#endif diff --git a/eve/inc/TEveVSD.h b/eve/inc/TEveVSD.h new file mode 100644 index 0000000000..babb02c352 --- /dev/null +++ b/eve/inc/TEveVSD.h @@ -0,0 +1,71 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveVSD +#define ROOT_TEveVSD + +#include +#include +#include + +class TEveVSD : public TObject +{ + TEveVSD(const TEveVSD&); // Not implemented + TEveVSD& operator=(const TEveVSD&); // Not implemented + +protected: + Int_t fBuffSize; + + TFile* mFile; //! + TDirectory* mDirectory; //! + +public: + TTree* mTreeK; //! X{g} + // TTree* mTreeTR; //! X{g} + TTree* mTreeH; //! X{g} + TTree* mTreeC; //! X{g} + TTree* mTreeR; //! X{g} + TTree* mTreeKK; //! X{g} + TTree* mTreeV0; //! X{g} + TTree* mTreeGI; //! X{g} + + TEveMCTrack mK, *mpK; //! + // MCTrackRef mTR, *mpTR; //! + TEveHit mH, *mpH; //! + TEveCluster mC, *mpC; //! + TEveRecTrack mR, *mpR; //! + TEveRecKink mKK, *mpKK; //! + TEveRecV0 mV0, *mpV0; //! + TEveMCRecCrossRef mGI, *mpGI; //! + +public: + TEveVSD(const Text_t* name="TEveVSD", const Text_t* title=""); + + virtual void SetDirectory(TDirectory* dir); + + virtual void CreateTrees(); + virtual void DeleteTrees(); + + virtual void CreateBranches(); + virtual void SetBranchAddresses(); + + virtual void WriteTrees(); + virtual void LoadTrees(); + + virtual void LoadVSD(const Text_t* vsd_file_name, + const Text_t* dir_name="Event0"); + + static void DisableTObjectStreamersForVSDStruct(); + + ClassDef(TEveVSD, 1); // Visualization Summary Data - a collection of trees holding standard event data in experiment independant format. +}; + +#endif diff --git a/eve/inc/TEveVSDStructs.h b/eve/inc/TEveVSDStructs.h new file mode 100644 index 0000000000..d5ad1301a4 --- /dev/null +++ b/eve/inc/TEveVSDStructs.h @@ -0,0 +1,357 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveVSDStructs +#define ROOT_TEveVSDStructs + +#include +#include + +#include + +/******************************************************************************/ +// VSD Structures +/******************************************************************************/ + +// Basic structures for Reve VSD concept. Design criteria: +// +// * provide basic cross-referencing functionality; +// +// * small memory/disk footprint (floats / count on compression in +// split mode); +// +// * simple usage from tree selections; +// +// * placement in TClonesArray (composites are TObject derived); +// +// * minimal member-naming (impossible to make everybody happy). + + +/******************************************************************************/ +// TEveVector +/******************************************************************************/ + +class TEveVector +{ +public: + Float_t x, y, z; + + TEveVector() : x(0), y(0), z(0) {} + TEveVector(Float_t _x, Float_t _y, Float_t _z) : x(_x), y(_y), z(_z) {} + virtual ~TEveVector() {} + + TEveVector operator + (const TEveVector &); + TEveVector operator - (const TEveVector &); + TEveVector operator * (Float_t a); + + Float_t* c_vec() { return &x; } + Float_t& operator [] (Int_t indx); + Float_t operator [] (Int_t indx) const; + + void Set(Float_t* v) { x=v[0]; y=v[1]; z=v[2]; } + void Set(Double_t* v) { x=v[0]; y=v[1]; z=v[2]; } + void Set(Float_t _x, Float_t _y, Float_t _z) { x=_x; y=_y; z=_z; } + void Set(Double_t _x, Double_t _y, Double_t _z) { x=_x; y=_y; z=_z; } + void Set(const TVector3& v) { x=v.x(); y=v.y(); z=v.z(); } + void Set(const TEveVector& v) { x=v.x; y=v.y; z=v.z; } + + Float_t Phi() const; + Float_t Theta() const; + Float_t CosTheta() const; + Float_t Eta() const; + + Float_t Mag() const { return TMath::Sqrt(x*x+y*y+z*z);} + Float_t Mag2() const { return x*x+y*y+z*z;} + + Float_t Perp() const { return TMath::Sqrt(x*x+y*y);} + Float_t Perp2() const { return x*x+y*y;} + Float_t R() const { return Perp(); } + + Float_t Distance(const TEveVector& v) const; + Float_t SquareDistance(const TEveVector& v) const; + Float_t Dot(const TEveVector&a) const; + + TEveVector& Mult(const TEveVector&a, Float_t af) { x = a.x*af; y = a.y*af; z = a.z*af; return *this; } + + + ClassDef(TEveVector, 1); // Float three-vector; a inimal Float_t copy of TVector3 used to represent points and momenta (also used in VSD). +}; + +//______________________________________________________________________________ +inline Float_t TEveVector::Phi() const +{ return x == 0.0 && y == 0.0 ? 0.0 : TMath::ATan2(y,x); } + +inline Float_t TEveVector::Theta() const +{ return x == 0.0 && y == 0.0 && z == 0.0 ? 0.0 : TMath::ATan2(Perp(),z); } + +inline Float_t TEveVector::CosTheta() const +{ Float_t ptot = Mag(); return ptot == 0.0 ? 1.0 : z/ptot; } + +inline Float_t TEveVector::Distance( const TEveVector& b) const +{ + return TMath::Sqrt((x - b.x)*(x - b.x) + (y - b.y)*(y - b.y) + (z - b.z)*(z - b.z)); +} +inline Float_t TEveVector::SquareDistance(const TEveVector& b) const +{ + return ((x - b.x)*(x - b.x) + (y - b.y)*(y - b.y) + (z - b.z)*(z - b.z)); +} + +//______________________________________________________________________________ +inline Float_t TEveVector::Dot(const TEveVector& a) const +{ + return a.x*x + a.y*y + a.z*z; +} + +inline Float_t& TEveVector::operator [] (Int_t idx) +{ return (&x)[idx]; } + +inline Float_t TEveVector::operator [] (Int_t idx) const +{ return (&x)[idx]; } + + +/******************************************************************************/ +// TEvePathMark +/******************************************************************************/ + +class TEvePathMark +{ +public: + enum Type_e { Reference, Daughter, Decay }; + + TEveVector V; // vertex + TEveVector P; // momentum + Float_t time; // time + Type_e type; // mark-type + + TEvePathMark(Type_e t=Reference) : V(), P(), time(0), type(t) {} + virtual ~TEvePathMark() {} + + const char* type_name(); + + ClassDef(TEvePathMark, 1); // Special-point on track: position/momentum reference, daughter creation or decay (also used in VSD). +}; + +/******************************************************************************/ +// TEveMCTrack +/******************************************************************************/ + +class TEveMCTrack : public TParticle // ?? Copy stuff over ?? +{ +public: + Int_t label; // Label of the track + Int_t index; // Index of the track (in some source array) + Int_t eva_label; // Label of primary particle + + Bool_t decayed; // True if decayed during tracking. + // ?? Perhaps end-of-tracking point/momentum would be better. + Float_t t_decay; // Decay time + TEveVector V_decay; // Decay vertex + TEveVector P_decay; // Decay momentum + + TEveMCTrack() : label(-1), index(-1), eva_label(-1), + decayed(false), t_decay(0), V_decay(), P_decay() {} + virtual ~TEveMCTrack() {} + + TEveMCTrack& operator=(const TParticle& p) + { *((TParticle*)this) = p; return *this; } + + void ResetPdgCode() { fPdgCode = 0; } + + ClassDef(TEveMCTrack, 1); // Monte Carlo track (also used in VSD). +}; + + +/******************************************************************************/ +// TEveHit +/******************************************************************************/ + +// Representation of a hit. + +// Members det_id (and subdet_id) serve for cross-referencing into +// geometry. Hits should be stored in det_id (+some label ordering) in +// order to maximize branch compression. + + +class TEveHit : public TObject +{ +public: + UShort_t det_id; // Custom detector id + UShort_t subdet_id; // Custom sub-detector id + Int_t label; // Label of particle that produced the hit + Int_t eva_label; // Label of primary particle, ancestor of label + TEveVector V; // Hit position + + // Float_t charge; Probably specific. + + TEveHit() : det_id(0), subdet_id(0), label(0), eva_label(0), V() {} + virtual ~TEveHit() {} + + ClassDef(TEveHit, 1); // Monte Carlo hit (also used in VSD). +}; + + +/******************************************************************************/ +// TEveCluster +/******************************************************************************/ + +// Base class for reconstructed clusters + +// ?? Should TEveHit and cluster have common base? No. + +class TEveCluster : public TObject +{ +public: + UShort_t det_id; // Custom detector id + UShort_t subdet_id; // Custom sub-detector id + Int_t label[3]; // Labels of particles that contributed hits + // ?? Should include reconstructed track using it? Rather not, separate. + + TEveVector V; // Vertex + // TEveVector W; // Cluster widths + // ?? Coord system? Special variables Wz, Wy? + + TEveCluster() : det_id(0), subdet_id(0), V() { label[0] = label[1] = label [2] = 0; } + virtual ~TEveCluster() {} + + ClassDef(TEveCluster, 1); // Reconstructed cluster (also used in VSD). +}; + + +/******************************************************************************/ +// TEveRecTrack +/******************************************************************************/ + +class TEveRecTrack : public TObject +{ +public: + Int_t label; // Label of the track + Int_t index; // Index of the track (in some source array) + Int_t status; // Status as exported from reconstruction + Int_t sign; // Charge of the track + TEveVector V; // Start vertex from reconstruction + TEveVector P; // Reconstructed momentum at start vertex + Float_t beta; + + // PID data missing + + TEveRecTrack() : label(-1), index(-1), status(0), sign(0), V(), P(), beta(0) {} + virtual ~TEveRecTrack() {} + + Float_t Pt() { return P.Perp(); } + + ClassDef(TEveRecTrack, 1); // Reconstructed track (also used in VSD). +}; + + +/******************************************************************************/ +// TEveRecKink +/******************************************************************************/ + +class TEveRecKink : public TEveRecTrack +{ +public: + Int_t label_sec; // Label of the secondary track + TEveVector V_end; // End vertex: last point on the primary track + TEveVector V_kink; // Kink vertex: reconstructed position of the kink + TEveVector P_sec; // Momentum of secondary track + + TEveRecKink() : TEveRecTrack(), label_sec(0), V_end(), V_kink(), P_sec() {} + virtual ~TEveRecKink() {} + + ClassDef(TEveRecKink, 1); // Reconstructed kink (also used in VSD). +}; + + +/******************************************************************************/ +// TEveRecV0 +/******************************************************************************/ + +class TEveRecV0 : public TObject +{ +public: + Int_t status; + + TEveVector V_neg; // Vertex of negative track + TEveVector P_neg; // Momentum of negative track + TEveVector V_pos; // Vertex of positive track + TEveVector P_pos; // Momentum of positive track + + TEveVector V_ca; // Point of closest approach + TEveVector V0_birth; // Reconstucted birth point of neutral particle + + // ? Data from simulation. + Int_t label; // Neutral mother label read from kinematics + Int_t pdg; // PDG code of mother + Int_t d_label[2]; // Daughter labels ?? Rec labels present anyway. + + TEveRecV0() : status(), V_neg(), P_neg(), V_pos(), P_pos(), + V_ca(), V0_birth(), label(0), pdg(0) + { d_label[0] = d_label[1] = 0; } + virtual ~TEveRecV0() {} + + ClassDef(TEveRecV0, 1); // Reconstructed V0 (also used in VSD). +}; + +/******************************************************************************/ +/******************************************************************************/ + +// Missing primary vertex. + +// Missing TEveMCRecCrossRef, RecInfo. + +class TEveMCRecCrossRef : public TObject +{ +public: + Bool_t is_rec; // is reconstructed + Bool_t has_V0; + Bool_t has_kink; + Int_t label; + Int_t n_hits; + Int_t n_clus; + + TEveMCRecCrossRef() : is_rec(false), has_V0(false), has_kink(false), + label(0), n_hits(0), n_clus(0) {} + virtual ~TEveMCRecCrossRef() {} + + ClassDef(TEveMCRecCrossRef, 1); // Cross-reference of sim/rec data per particle (also used in VSD). +}; + +/******************************************************************************/ +/******************************************************************************/ + +// This whole construction is somewhat doubtable. It requires +// shameless copying of experiment data. What is good about this +// scheme: +// +// 1) Filters can be applied at copy time so that only part of the +// data is copied over. +// +// 2) Once the data is extracted it can be used without experiment +// software. Thus, external service can provide this data and local +// client can be really thin. +// +// 3) Some pretty advanced visualization schemes/selections can be +// implemented in a general framework by providing data extractors +// only. This is also good for PR or VIP displays. +// +// 4) These classes can be extended by particular implementations. The +// container classes will use TClonesArray with user-specified element +// class. + +// The common behaviour could be implemented entirely without usage of +// a common base classes, by just specifying names of members that +// retrieve specific data. This is fine as long as one only uses tree +// selections but becomes painful for extraction of data into local +// structures (could a) use interpreter but this is an overkill and +// would cause serious trouble for multi-threaded environment; b) use +// member offsets and data-types from the dictionary). + +#endif diff --git a/eve/inc/TEveViewer.h b/eve/inc/TEveViewer.h new file mode 100644 index 0000000000..25981a0527 --- /dev/null +++ b/eve/inc/TEveViewer.h @@ -0,0 +1,83 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TEveViewer +#define ROOT_TEveViewer + +#include + +class TGWindow; +class TGedEditor; +class TGLViewer; + +class TEveScene; + +/******************************************************************************/ +// TEveViewer +/******************************************************************************/ + +class TEveViewer : public TEveElementList +{ +private: + TEveViewer(const TEveViewer&); // Not implemented + TEveViewer& operator=(const TEveViewer&); // Not implemented + +protected: + TGLViewer *fGLViewer; + +public: + TEveViewer(const Text_t* n="TEveViewer", const Text_t* t=""); + virtual ~TEveViewer(); + + TGLViewer* GetGLViewer() const { return fGLViewer; } + void SetGLViewer(TGLViewer* s); + void SpawnGLViewer(const TGWindow* parent, TGedEditor* ged); + + virtual void AddScene(TEveScene* scene); + + virtual void RemoveElementLocal(TEveElement* el); + virtual void RemoveElementsLocal(); + + virtual TObject* GetEditorObject() const; + + virtual Bool_t HandleElementPaste(TEveElement* el); + + virtual const TGPicture* GetListTreeIcon() { return TEveElement::fgListTreeIcons[1]; } + + ClassDef(TEveViewer, 0); // Reve representation of TGLViewer. +}; + + +/******************************************************************************/ +// TEveViewerList +/******************************************************************************/ + +class TEveViewerList : public TEveElementList +{ +private: + TEveViewerList(const TEveViewerList&); // Not implemented + TEveViewerList& operator=(const TEveViewerList&); // Not implemented + +protected: + +public: + TEveViewerList(const Text_t* n="TEveViewerList", const Text_t* t=""); + virtual ~TEveViewerList(); + + void RepaintChangedViewers(Bool_t resetCameras, Bool_t dropLogicals); + void RepaintAllViewers(Bool_t resetCameras, Bool_t dropLogicals); + + void SceneDestructing(TEveScene* scene); + + ClassDef(TEveViewerList, 0); // List of Viewers providing common operations on TEveViewer collections. +}; + +#endif diff --git a/eve/src/TEveBoxSet.cxx b/eve/src/TEveBoxSet.cxx new file mode 100644 index 0000000000..b9d8e862a6 --- /dev/null +++ b/eve/src/TEveBoxSet.cxx @@ -0,0 +1,249 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include +#include +#include +#include + +//______________________________________________________________________________ +// TEveBoxSet +// +// Collection of 3D primitives (fixed-size boxes, boxes of different +// sizes, or arbitrary sexto-epipeds); each primitive can be assigned +// a signal value and a TRef. +// +// A collection of 3D-boxes. The way how the boxes are defined depends +// on the fBoxType data-member. +// BT_FreeBox arbitrary box: specify 8*(x,y,z) box corners +// BT_AABox axis-aligned box: specify (x,y,z) and (w, h, d) +// BT_AABoxFixedDim axis-aligned box w/ fixed dimensions: specify (x,y,z) +// also set fDefWidth, fDefHeight and fDefDepth +// +// Each box can be assigned: +// a) Color or signal value. Thresholds and signal-to-color mapping +// can then be set dynamically via the TEveRGBAPalette class. +// b) External TObject* (stored as TRef). +// +// See also base-class TEveDigitSet for more information. + +ClassImp(TEveBoxSet) + +//______________________________________________________________________________ +TEveBoxSet::TEveBoxSet(const Text_t* n, const Text_t* t) : + TEveDigitSet (n, t), + + fBoxType (BT_Undef), + fDefWidth (1), + fDefHeight (1), + fDefDepth (1) +{ + // Constructor. + + // Override from TEveDigitSet. + fDisableLigting = kFALSE; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +Int_t TEveBoxSet::SizeofAtom(TEveBoxSet::BoxType_e bt) +{ + // Return size of data-structure describing a box of type bt. + + static const TEveException eH("TEveBoxSet::SizeofAtom "); + + switch (bt) { + case BT_Undef: return 0; + case BT_FreeBox: return sizeof(BFreeBox); + case BT_AABox: return sizeof(BAABox); + case BT_AABoxFixedDim: return sizeof(BAABoxFixedDim); + default: throw(eH + "unexpected atom type."); + } + return 0; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveBoxSet::Reset(TEveBoxSet::BoxType_e boxType, Bool_t valIsCol, Int_t chunkSize) +{ + // Reset the data containers to zero size. + // The arguments describe the basic parameters of data storage. + + fBoxType = boxType; + fValueIsColor = valIsCol; + fDefaultValue = valIsCol ? 0 : kMinInt; + if (fOwnIds) + ReleaseIds(); + fPlex.Reset(SizeofAtom(fBoxType), chunkSize); +} + +//______________________________________________________________________________ +void TEveBoxSet::Reset() +{ + // Reset the data containers to zero size. + // Keep the old data-storage parameters. + + if (fOwnIds) + ReleaseIds(); + fPlex.Reset(SizeofAtom(fBoxType), TMath::Max(fPlex.N(), 64)); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveBoxSet::AddBox(const Float_t* verts) +{ + // Create a new box from a set of 8 vertices. + // To be used for box-type BT_FreeBox. + + static const TEveException eH("TEveBoxSet::AddBox "); + + if (fBoxType != BT_FreeBox) + throw(eH + "expect free box-type."); + + BFreeBox* b = (BFreeBox*) NewDigit(); + memcpy(b->fVertices, verts, sizeof(b->fVertices)); +} + +//______________________________________________________________________________ +void TEveBoxSet::AddBox(Float_t a, Float_t b, Float_t c, Float_t w, Float_t h, Float_t d) +{ + // Create a new axis-aligned box from at a given position and with + // specified dimensions. + // To be used for box-type BT_AABox. + + static const TEveException eH("TEveBoxSet::AddBox "); + + if (fBoxType != BT_AABox) + throw(eH + "expect axis-aligned box-type."); + + BAABox* box = (BAABox*) NewDigit(); + box->fA = a; box->fB = b; box->fC = c; + box->fW = w; box->fH = h; box->fD = d; +} + +//______________________________________________________________________________ +void TEveBoxSet::AddBox(Float_t a, Float_t b, Float_t c) +{ + // Create a new axis-aligned box from at a given position. + // To be used for box-type BT_AABoxFixedDim. + + static const TEveException eH("TEveBoxSet::AddBox "); + + if (fBoxType != BT_AABoxFixedDim) + throw(eH + "expect axis-aligned fixed-dimension box-type."); + + BAABoxFixedDim* box = (BAABoxFixedDim*) NewDigit(); + box->fA = a; box->fB = b; box->fC = c; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveBoxSet::ComputeBBox() +{ + // Fill bounding-box information of the base-class TAttBBox (virtual method). + // If member 'TEveFrameBox* fFrame' is set, frame's corners are used as bbox. + + static const TEveException eH("TEveBoxSet::ComputeBBox "); + + if (fFrame != 0) + { + BBoxInit(); + Int_t n = fFrame->GetFrameSize() / 3; + Float_t *bbps = fFrame->GetFramePoints(); + for (int i=0; i +#include + +#include +#include +#include +#include +#include + +//______________________________________________________________________________ +// TEveBoxSetGL +// +// A GL rendering class for TEveBoxSet. +// + +ClassImp(TEveBoxSetGL) + +//______________________________________________________________________________ +TEveBoxSetGL::TEveBoxSetGL() : fM(0), fBoxDL(0) +{ + // Default constructor. + + // fDLCache = false; // Disable display list. +} + +//______________________________________________________________________________ +TEveBoxSetGL::~TEveBoxSetGL() +{ + // Destructor. Noop. +} + +/******************************************************************************/ +// Protected methods +/******************************************************************************/ + +//______________________________________________________________________________ +Int_t TEveBoxSetGL::PrimitiveType() const +{ + // Return GL primitive used to render the boxes, based on the + // render-mode specified in the model object. + + return (fM->fRenderMode != TEveDigitSet::RM_TEveLine) ? GL_QUADS : GL_LINE_LOOP; +} + +//______________________________________________________________________________ +inline Bool_t TEveBoxSetGL::SetupColor(const TEveDigitSet::DigitBase& q) const +{ + // Set GL color for given primitive. + + if (fM->fValueIsColor) + { + glColor4ubv((UChar_t*) & q.fValue); + return kTRUE; + } + else + { + UChar_t c[4]; + Bool_t visible = fM->fPalette->ColorFromValue(q.fValue, fM->fDefaultValue, c); + if (visible) + glColor4ubv(c); + return visible; + } +} + +//______________________________________________________________________________ +void TEveBoxSetGL::MakeOriginBox(Float_t p[24], Float_t dx, Float_t dy, Float_t dz) const +{ + // Fill array p to represent a box (0,0,0) - (dx,dy,dz). + + // bottom + p[0] = 0; p[1] = dy; p[2] = 0; p += 3; + p[0] = dx; p[1] = dy; p[2] = 0; p += 3; + p[0] = dx; p[1] = 0; p[2] = 0; p += 3; + p[0] = 0; p[1] = 0; p[2] = 0; p += 3; + // top + p[0] = 0; p[1] = dy; p[2] = dz; p += 3; + p[0] = dx; p[1] = dy; p[2] = dz; p += 3; + p[0] = dx; p[1] = 0; p[2] = dz; p += 3; + p[0] = 0; p[1] = 0; p[2] = dz; +} + +//______________________________________________________________________________ +inline void TEveBoxSetGL::RenderBox(const Float_t p[24]) const +{ + // Render a box specified by points in array p. + + // bottom: 0123 + glNormal3f(0, 0, -1); + glVertex3fv(p); glVertex3fv(p + 3); + glVertex3fv(p + 6); glVertex3fv(p + 9); + // top: 7654 + glNormal3f(0, 0, 1); + glVertex3fv(p + 21); glVertex3fv(p + 18); + glVertex3fv(p + 15); glVertex3fv(p + 12); + // back: 0451 + glNormal3f(0, 1, 0); + glVertex3fv(p); glVertex3fv(p + 12); + glVertex3fv(p + 15); glVertex3fv(p + 3); + // front: 3267 + glNormal3f(0, -1, 0); + glVertex3fv(p + 9); glVertex3fv(p + 6); + glVertex3fv(p + 18); glVertex3fv(p + 21); + // left: 0374 + glNormal3f(-1, 0, 0); + glVertex3fv(p); glVertex3fv(p + 9); + glVertex3fv(p + 21); glVertex3fv(p + 12); + // right: 1562 + glNormal3f(1, 0, 0); + glVertex3fv(p + 3); glVertex3fv(p + 15); + glVertex3fv(p + 18); glVertex3fv(p + 6); +} + +//______________________________________________________________________________ +void TEveBoxSetGL::MakeDisplayList() const +{ + // Create a display-list for rendering a single box, based on the + // current box-type. + // Some box-types don't benefit from the display-list rendering and + // so display-list is not created. + + if (fM->fBoxType == TEveBoxSet::BT_AABox || + fM->fBoxType == TEveBoxSet::BT_AABoxFixedDim) + { + if (fBoxDL == 0) + fBoxDL = glGenLists(1); + + Float_t p[24]; + if (fM->fBoxType == TEveBoxSet::BT_AABox) + MakeOriginBox(p, 1.0f, 1.0f, 1.0f); + else + MakeOriginBox(p, fM->fDefWidth, fM->fDefHeight, fM->fDefDepth); + + glNewList(fBoxDL, GL_COMPILE); + glBegin(PrimitiveType()); + RenderBox(p); + glEnd(); + glEndList(); + } +} + +/******************************************************************************/ +// Virtuals from base-classes +/******************************************************************************/ + +//______________________________________________________________________________ +Bool_t TEveBoxSetGL::ShouldDLCache(const TGLRnrCtx & rnrCtx) const +{ + // Determines if display-list will be used for rendering. + // Virtual from TGLLogicalShape. + + MakeDisplayList(); + + if (rnrCtx.DrawPass() == TGLRnrCtx::kPassOutlineLine) + return kFALSE; + return TGLObject::ShouldDLCache(rnrCtx); +} + +//______________________________________________________________________________ +void TEveBoxSetGL::DLCacheDrop() +{ + // Called when display lists have been destroyed externally and the + // internal display-list data needs to be cleare. + // Virtual from TGLLogicalShape. + + fBoxDL = 0; + TGLObject::DLCacheDrop(); +} + +//______________________________________________________________________________ +void TEveBoxSetGL::DLCachePurge() +{ + // Called when display-lists need to be returned to the system. + // Virtual from TGLLogicalShape. + + static const TEveException eH("TEveBoxSetGL::DLCachePurge "); + + if (fBoxDL == 0) return; + if (fScene) + { + fScene->GetGLCtxIdentity()->RegisterDLNameRangeToWipe(fBoxDL, 1); + } + else + { + Warning(eH, "TEveScene unknown, attempting direct deletion."); + glDeleteLists(fBoxDL, 1); + } + TGLObject::DLCachePurge(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +Bool_t TEveBoxSetGL::SetModel(TObject* obj, const Option_t* /*opt*/) +{ + // Set model object. + // Virtual from TGLObject. + + Bool_t isok = SetModelCheckClass(obj, TEveBoxSet::Class()); + fM = isok ? dynamic_cast(obj) : 0; + return isok; +} + +//______________________________________________________________________________ +void TEveBoxSetGL::SetBBox() +{ + // Fill the bounding-box data of the logical-shape. + // Virtual from TGLObject. + + SetAxisAlignedBBox(fM->AssertBBox()); +} + +//______________________________________________________________________________ +void TEveBoxSetGL::DirectDraw(TGLRnrCtx & rnrCtx) const +{ + // Actual rendering code. + // Virtual from TGLLogicalShape. + + static const TEveException eH("TEveBoxSetGL::DirectDraw "); + + if (rnrCtx.DrawPass() == TGLRnrCtx::kPassOutlineLine) + return; + + TEveBoxSet& mB = * fM; + // printf("TEveBoxSetGL::DirectDraw N boxes %d\n", mB.fPlex.Size()); + if(mB.fPlex.Size() == 0) + return; + + glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + + if (mB.fRenderMode == TEveDigitSet::RM_Fill) + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + else if (mB.fRenderMode == TEveDigitSet::RM_TEveLine) + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + if (mB.fDisableLigting) glDisable(GL_LIGHTING); + + if (rnrCtx.SecSelection()) glPushName(0); + + Int_t boxSkip = 0; + if (rnrCtx.ShapeLOD() < 50) + boxSkip = 6 - (rnrCtx.ShapeLOD()+1)/10; + + TEveChunkManager::iterator bi(mB.fPlex); + + switch (mB.fBoxType) + { + + case TEveBoxSet::BT_FreeBox: + { + GLenum primitiveType = PrimitiveType(); + while (bi.next()) + { + TEveBoxSet::BFreeBox& b = * (TEveBoxSet::BFreeBox*) bi(); + if (SetupColor(b)) + { + if (rnrCtx.SecSelection()) glLoadName(bi.index()); + glBegin(primitiveType); + RenderBox(b.fVertices); + glEnd(); + } + if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); } + } + break; + } // end case free-box + + case TEveBoxSet::BT_AABox: + { + glEnable(GL_NORMALIZE); + while (bi.next()) + { + TEveBoxSet::BAABox& b = * (TEveBoxSet::BAABox*) bi(); + if (SetupColor(b)) + { + if (rnrCtx.SecSelection()) glLoadName(bi.index()); + glPushMatrix(); + glTranslatef(b.fA, b.fB, b.fC); + glScalef (b.fW, b.fH, b.fD); + glCallList(fBoxDL); + glPopMatrix(); + } + if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); } + } + break; + } + + case TEveBoxSet::BT_AABoxFixedDim: + { + while (bi.next()) + { + TEveBoxSet::BAABoxFixedDim& b = * (TEveBoxSet::BAABoxFixedDim*) bi(); + if (SetupColor(b)) + { + if (rnrCtx.SecSelection()) glLoadName(bi.index()); + glTranslatef(b.fA, b.fB, b.fC); + glCallList(fBoxDL); + glTranslatef(-b.fA, -b.fB, -b.fC); + } + if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); } + } + break; + } + + default: + { + throw(eH + "unsupported box-type."); + } + + } // end switch box-type + + if (rnrCtx.SecSelection()) glPopName(); + + glPopAttrib(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveBoxSetGL::ProcessSelection(TGLRnrCtx & /*rnrCtx*/, TGLSelectRecord & rec) +{ + // Processes secondary selection from TGLViewer. + // Calls TPointSet3D::PointSelected(Int_t) with index of selected + // point as an argument. + + if (rec.GetN() < 2) return; + fM->DigitSelected(rec.GetItem(1)); +} + +//______________________________________________________________________________ +void TEveBoxSetGL::Render(TGLRnrCtx & rnrCtx) +{ + // Interface for direct rendering from classes that include TEveBoxSet + // as a member. + + MakeDisplayList(); + DirectDraw(rnrCtx); + glDeleteLists(fBoxDL, 1); + fBoxDL = 0; +} diff --git a/eve/src/TEveBrowser.cxx b/eve/src/TEveBrowser.cxx new file mode 100644 index 0000000000..47228b0ab6 --- /dev/null +++ b/eve/src/TEveBrowser.cxx @@ -0,0 +1,595 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 + +#include +#include +#include +#include + +#include "TGFileBrowser.h" +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +//______________________________________________________________________________ +// TEveGListTreeEditorFrame +// +// Composite GUI frame for parallel display of a TGListTree and TEveGedEditor. +// + +ClassImp(TEveGListTreeEditorFrame) + +//______________________________________________________________________________ +TEveGListTreeEditorFrame::TEveGListTreeEditorFrame(const Text_t* name, Int_t width, Int_t height) : + TGMainFrame(gClient->GetRoot(), width, height), + fCtxMenu (0), + fNewSelected (0) +{ + SetWindowName(name); + SetCleanup(kNoCleanup); + + fFrame = new TGCompositeFrame(this, width, height, kVerticalFrame); + + // List-tree + fLTFrame = new TGCompositeFrame(fFrame, width, 3*height/7, kVerticalFrame); + fLTCanvas = new TGCanvas(fLTFrame, 10, 10, kSunkenFrame | kDoubleBorder); + fListTree = new TGListTree(fLTCanvas->GetViewPort(), 10, 10, kHorizontalFrame); + fListTree->SetCanvas(fLTCanvas); + fListTree->Associate(fFrame); + fListTree->SetColorMode(TGListTree::EColorMarkupMode(TGListTree::kColorUnderline | TGListTree::kColorBox)); + fListTree->SetAutoCheckBoxPic(kFALSE); + fLTCanvas->SetContainer(fListTree); + fLTFrame->AddFrame(fLTCanvas, new TGLayoutHints + (kLHintsNormal | kLHintsExpandX | kLHintsExpandY, 1, 1, 1, 1)); + fFrame ->AddFrame(fLTFrame, new TGLayoutHints + (kLHintsNormal | kLHintsExpandX | kLHintsExpandY)); + + // Splitter + fSplitter = new TGHSplitter(fFrame); + fFrame->AddFrame(fSplitter, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 1,1,2,2)); + + // Editor + fFrame->SetEditDisabled(kEditEnable); + fFrame->SetEditable(); + fEditor = new TEveGedEditor(0, width, 4*height/7); + fEditor->SetGlobal(kFALSE); + fEditor->ChangeOptions(fEditor->GetOptions() | kFixedHeight); + fFrame->SetEditable(kEditDisable); + fFrame->SetEditable(kFALSE); + { + TGFrameElement *el = 0; + TIter next(fFrame->GetList()); + while ((el = (TGFrameElement *) next())) { + if (el->fFrame == fEditor) + if (el->fLayout) { + el->fLayout->SetLayoutHints(kLHintsTop | kLHintsExpandX); + el->fLayout->SetPadLeft(0); el->fLayout->SetPadRight(1); + el->fLayout->SetPadTop(2); el->fLayout->SetPadBottom(1); + break; + } + } + } + fSplitter->SetFrame(fEditor, kFALSE); + + AddFrame(fFrame, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY)); + + fCtxMenu = new TContextMenu("", ""); + + fListTree->Connect("Checked(TObject*,Bool_t)", "TEveGListTreeEditorFrame", + this, "ItemChecked(TObject*, Bool_t)"); + fListTree->Connect("Clicked(TGListTreeItem*, Int_t, Int_t, Int_t)", "TEveGListTreeEditorFrame", + this, "ItemClicked(TGListTreeItem*, Int_t, Int_t, Int_t)"); + fListTree->Connect("DoubleClicked(TGListTreeItem*, Int_t)", "TEveGListTreeEditorFrame", + this, "ItemDblClicked(TGListTreeItem*, Int_t)"); + fListTree->Connect("KeyPressed(TGListTreeItem*, ULong_t, ULong_t)", "TEveGListTreeEditorFrame", + this, "ItemKeyPress(TGListTreeItem*, UInt_t, UInt_t)"); + + Layout(); + MapSubwindows(); + MapWindow(); +} + +//______________________________________________________________________________ +TEveGListTreeEditorFrame::~TEveGListTreeEditorFrame() +{ + delete fCtxMenu; + + // Should un-register editor, all items and list-tree from gEve ... eventually. + + delete fEditor; + delete fSplitter; + delete fListTree; + delete fLTCanvas; + delete fLTFrame; + delete fFrame; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGListTreeEditorFrame::ReconfToHorizontal() +{ + UnmapWindow(); + + fFrame->ChangeOptions(kHorizontalFrame); + fLTFrame->ChangeOptions(kHorizontalFrame); + fListTree->ChangeOptions(kVerticalFrame); + + TGFrameElement *el = 0; + TIter next(fFrame->GetList()); + while ((el = (TGFrameElement *) next())) + { + if (el->fFrame == fSplitter) + { + delete fSplitter; + el->fFrame = fSplitter = new TGVSplitter(fFrame); + el->fLayout->SetLayoutHints(kLHintsLeft | kLHintsExpandY); + el->fLayout->SetPadLeft(2); el->fLayout->SetPadRight (2); + el->fLayout->SetPadTop (1); el->fLayout->SetPadBottom(1); + } + else if (el->fFrame == fEditor) + { + fEditor->ChangeOptions(fEditor->GetOptions() & (~kFixedHeight)); + fEditor->ChangeOptions(fEditor->GetOptions() | kFixedWidth); + el->fLayout->SetLayoutHints(kLHintsLeft | kLHintsExpandY); + } + } + + fEditor->Resize(fEditor->GetWidth() / 2 - 1, fEditor->GetHeight()); + fSplitter->SetFrame(fEditor, kFALSE); + + Layout(); + //fFrame->Layout(); + //fLTFrame->Layout(); + //fLTCanvas->Layout(); + //fListTree->ClearViewPort(); + MapSubwindows(); + MapWindow(); +} + +//______________________________________________________________________________ +void TEveGListTreeEditorFrame::ReconfToVertical() +{ + UnmapWindow(); + + fFrame->ChangeOptions(kVerticalFrame); + fLTFrame->ChangeOptions(kVerticalFrame); + fListTree->ChangeOptions(kHorizontalFrame); + + TGFrameElement *el = 0; + TIter next(fFrame->GetList()); + while ((el = (TGFrameElement *) next())) + { + if (el->fFrame == fSplitter) + { + delete fSplitter; + el->fFrame = fSplitter = new TGHSplitter(fFrame); + el->fLayout->SetLayoutHints(kLHintsTop | kLHintsExpandX); + el->fLayout->SetPadLeft(2); el->fLayout->SetPadRight (2); + el->fLayout->SetPadTop (1); el->fLayout->SetPadBottom(1); + } + else if (el->fFrame == fEditor) + { + fEditor->ChangeOptions(fEditor->GetOptions() & (~kFixedWidth)); + fEditor->ChangeOptions(fEditor->GetOptions() | kFixedHeight); + el->fLayout->SetLayoutHints(kLHintsTop | kLHintsExpandX); + } + } + + fEditor->Resize(fEditor->GetWidth(), fEditor->GetHeight() / 2 - 1); + fSplitter->SetFrame(fEditor, kFALSE); + + Layout(); + //fFrame->Layout(); + //fLTFrame->Layout(); + //fLTCanvas->Layout(); + //fListTree->ClearViewPort(); + MapSubwindows(); + MapWindow(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGListTreeEditorFrame::ItemChecked(TObject* obj, Bool_t state) +{ + // Item's user-data is blindly casted into TObject. + // We recast it blindly back into the render element. + + TEveElement* rnrEl = (TEveElement*) obj; + gEve->ElementChecked(rnrEl, state); + gEve->Redraw3D(); +} + +//______________________________________________________________________________ +void TEveGListTreeEditorFrame::ItemClicked(TGListTreeItem *item, Int_t btn, Int_t x, Int_t y) +{ + //printf("ItemClicked item %s List %d btn=%d, x=%d, y=%d\n", + // item->GetText(),fDisplayFrame->GetList()->GetEntries(), btn, x, y); + + TEveElement* re = (TEveElement*)item->GetUserData(); + if(re == 0) return; + TObject* obj = re->GetObject(); + + switch (btn) + { + case 1: + gEve->ElementSelect(re); + break; + + case 2: + if (gEve->ElementPaste(re)) + gEve->Redraw3D(); + break; + + case 3: + // If control pressed, show menu for render-element itself. + // event->fState & kKeyControlMask + // ??? how do i get current event? + if (obj) fCtxMenu->Popup(x, y, obj); + break; + + default: + break; + } +} + +//______________________________________________________________________________ +void TEveGListTreeEditorFrame::ItemDblClicked(TGListTreeItem* item, Int_t btn) +{ + if (btn != 1) return; + + TEveElement* re = (TEveElement*) item->GetUserData(); + if (re == 0) return; + + re->ExpandIntoListTree(fListTree, item); + + TObject* obj = re->GetObject(); + if (obj) + { + // Browse geonodes. + if (obj->IsA()->InheritsFrom(TGeoNode::Class())) + { + TGeoNode* n = dynamic_cast(obj); + if (item->GetFirstChild() == 0 && n->GetNdaughters()) + { + fListTree->DeleteChildren(item); + for (Int_t i=0; i< n->GetNdaughters(); i++) + { + TString title; + title.Form("%d : %s[%d]", i, + n->GetDaughter(i)->GetVolume()->GetName(), + n->GetDaughter(i)->GetNdaughters()); + + TGListTreeItem* child = fListTree->AddItem( item, title.Data()); + child->SetUserData(n->GetDaughter(i)); + } + } + } + } +} + +//______________________________________________________________________________ +void TEveGListTreeEditorFrame::ItemKeyPress(TGListTreeItem *entry, UInt_t keysym, UInt_t /*mask*/) +{ + static const TEveException eH("TEveGListTreeEditorFrame::ItemKeyPress "); + + // replace entry with selected! + entry = fListTree->GetSelected(); + if (entry == 0) return; + + if (keysym == kKey_Delete) + { + TEveElement* rnr_el = dynamic_cast + ((TEveElement*) entry->GetUserData()); + if (rnr_el == 0) + return; + + if (entry->GetParent()) + { + if (rnr_el->GetDenyDestroy() > 0 && rnr_el->GetNItems() == 1) + throw(eH + "DestroyDenied set for this item."); + + TEveElement* parent_re = dynamic_cast + ((TEveElement*) entry->GetParent()->GetUserData()); + + if (parent_re) + { + ResetSelectedTimer(entry); + gEve->RemoveElement(rnr_el, parent_re); + gEve->Redraw3D(); + } + } + else + { + if (rnr_el->GetDenyDestroy() > 0) + throw(eH + "DestroyDenied set for this top-level item."); + ResetSelectedTimer(entry); + gEve->RemoveFromListTree(rnr_el, fListTree, entry); + gEve->Redraw3D(); + } + } +} + +//______________________________________________________________________________ +void TEveGListTreeEditorFrame::ResetSelectedTimer(TGListTreeItem* lti) +{ + fNewSelected = lti->GetPrevSibling(); + if (! fNewSelected) { + fNewSelected = lti->GetNextSibling(); + if (! fNewSelected) + fNewSelected = lti->GetParent(); + } + + TTimer::SingleShot(0, IsA()->GetName(), this, "ResetSelected()"); +} + +//______________________________________________________________________________ +void TEveGListTreeEditorFrame::ResetSelected() +{ + fListTree->HighlightItem(fNewSelected); + fListTree->SetSelected(fNewSelected); + fNewSelected = 0; +} + + +//______________________________________________________________________________ +// TEveBrowser +// +// Specialization of TRootBrowser for Reve. + +ClassImp(TEveBrowser) + +//______________________________________________________________________________ +void TEveBrowser::SetupCintExport(TClass* cl) +{ + TList* l = cl->GetMenuList(); + TClassMenuItem* n = new TClassMenuItem(TClassMenuItem::kPopupUserFunction, cl, + "Export to CINT", "ExportToCINT", this, "const char*,TObject*", 1); + + l->AddFirst(n); +} + +//______________________________________________________________________________ +void TEveBrowser::CalculateReparentXY(TGObject* parent, Int_t& x, Int_t& y) +{ + UInt_t w, h; + Window_t childdum; + gVirtualX->GetWindowSize(parent->GetId(), x, y, w, h); + gVirtualX->TranslateCoordinates(parent->GetId(), + gClient->GetDefaultRoot()->GetId(), + 0, 0, x, y, childdum); +} + +/******************************************************************************/ + +namespace +{ +enum ReveMenu_e { + kNewViewer, kNewScene, kNewProjector, + kNewBrowser, kNewCanvas, kNewCanvasExt, kNewTextEditor, kNewHtmlBrowser, + kVerticalBrowser +}; +} + +//______________________________________________________________________________ +TEveBrowser::TEveBrowser(UInt_t w, UInt_t h) : + TRootBrowser(0, "Reve Main Window", w, h, kFALSE), + fFileBrowser (0) +{ + // Construct TEveUtil menu + + fRevePopup = new TGPopupMenu(gClient->GetRoot()); + fRevePopup->AddEntry("New &TEveViewer", kNewViewer); + fRevePopup->AddEntry("New &TEveScene", kNewScene); + fRevePopup->AddEntry("New &Projector", kNewProjector); + fRevePopup->AddSeparator(); + fRevePopup->AddEntry("New &Browser", kNewBrowser); + fRevePopup->AddEntry("New &Canvas", kNewCanvas); + fRevePopup->AddEntry("New Canvas Ext", kNewCanvasExt); + fRevePopup->AddEntry("New Text Editor", kNewTextEditor); + // fRevePopup->AddEntry("New HTML Browser", kNewHtmlBrowser); + fRevePopup->AddSeparator(); + fRevePopup->AddEntry("Vertical browser", kVerticalBrowser); + fRevePopup->CheckEntry(kVerticalBrowser); + + fRevePopup->Connect("Activated(Int_t)", "TEveBrowser", + this, "ReveMenu(Int_t)"); + + fMenuBar->RemovePopup("Framework"); + // ?? should disconnect / delete. + fMenuBar->AddPopup("&TEveUtil", fRevePopup, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0)); + + fPreMenuFrame->ChangeOptions(fPreMenuFrame->GetOptions() | kRaisedFrame); + fTopMenuFrame->Layout(); + fTopMenuFrame->MapSubwindows(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveBrowser::ReveMenu(Int_t id) +{ + switch (id) + { + case kNewViewer: + gEve->SpawnNewViewer("TEveViewer Pepe"); + break; + + case kNewScene: + gEve->SpawnNewScene("Scena Mica"); + break; + + case kNewProjector: { + TEveElement* pr = (TEveElement*) (gROOT->GetClass("TEveProjectionManager")->New()); + pr->SetRnrElNameTitle("Projector", "User-created projector."); + gEve->AddToListTree(pr, kTRUE); + break; + } + case kNewBrowser: + gROOT->ProcessLineFast("new TBrowser"); + break; + + case kNewCanvas: + StartEmbedding(1); + gROOT->ProcessLineFast("new TCanvas"); + StopEmbedding(); + SetTabTitle("Canvas", 1); + break; + + case kNewCanvasExt: + gROOT->ProcessLineFast("new TCanvas"); + break; + + case kNewTextEditor: + StartEmbedding(1); + gROOT->ProcessLineFast(Form("new TGTextEditor((const char *)0, (const TGWindow *)0x%lx)", gClient->GetRoot())); + StopEmbedding(); + SetTabTitle("Editor", 1); + break; + + case kNewHtmlBrowser: + gSystem->Load("libGuiHtml"); + if (gSystem->Load("libRHtml") >= 0) + { + StartEmbedding(1); + gROOT->ProcessLine(Form("new TGHtmlBrowser(\"http://root.cern.ch/root/html/ClassIndex.html\", \ + (const TGWindow *)0x%lx)", gClient->GetRoot())); + StopEmbedding(); + SetTabTitle("HTML", 1); + } + break; + + case kVerticalBrowser: + if (fRevePopup->IsEntryChecked(kVerticalBrowser)) { + gEve->GetLTEFrame()->ReconfToHorizontal(); + fRevePopup->UnCheckEntry(kVerticalBrowser); + } else { + gEve->GetLTEFrame()->ReconfToVertical(); + fRevePopup->CheckEntry(kVerticalBrowser); + } + break; + + default: + break; + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveBrowser::InitPlugins() +{ + // File browser plugin... + StartEmbedding(0); + //gROOT->ProcessLine(Form("new TGFileBrowser((const TGWindow *)0x%lx, 200, 500)", + // gClient->GetRoot())); + { + TGFileBrowser *fb = MakeFileBrowser(); + fb->BrowseObj(gROOT); + fb->AddFSDirectory("/"); + fb->Show(); + + fFileBrowser = fb; + } + StopEmbedding(); + SetTabTitle("Files", 0); + + // Class browser plugin + /* + StartEmbedding(0); + gROOT->ProcessLine(Form("new TGClassBrowser((const TGWindow *)0x%lx, 200, 500)", + gClient->GetRoot())); + StopEmbedding(); + SetTabTitle("Classes", 0, 1); + */ + + // --- main frame + + // Canvas plugin... + /* Now in menu + StartEmbedding(1); + gROOT->ProcessLineFast("new TCanvas"); + StopEmbedding(); + SetTabTitle("Canvas", 1); + */ + + // Editor plugin... + /* Now in menu + StartEmbedding(1); + gROOT->ProcessLineFast(Form("new TGTextEditor((const char *)0, (const TGWindow *)0x%lx)", + gClient->GetRoot())); + StopEmbedding(); + SetTabTitle("Editor", 1); + */ + + // --- bottom area + + // Command plugin... + StartEmbedding(2); + gROOT->ProcessLineFast(Form("new TGCommandPlugin((const TGWindow *)0x%lx, 700, 300)", + gClient->GetRoot())); + StopEmbedding(); + SetTabTitle("Command", 2); + + // --- Select first tab everywhere + SetTab(0, 0); + SetTab(1, 0); + SetTab(2, 0); +} + +//______________________________________________________________________________ +TGFileBrowser* TEveBrowser::MakeFileBrowser() +{ + // Create a file-browser. Caller should provide + // Start/StopEmbedding() calls and populate the new browser. + + TBrowserImp imp; + TBrowser *tb = new TBrowser("Pipi", "Strel", &imp); + TGFileBrowser *fb = new TGFileBrowser(gClient->GetRoot(), tb, 200, 500); + tb->SetBrowserImp((TBrowserImp *)fb); + fb->SetBrowser(tb); + fb->SetNewBrowser(this); + return fb; +} diff --git a/eve/src/TEveChunkManager.cxx b/eve/src/TEveChunkManager.cxx new file mode 100644 index 0000000000..86be0d222e --- /dev/null +++ b/eve/src/TEveChunkManager.cxx @@ -0,0 +1,93 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 + +//______________________________________________________________________________ +// TEveChunkManager +// +// Vector-like container with chunked memory allocation. +// +// Allocation chunk can accommodate fN atoms of byte-size fS each. +// The chunks themselves are TArrayCs and are stored in a std::vector. +// Holes in the structure are not supported, neither is removal of atoms. +// The structure can be Refit() to occupy a single contiguous array. +// + +ClassImp(TEveChunkManager) +ClassImp(TEveChunkManager::iterator) + +void TEveChunkManager::ReleaseChunks() +{ + for (Int_t i=0; ifArray; + for (Int_t i=0; ifArray, size); + pos += size; + } + ReleaseChunks(); + fN = fCapacity = fSize; + fVecSize = 1; + fChunks.push_back(one); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +Char_t* TEveChunkManager::NewChunk() +{ + fChunks.push_back(new TArrayC(fS*fN)); + ++fVecSize; + fCapacity += fN; + return fChunks.back()->fArray; +} diff --git a/eve/src/TEveDigitSet.cxx b/eve/src/TEveDigitSet.cxx new file mode 100644 index 0000000000..a35a60b800 --- /dev/null +++ b/eve/src/TEveDigitSet.cxx @@ -0,0 +1,305 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 + +#include + +#include + +#include +#include +#include +#include + +//______________________________________________________________________________ +// TEveDigitSet +// +// Base-class for storage of digit collections; provides +// transformation matrix (TEveTrans), signal to color mapping +// (TEveRGBAPalette) and visual grouping (TEveFrameBox). +// +// Base-class for displaying a digit collection. +// Provdies common services for: +// - specifying signal / color per digit +// - specifying object reference per digit +// - controlling palette and thresholds (external object TEveRGBAPalette) +// - showing a frame around the digits (external object TEveFrameBox) +// - specifying transformation matrix for the whole collection +// by data-member of class TEveTrans. +// +// See also: +// TEveQuadSet: rectangle, hexagon or line per digit +// TEveBoxSet a 3D box per digit + +ClassImp(TEveDigitSet) + +//______________________________________________________________________________ +TEveDigitSet::TEveDigitSet(const Text_t* n, const Text_t* t) : + TEveElement (), + TNamed (n, t), + + fDefaultValue (kMinInt), + fValueIsColor (kFALSE), + fOwnIds (kFALSE), + fPlex (), + fLastDigit (0), + + fFrame (0), + fPalette (0), + fRenderMode (RM_Fill), + fDisableLigting (kTRUE), + fEmitSignals (kFALSE), + fHistoButtons (kTRUE), + fHMTrans () +{ + // Constructor. +} + +//______________________________________________________________________________ +TEveDigitSet::~TEveDigitSet() +{ + // Destructor. + // Unreference frame and palette. Destroy referenced objects if they + // are owned by the TEveDigitSet. + + SetFrame(0); + SetPalette(0); + if (fOwnIds) + ReleaseIds(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +TEveDigitSet::DigitBase* TEveDigitSet::NewDigit() +{ + // Protected method called whenever a new digit is added. + + fLastDigit = new (fPlex.NewAtom()) DigitBase(fDefaultValue); + return fLastDigit; +} + +//______________________________________________________________________________ +void TEveDigitSet::ReleaseIds() +{ + // Protected method. Release and delete the referenced objects, the + // ownership is *NOT* checked. + + TEveChunkManager::iterator qi(fPlex); + while (qi.next()) { + DigitBase& q = * (DigitBase*) qi(); + if (q.fId.GetObject()) { + delete q.fId.GetObject(); + q.fId = 0; + } + } +} + +/******************************************************************************/ +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveDigitSet::SetMainColor(Color_t color) +{ + // Override from TEveElement, forward to Frame. + + if (fFrame) { + fFrame->SetFrameColor(color); + fFrame->UpdateBackPtrItems(); + } + gEve->Redraw3D(); +} + +/******************************************************************************/ +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveDigitSet::RefitPlex() +{ + // Instruct underlying memory allocator to regroup itself into a + // contiguous memory chunk. + + fPlex.Refit(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveDigitSet::ScanMinMaxValues(Int_t& min, Int_t& max) +{ + // Iterate over the digits and detmine min and max signal values. + + if (fValueIsColor || fPlex.Size() == 0) return; + min = kMaxInt; + max = kMinInt; + for (Int_t c=0; cfValue; + if (v < min) min = v; + if (v > max) max = v; + a += fPlex.S(); + } + } + if (min == max) + --min; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveDigitSet::DigitValue(Int_t value) +{ + // Set signal value for the last digit added. + + fLastDigit->fValue = value; +} + +//______________________________________________________________________________ +void TEveDigitSet::DigitColor(Color_t ci) +{ + // Set color for the last digit added. + + TEveUtil::ColorFromIdx(ci, (UChar_t*) & fLastDigit->fValue, kTRUE); +} + +//______________________________________________________________________________ +void TEveDigitSet::DigitColor(UChar_t r, UChar_t g, UChar_t b, UChar_t a) +{ + // Set color for the last digit added. + + UChar_t* x = (UChar_t*) & fLastDigit->fValue; + x[0] = r; x[1] = g; x[2] = b; x[3] = a; +} + +//______________________________________________________________________________ +void TEveDigitSet::DigitColor(UChar_t* rgba) +{ + // Set color for the last digit added. + + UChar_t* x = (UChar_t*) & fLastDigit->fValue; + x[0] = rgba[0]; x[1] = rgba[1]; x[2] = rgba[2]; x[3] = rgba[3]; +} + +//______________________________________________________________________________ +void TEveDigitSet::DigitId(TObject* id) +{ + // Set external object reference for the last digit added. + + fLastDigit->fId = id; +} + +/******************************************************************************/ +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveDigitSet::Paint(Option_t* /*option*/) +{ + // Paint this object. Only direct rendering is supported. + + static const TEveException eH("TEveDigitSet::Paint "); + + TBuffer3D buff(TBuffer3DTypes::kGeneric); + + // Section kCore + buff.fID = this; + buff.fColor = fFrame ? fFrame->GetFrameColor() : 1; + buff.fTransparency = 0; + fHMTrans.SetBuffer3D(buff); + buff.SetSectionsValid(TBuffer3D::kCore); + + Int_t reqSections = gPad->GetViewer3D()->AddObject(buff); + if (reqSections != TBuffer3D::kNone) + Error(eH, "only direct GL rendering supported."); +} + +//______________________________________________________________________________ +void TEveDigitSet::DigitSelected(Int_t idx) +{ + // Called from renderer when a digit with index idx is selected. + + if (fEmitSignals) { + CtrlClicked(this, idx); + } else { + DigitBase* qb = GetDigit(idx); + TObject* obj = qb->fId.GetObject(); + printf("TEveDigitSet::DigitSelected idx=%d, value=%d, obj=0x%lx\n", + idx, qb->fValue, (ULong_t)obj); + if (obj) + obj->Print(); + } +} + +//______________________________________________________________________________ +void TEveDigitSet::CtrlClicked(TEveDigitSet* qs, Int_t idx) +{ + // Emit a CtrlClicked signal. + + Long_t args[2]; + args[0] = (Long_t) qs; + args[1] = (Long_t) idx; + + Emit("CtrlClicked(TEveDigitSet*, Int_t)", args); +} + +/******************************************************************************/ +// Getters / Setters for Frame, TEveRGBAPalette, TEveTrans +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveDigitSet::SetFrame(TEveFrameBox* b) +{ + // Set TEveFrameBox pointer. + + if (fFrame == b) return; + if (fFrame) fFrame->DecRefCount(this); + fFrame = b; + if (fFrame) { + fFrame->IncRefCount(this); + SetMainColorPtr(fFrame->PtrFrameColor()); + } else { + SetMainColorPtr(0); + } +} + +//______________________________________________________________________________ +void TEveDigitSet::SetPalette(TEveRGBAPalette* p) +{ + // Set TEveRGBAPalette pointer. + + if (fPalette == p) return; + if (fPalette) fPalette->DecRefCount(); + fPalette = p; + if (fPalette) fPalette->IncRefCount(); +} + +//______________________________________________________________________________ +TEveRGBAPalette* TEveDigitSet::AssertPalette() +{ + // Make sure the TEveRGBAPalette pointer is not null. + // If it is not set, a new one is instantiated and the range is set + // to current min/max signal values. + + if (fPalette == 0) { + fPalette = new TEveRGBAPalette; + if (!fValueIsColor) { + Int_t min, max; + ScanMinMaxValues(min, max); + fPalette->SetLimits(min, max); + fPalette->SetMinMax(min, max); + } + } + return fPalette; +} diff --git a/eve/src/TEveDigitSetEditor.cxx b/eve/src/TEveDigitSetEditor.cxx new file mode 100644 index 0000000000..03b9a4fbd1 --- /dev/null +++ b/eve/src/TEveDigitSetEditor.cxx @@ -0,0 +1,187 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +//______________________________________________________________________________ +// TEveDigitSetEditor +// +// Editor for TEveDigitSet class. + +ClassImp(TEveDigitSetEditor) + +//______________________________________________________________________________ +TEveDigitSetEditor::TEveDigitSetEditor(const TGWindow *p, Int_t width, Int_t height, + UInt_t options, Pixel_t back) : + TGedFrame(p, width, height, options | kVerticalFrame, back), + fM(0), + fHMTrans (0), + fPalette (0), + + fHistoButtFrame(0), + fInfoFrame(0) +{ + // Constructor. + + MakeTitle("Transformation matrix"); + + fHMTrans = new TEveTransSubEditor(this); + fHMTrans->Connect("UseTrans()", "TEveDigitSetEditor", this, "Update()"); + fHMTrans->Connect("TransChanged()", "TEveDigitSetEditor", this, "Update()"); + AddFrame(fHMTrans, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 2, 0, 0, 0)); + + + MakeTitle("Palette controls"); + + fPalette = new TEveRGBAPaletteSubEditor(this); + fPalette->Connect("Changed", "TEveDigitSetEditor", this, "Update()"); + AddFrame(fPalette, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 2, 0, 0, 0)); + + CreateInfoTab(); +} + +//______________________________________________________________________________ +TEveDigitSetEditor::~TEveDigitSetEditor() +{ + // Destructor. Noop. +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveDigitSetEditor::CreateInfoTab() +{ + // Create information tab. + + fInfoFrame = CreateEditorTabSubFrame("Info"); + + TGCompositeFrame *title1 = new TGCompositeFrame(fInfoFrame, 180, 10, + kHorizontalFrame | + kLHintsExpandX | + kFixedWidth | + kOwnBackground); + + title1->AddFrame(new TGLabel(title1, "TEveDigitSet Info"), + new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); + title1->AddFrame(new TGHorizontal3DLine(title1), + new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7)); + fInfoFrame->AddFrame(title1, new TGLayoutHints(kLHintsTop, 0, 0, 2, 0)); + + + fHistoButtFrame = new TGHorizontalFrame(fInfoFrame); + TGTextButton* b = 0; + b = new TGTextButton(fHistoButtFrame, "Histo"); + b->SetToolTipText("Show histogram over full range."); + fHistoButtFrame->AddFrame(b, new TGLayoutHints(kLHintsLeft|kLHintsExpandX, 1, 1, 0, 0)); + b->Connect("Clicked()", "TEveDigitSetEditor", this, "DoHisto()"); + + b = new TGTextButton(fHistoButtFrame, "Range Histo"); + b->SetToolTipText("Show histogram over selected range."); + fHistoButtFrame->AddFrame(b, new TGLayoutHints(kLHintsLeft|kLHintsExpandX, 1, 1, 0, 0)); + b->Connect("Clicked()", "TEveDigitSetEditor", this, "DoRangeHisto()"); + fInfoFrame->AddFrame(fHistoButtFrame, new TGLayoutHints(kLHintsExpandX, 2, 0, 0, 0)); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveDigitSetEditor::SetModel(TObject* obj) +{ + // Set model object. + + fM = dynamic_cast(obj); + + fHMTrans->SetDataFromTrans(&fM->fHMTrans); + + if (fM->fValueIsColor || fM->fPalette == 0) { + fPalette->UnmapWindow(); + } else { + fPalette->SetModel(fM->fPalette); + fPalette->MapWindow(); + } + + if (fM->fHistoButtons) + fHistoButtFrame->MapWindow(); + else + fHistoButtFrame->UnmapWindow(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveDigitSetEditor::DoHisto() +{ + // Show histogram slot. + + Int_t min, max; + if (fM->fPalette) { + min = fM->fPalette->GetLowLimit(); + max = fM->fPalette->GetHighLimit(); + } else { + fM->ScanMinMaxValues(min, max); + } + PlotHisto(min, max); +} + +//______________________________________________________________________________ +void TEveDigitSetEditor::DoRangeHisto() +{ + // Show ranged histogram slot. + + Int_t min, max; + if (fM->fPalette) { + min = fM->fPalette->GetMinVal(); + max = fM->fPalette->GetMaxVal(); + } else { + fM->ScanMinMaxValues(min, max); + } + PlotHisto(min, max); +} + +//______________________________________________________________________________ +void TEveDigitSetEditor::PlotHisto(Int_t min, Int_t max) +{ + // Plots a histogram from digit vales with given range. + + Int_t nbins = max-min+1; + while (nbins > 200) + nbins /= 2; + + TH1F* h = new TH1F(fM->GetName(), fM->GetTitle(), nbins, min-0.5, max+0.5); + h->SetDirectory(0); + h->SetBit(kCanDelete); + TEveChunkManager::iterator qi(fM->fPlex); + while (qi.next()) + h->Fill(((TEveDigitSet::DigitBase*)qi())->fValue); + + gStyle->SetOptStat(1111111); + h->Draw(); + gPad->Modified(); + gPad->Update(); +} diff --git a/eve/src/TEveElement.cxx b/eve/src/TEveElement.cxx new file mode 100644 index 0000000000..6da61528a7 --- /dev/null +++ b/eve/src/TEveElement.cxx @@ -0,0 +1,822 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include + +#include +#include +#include +#include + +#include + +//______________________________________________________________________________ +// TEveElement +// +// Base class for TEveUtil visualization elements, providing hierarchy +// management, rendering control and list-tree item management. + +ClassImp(TEveElement) + +//______________________________________________________________________________ +const TGPicture* TEveElement::fgRnrIcons[4] = { 0 }; +const TGPicture* TEveElement::fgListTreeIcons[8] = { 0 }; + +//______________________________________________________________________________ +TEveElement::TEveElement() : + fRnrSelf (kTRUE), + fRnrChildren (kTRUE), + fMainColorPtr (0), + fItems (), + fParents (), + fDestroyOnZeroRefCnt (kTRUE), + fDenyDestroy (0), + fChildren () +{ + // Default contructor. +} + +//______________________________________________________________________________ +TEveElement::TEveElement(Color_t& main_color) : + fRnrSelf (kTRUE), + fRnrChildren (kTRUE), + fMainColorPtr (&main_color), + fItems (), + fParents (), + fDestroyOnZeroRefCnt (kTRUE), + fDenyDestroy (0), + fChildren () +{ + // Constructor. +} + +//______________________________________________________________________________ +TEveElement::~TEveElement() +{ + // Destructor. + + static const TEveException _eh("TEveElement::TEveElement "); + + RemoveElements(); + + for (List_i p=fParents.begin(); p!=fParents.end(); ++p) + { + (*p)->RemoveElementLocal(this); + (*p)->fChildren.remove(this); + } + fParents.clear(); + + for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i) + i->fTree->DeleteItem(i->fItem); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveElement::SetRnrElNameTitle(const Text_t* name, const Text_t* title) +{ + // Virtual function for setting of name and title of render element. + // Here we attempt to cast the assigned object into TNamed and call + // SetNameTitle() there. + + TNamed* named = dynamic_cast(GetObject()); + if (named) + named->SetNameTitle(name, title); +} + +//______________________________________________________________________________ +const Text_t* TEveElement::GetRnrElName() const +{ + // Virtual function for retrieveing name of the render-element. + // Here we attempt to cast the assigned object into TNamed and call + // GetName() there. + + TObject* named = dynamic_cast(GetObject()); + return named ? named->GetName() : ""; +} + +//______________________________________________________________________________ +const Text_t* TEveElement::GetRnrElTitle() const +{ + // Virtual function for retrieveing title of the render-element. + // Here we attempt to cast the assigned object into TNamed and call + // GetTitle() there. + + TObject* named = dynamic_cast(GetObject()); + return named ? named->GetTitle() : ""; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveElement::AddParent(TEveElement* re) +{ + // Add re into the list parents. + // Adding parent is subordinate to adding an element. + // This is an internal function. + + fParents.push_back(re); +} + +//______________________________________________________________________________ +void TEveElement::RemoveParent(TEveElement* re) +{ + // Remove re from the list of parents. + // Removing parent is subordinate to removing an element. + // This is an internal function. + + static const TEveException eH("TEveElement::RemoveParent "); + + fParents.remove(re); + CheckReferenceCount(eH); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveElement::CheckReferenceCount(const TEveException& eh) +{ + // Check external references to this and eventually auto-destruct + // the render-element. + + if(fParents.empty() && fItems.empty() && + fDenyDestroy <= 0 && fDestroyOnZeroRefCnt) + { + if (gDebug > 0) + Info(eh, Form("auto-destructing '%s' on zero reference count.", GetRnrElName())); + + gEve->PreDeleteElement(this); + delete this; + } +} + +//______________________________________________________________________________ +void TEveElement::CollectSceneParents(List_t& scenes) +{ + // Collect all parents of class TEveScene. This is needed to + // automatically detect which scenes need to be updated. + // + // Overriden in TEveScene to include itself and return. + + for(List_i p=fParents.begin(); p!=fParents.end(); ++p) + (*p)->CollectSceneParents(scenes); +} + +//______________________________________________________________________________ +void TEveElement::CollectSceneParentsFromChildren(List_t& scenes, TEveElement* parent) +{ + // Collect scene-parents from all children. This is needed to + // automatically detect which scenes need to be updated during/after + // a full sub-tree update. + // Argument parent specifies parent in traversed hierarchy for which we can + // skip the upwards search. + + for (List_i p=fParents.begin(); p!=fParents.end(); ++p) + { + if (*p != parent) (*p)->CollectSceneParents(scenes); + } + + for (List_i c=fChildren.begin(); c!=fChildren.end(); ++c) + { + (*c)->CollectSceneParentsFromChildren(scenes, this); + } +} + +/******************************************************************************/ +// List-tree stuff +/******************************************************************************/ + +//______________________________________________________________________________ +Int_t TEveElement::ExpandIntoListTree(TGListTree* ltree, + TGListTreeItem* parent) +{ + // Populates parent with elements. + // parent must be an already existing representation of *this*. + // Returns number of inserted elements. + // If parent already has children, it does nothing. + // + // RnrEl can be inserted in a list-tree several times, thus we can not + // search through fItems to get parent here. + // Anyhow, it is probably known as it must have been selected by the user. + + if (parent->GetFirstChild() != 0) + return 0; + Int_t n = 0; + for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) { + (*i)->AddIntoListTree(ltree, parent); + ++n; + } + return n; +} + +//______________________________________________________________________________ +Int_t TEveElement::DestroyListSubTree(TGListTree* ltree, + TGListTreeItem* parent) +{ + Int_t n = 0; + TGListTreeItem* i = parent->GetFirstChild(); + while (i != 0) + { + //n += DestroyListSubTree(ltree, i); + TEveElement* re = (TEveElement*) i->GetUserData(); + i = i->GetNextSibling(); + re->RemoveFromListTree(ltree, parent); + } + return n; +} + +//______________________________________________________________________________ +TGListTreeItem* TEveElement::AddIntoListTree(TGListTree* ltree, + TGListTreeItem* parent_lti) +{ + // Add this render element into ltree to already existing item + // parent_lti. + + static const TEveException eH("TEveElement::AddIntoListTree "); + + TObject* tobj = GetObject(eH); + TGListTreeItem* item = ltree->AddItem(parent_lti, tobj->GetName(), this, + 0, 0, kTRUE); + item->SetCheckBoxPictures(GetCheckBoxPicture(1, fRnrChildren), + GetCheckBoxPicture(0, fRnrChildren)); + + item->SetPictures(GetListTreeIcon(),GetListTreeIcon()); + item->CheckItem(fRnrSelf); + + if (fMainColorPtr != 0) item->SetColor(GetMainColor()); + item->SetTipText(tobj->GetTitle()); + + fItems.insert(TEveListTreeInfo(ltree, item)); + ltree->ClearViewPort(); + + return item; +} + +//______________________________________________________________________________ +TGListTreeItem* TEveElement::AddIntoListTree(TGListTree* ltree, + TEveElement* parent) +{ + // Add this render element into ltree to all items belonging to + // parent. Returns list-tree-item from the first register entry (but + // we use a set for that so it can be anything). + + TGListTreeItem* lti = 0; + if (parent == 0) { + lti = AddIntoListTree(ltree, (TGListTreeItem*) 0); + } else { + for (sLTI_ri i = parent->fItems.rbegin(); i != parent->fItems.rend(); ++i) + { + if (i->fTree == ltree) + lti = AddIntoListTree(ltree, i->fItem); + } + } + return lti; +} + +//______________________________________________________________________________ +TGListTreeItem* TEveElement::AddIntoListTrees(TEveElement* parent) +{ + // Add this render element into all list-trees and all items + // belonging to parent. Returns list-tree-item from the first + // register entry (but we use a set for that so it can be anything). + + TGListTreeItem* lti = 0; + for (sLTI_ri i = parent->fItems.rbegin(); i != parent->fItems.rend(); ++i) + { + lti = AddIntoListTree(i->fTree, i->fItem); + } + return lti; +} + +//______________________________________________________________________________ +Bool_t TEveElement::RemoveFromListTree(TGListTree* ltree, + TGListTreeItem* parent_lti) +{ + static const TEveException eH("TEveElement::RemoveFromListTree "); + + sLTI_i i = FindItem(ltree, parent_lti); + if (i != fItems.end()) { + DestroyListSubTree(ltree, i->fItem); + ltree->DeleteItem(i->fItem); + ltree->ClearViewPort(); + fItems.erase(i); + if (parent_lti == 0) CheckReferenceCount(eH); + return kTRUE; + } else { + return kFALSE; + } +} + +//______________________________________________________________________________ +Int_t TEveElement::RemoveFromListTrees(TEveElement* parent) +{ + Int_t count = 0; + + sLTI_i i = fItems.begin(); + while (i != fItems.end()) + { + sLTI_i j = i++; + TGListTreeItem *plti = j->fItem->GetParent(); + if (plti != 0 && (TEveElement*) plti->GetUserData() == parent) + { + DestroyListSubTree(j->fTree, j->fItem); + j->fTree->DeleteItem(j->fItem); + j->fTree->ClearViewPort(); + fItems.erase(j); + ++count; + } + } + + return count; +} + +//______________________________________________________________________________ +TEveElement::sLTI_i TEveElement::FindItem(TGListTree* ltree) +{ + for (sLTI_i i = fItems.begin(); i != fItems.end(); ++i) + if (i->fTree == ltree) + return i; + return fItems.end(); +} + +//______________________________________________________________________________ +TEveElement::sLTI_i TEveElement::FindItem(TGListTree* ltree, + TGListTreeItem* parent_lti) +{ + for (sLTI_i i = fItems.begin(); i != fItems.end(); ++i) + if (i->fTree == ltree && i->fItem->GetParent() == parent_lti) + return i; + return fItems.end(); +} + +//______________________________________________________________________________ +TGListTreeItem* TEveElement::FindListTreeItem(TGListTree* ltree) +{ + for (sLTI_i i = fItems.begin(); i != fItems.end(); ++i) + if (i->fTree == ltree) + return i->fItem; + return 0; +} + +//______________________________________________________________________________ +TGListTreeItem* TEveElement::FindListTreeItem(TGListTree* ltree, + TGListTreeItem* parent_lti) +{ + for (sLTI_i i = fItems.begin(); i != fItems.end(); ++i) + if (i->fTree == ltree && i->fItem->GetParent() == parent_lti) + return i->fItem; + return 0; +} + +//______________________________________________________________________________ +void TEveElement::UpdateItems() +{ + // Update list-tree-items representing this render-element. + + static const TEveException eH("TEveElement::UpdateItems "); + + TObject* tobj = GetObject(eH); + + for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i) { + i->fItem->Rename(tobj->GetName()); + i->fItem->SetTipText(tobj->GetTitle()); + i->fItem->CheckItem(fRnrSelf); + if (fMainColorPtr != 0) i->fItem->SetColor(GetMainColor()); + i->fTree->ClearViewPort(); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +TObject* TEveElement::GetObject(TEveException eh) const +{ + // Get a TObject associated with this render-element. + // Most cases uses double-inheritance from TEveElement and TObject + // so we just do a dynamic cast here. + // If some TEveElement descendant implements a different scheme, + // this virtual method should be overriden accordingly. + + const TObject* obj = dynamic_cast(this); + if (obj == 0) + throw(eh + "not a TObject."); + return const_cast(obj); +} + +//______________________________________________________________________________ +void TEveElement::SpawnEditor() +{ + // Show GUI editor for this object. + + gEve->EditElement(this); +} + +//______________________________________________________________________________ +void TEveElement::ExportToCINT(Text_t* var_name) +{ + // Export render-element to CINT with variable name var_name. + + const char* cname = IsA()->GetName(); + gROOT->ProcessLine(Form("%s* %s = (%s*)0x%lx;", cname, var_name, cname, this)); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveElement::PadPaint(Option_t* option) +{ + // Paint self and/or children into currently active pad. + + if (GetRnrSelf() && GetObject()) + GetObject()->Paint(option); + + + if (GetRnrChildren()) { + for (List_i i=BeginChildren(); i!=EndChildren(); ++i) { + (*i)->PadPaint(option); + } + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveElement::SetRnrSelf(Bool_t rnr) +{ + if (rnr != fRnrSelf) + { + fRnrSelf = rnr; + + for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i) + { + if (i->fItem->IsChecked() != rnr) { + i->fItem->SetCheckBoxPictures(GetCheckBoxPicture(1, fRnrChildren), + GetCheckBoxPicture(0, fRnrChildren)); + i->fItem->CheckItem(fRnrSelf); + i->fTree->ClearViewPort(); + } + } + } +} + +//______________________________________________________________________________ +void TEveElement::SetRnrChildren(Bool_t rnr) +{ + if (rnr != fRnrChildren) + { + fRnrChildren = rnr; + + for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i) + { + i->fItem->SetCheckBoxPictures(GetCheckBoxPicture(fRnrSelf, fRnrChildren), + GetCheckBoxPicture(fRnrSelf, fRnrChildren)); + i->fTree->ClearViewPort(); + } + } +} + +//______________________________________________________________________________ +void TEveElement::SetRnrState(Bool_t rnr) +{ + if (fRnrSelf != rnr || fRnrChildren != rnr) + { + fRnrSelf = fRnrChildren = rnr; + + for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i) + { + i->fItem->SetCheckBoxPictures(GetCheckBoxPicture(1,1), GetCheckBoxPicture(0,0)); + i->fItem->CheckItem(fRnrSelf); + i->fTree->ClearViewPort(); + } + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveElement::SetMainColor(Color_t color) +{ + // Set main color of the render-element. + // List-tree-items are updated. + + Color_t oldcol = GetMainColor(); + for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) { + if ((*i)->GetMainColor() == oldcol) (*i)->SetMainColor(color); + } + + if (fMainColorPtr) { + *fMainColorPtr = color; + for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i) { + if (i->fItem->GetColor() != color) { + i->fItem->SetColor(GetMainColor()); + i->fTree->ClearViewPort(); + } + } + } +} + +//______________________________________________________________________________ +void TEveElement::SetMainColor(Pixel_t pixel) +{ + // Convert pixel to Color_t and call the above function. + + SetMainColor(Color_t(TColor::GetColor(pixel))); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +TGListTreeItem* TEveElement::AddElement(TEveElement* el) +{ + // Add el to the list of children. + + static const TEveException eH("TEveElement::AddElement "); + + if ( ! AcceptElement(el)) + throw(eH + Form("parent '%s' rejects '%s'.", + GetRnrElName(), el->GetRnrElName())); + + el->AddParent(this); + fChildren.push_back(el); + TGListTreeItem* ret = el->AddIntoListTrees(this); + ElementChanged(); + return ret; +} + +//______________________________________________________________________________ +void TEveElement::RemoveElement(TEveElement* el) +{ + // Remove el from the list of children. + + el->RemoveFromListTrees(this); + RemoveElementLocal(el); + el->RemoveParent(this); + fChildren.remove(el); + ElementChanged(); +} + +//______________________________________________________________________________ +void TEveElement::RemoveElementLocal(TEveElement* /*el*/) +{ + // Perform additional local removal of el. + // Called from RemoveElement() which does whole untangling. + // Put into special function as framework-related handling of + // element removal should really be common to all classes and + // clearing of local structures happens in between removal + // of list-tree-items and final removal. + // If you override this, you should also override + // RemoveElementsLocal(). +} + +//______________________________________________________________________________ +void TEveElement::RemoveElements() +{ + // Remove all elements. This assumes removing of all elements can be + // done more efficiently then looping over them and removing one by + // one. + + for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i) + { + DestroyListSubTree(i->fTree, i->fItem); + } + RemoveElementsLocal(); + for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) + { + (*i)->RemoveParent(this); + } + fChildren.clear(); + ElementChanged(); +} + +//______________________________________________________________________________ +void TEveElement::RemoveElementsLocal() +{ + // Perform additional local removal of all elements. + // See comment to RemoveelementLocal(TEveElement*). +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveElement::EnableListElements(Bool_t rnr_self, Bool_t rnr_children) +{ + // Enable rendering of children and their list contents. + // Arguments control how to set self/child rendering. + + for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) + { + (*i)->SetRnrSelf(rnr_self); + (*i)->SetRnrChildren(rnr_children); + } + + ElementChanged(kTRUE, kTRUE); +} + +//______________________________________________________________________________ +void TEveElement::DisableListElements(Bool_t rnr_self, Bool_t rnr_children) +{ + // Disable rendering of children and their list contents. + // Arguments control how to set self/child rendering. + // + // Same as above function, but default arguments are different. This + // is convenient for calls via context menu. + + for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) + { + (*i)->SetRnrSelf(rnr_self); + (*i)->SetRnrChildren(rnr_children); + } + + ElementChanged(kTRUE, kTRUE); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveElement::Destroy() +{ + static const TEveException eH("TEveElement::Destroy "); + + if (fDenyDestroy > 0) + throw(eH + "this element '%s' is protected against destruction.", GetRnrElName()); + + gEve->PreDeleteElement(this); + delete this; + gEve->Redraw3D(); +} + +//______________________________________________________________________________ +void TEveElement::DestroyElements() +{ + static const TEveException eH("TEveElement::DestroyElements "); + + while ( ! fChildren.empty()) { + TEveElement* c = fChildren.front(); + if (c->fDenyDestroy <= 0) + { + try { + c->Destroy(); + } + catch (TEveException exc) { + Warning(eH, Form("element destruction failed: '%s'.", exc.Data())); + RemoveElement(c); + } + } + else + { + if (gDebug > 0) + Info(eH, Form("element '%s' is protected agains destruction, removin locally.", c->GetRnrElName())); + + RemoveElement(c); + } + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +Bool_t TEveElement::HandleElementPaste(TEveElement* el) +{ + // React to element being pasted or dnd-ed. + // Return true if redraw is needed. + + gEve->AddElement(el, this); + return kTRUE; +} + +//______________________________________________________________________________ +void TEveElement::ElementChanged(Bool_t update_scenes, Bool_t redraw) +{ + if (update_scenes) + gEve->ElementChanged(this); + if (redraw) + gEve->Redraw3D(); +} + +/******************************************************************************/ +// Statics +/******************************************************************************/ + +//______________________________________________________________________________ +const TGPicture* +TEveElement::GetCheckBoxPicture(Bool_t rnrSelf, Bool_t rnrDaughters) +{ + Int_t idx = 0; + if (rnrSelf) idx = 2; + if (rnrDaughters ) idx++; + + return fgRnrIcons[idx]; +} + + +//______________________________________________________________________________ +// TEveElementObjectPtr +// +// TEveElement with external TObject as a holder of visualization data. + +ClassImp(TEveElementObjectPtr) + +//______________________________________________________________________________ +TEveElementObjectPtr::TEveElementObjectPtr(TObject* obj, Bool_t own) : + TEveElement(), + fObject(obj), + fOwnObject(own) +{ + // Constructor. +} + +//______________________________________________________________________________ +TEveElementObjectPtr::TEveElementObjectPtr(TObject* obj, Color_t& mainColor, Bool_t own) : + TEveElement(mainColor), + fObject(obj), + fOwnObject(own) +{ + // Constructor. +} + +//______________________________________________________________________________ +TObject* TEveElementObjectPtr::GetObject(TEveException eh) const +{ + // Return external object. + // Virtual from TEveElement. + + if(fObject == 0) + throw(eh + "fObject not set."); + return fObject; +} + +//______________________________________________________________________________ +void TEveElementObjectPtr::ExportToCINT(Text_t* var_name) +{ + // Export external object to CINT with variable name var_name. + // Virtual from TEveElement. + + static const TEveException eH("TEveElementObjectPtr::ExportToCINT "); + + TObject* obj = GetObject(eH); + const char* cname = obj->IsA()->GetName(); + gROOT->ProcessLine(Form("%s* %s = (%s*)0x%lx;", cname, var_name, cname, obj)); +} + +//______________________________________________________________________________ +TEveElementObjectPtr::~TEveElementObjectPtr() +{ + // Destructor. + + if(fOwnObject) + delete fObject; +} + + +/******************************************************************************/ +/******************************************************************************/ + +//______________________________________________________________________________ +// TEveElementList +// +// A list of TEveElements. +// +// Class of acceptable children can be limited by setting the +// fChildClass member. +// + +// !!! should have two ctors (like in TEveElement), one with Color_t& +// and set fDoColor automatically, based on which ctor is called. + +ClassImp(TEveElementList) + +//______________________________________________________________________________ +TEveElementList::TEveElementList(const Text_t* n, const Text_t* t, Bool_t doColor) : + TEveElement(), + TNamed(n, t), + fColor(0), + fDoColor(doColor), + fChildClass(0) +{ + // Constructor. + + if(fDoColor) { + SetMainColorPtr(&fColor); + } +} + +//______________________________________________________________________________ +Bool_t TEveElementList::AcceptElement(TEveElement* el) +{ + // Check if TEveElement el is inherited from fChildClass. + // Virtual from TEveElement. + + if (fChildClass && ! el->IsA()->InheritsFrom(fChildClass)) + return kFALSE; + return kTRUE; +} diff --git a/eve/src/TEveElementEditor.cxx b/eve/src/TEveElementEditor.cxx new file mode 100644 index 0000000000..33d30cc411 --- /dev/null +++ b/eve/src/TEveElementEditor.cxx @@ -0,0 +1,160 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +//______________________________________________________________________________ +// TEveElementEditor +// +// Editor for TEveElement class. + +ClassImp(TEveElementEditor) + +//______________________________________________________________________________ +TEveElementEditor::TEveElementEditor(const TGWindow *p, + Int_t width, Int_t height, + UInt_t options, Pixel_t back) : + TGedFrame(p, width, height, options | kVerticalFrame, back), + + fRE (0), + fHFrame (0), + fRnrSelf (0), + fRnrChildren (0), + fMainColor (0), + fTransparency (0), + fHMTrans (0) +{ + MakeTitle("TEveElement"); + fPriority = 0; + + fHFrame = new TGHorizontalFrame(this); + + fRnrSelf = new TGCheckButton(fHFrame, "RnrSelf"); + fHFrame->AddFrame(fRnrSelf, new TGLayoutHints(kLHintsLeft, 1, 2, 1, 1)); + fRnrSelf->Connect + ("Toggled(Bool_t)", + "TEveElementEditor", this, "DoRnrSelf()"); + + fRnrChildren = new TGCheckButton(fHFrame, "RnrChildren"); + fHFrame->AddFrame(fRnrChildren, new TGLayoutHints(kLHintsLeft, 2, 1, 1, 1)); + fRnrChildren->Connect + ("Toggled(Bool_t)", + "TEveElementEditor", this, "DoRnrChildren()"); + + fMainColor = new TGColorSelect(fHFrame, 0, -1); + fHFrame->AddFrame(fMainColor, new TGLayoutHints(kLHintsLeft, 2, 0, 1, 1)); + fMainColor->Connect + ("ColorSelected(Pixel_t)", + "TEveElementEditor", this, "DoMainColor(Pixel_t)"); + + fTransparency = new TGNumberEntry(fHFrame, 0., 2, -1, + TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, + TGNumberFormat::kNELLimitMinMax, 0, 100); + fTransparency->SetHeight(18); + fTransparency->GetNumberEntry()->SetToolTipText("Transparency: 0 is opaque, 100 fully transparent."); + fHFrame->AddFrame(fTransparency, new TGLayoutHints(kLHintsLeft, 0, 0, 2, 0)); + fTransparency->Connect + ("ValueSet(Long_t)", + "TEveElementEditor", this, "DoTransparency()"); + + AddFrame(fHFrame, new TGLayoutHints(kLHintsTop, 0, 0, 0, 0)); + + fHMTrans = new TEveTransSubEditor(this); + fHMTrans->Connect("UseTrans()", "TEveElementEditor", this, "Update()"); + fHMTrans->Connect("TransChanged()", "TEveElementEditor", this, "Update()"); + AddFrame(fHMTrans, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0, 0, 0, 0)); +} + +//______________________________________________________________________________ +TEveElementEditor::~TEveElementEditor() +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveElementEditor::SetModel(TObject* obj) +{ + fRE = dynamic_cast(obj); + + if (fRE->CanEditRnrElement()) { + fRnrSelf->SetState(fRE->GetRnrSelf() ? kButtonDown : kButtonUp); + fRnrChildren->SetState(fRE->GetRnrChildren() ? kButtonDown : kButtonUp); + fRnrSelf->MapWindow(); + fRnrChildren->MapWindow(); + } else { + fRnrSelf->UnmapWindow(); + fRnrChildren->UnmapWindow(); + } + + if (fRE->CanEditMainColor()) { + fMainColor->SetColor(TColor::Number2Pixel(fRE->GetMainColor()), kFALSE); + fMainColor->MapWindow(); + } else { + fMainColor->UnmapWindow(); + } + if (fRE->CanEditMainTransparency()) { + fTransparency->SetNumber(fRE->GetMainTransparency()); + fTransparency->MapWindow(); + } else { + fTransparency->UnmapWindow(); + } + if (fRE->CanEditMainHMTrans()) { + fHMTrans->SetDataFromTrans(fRE->PtrMainHMTrans()); + fHMTrans->MapWindow(); + } else { + fHMTrans->UnmapWindow(); + } + + fHFrame->Layout(); +} + +/******************************************************************************/ + + +//______________________________________________________________________________ +void TEveElementEditor::DoRnrSelf() +{ + fRE->SetRnrSelf(fRnrSelf->IsOn()); + Update(); +} + + +//______________________________________________________________________________ +void TEveElementEditor::DoRnrChildren() +{ + fRE->SetRnrChildren(fRnrChildren->IsOn()); + Update(); +} + +//______________________________________________________________________________ +void TEveElementEditor::DoMainColor(Pixel_t color) +{ + fRE->SetMainColor(color); + Update(); +} + +//______________________________________________________________________________ +void TEveElementEditor::DoTransparency() +{ + fRE->SetMainTransparency((UChar_t)(fTransparency->GetNumber())); + Update(); +} diff --git a/eve/src/TEveEventManager.cxx b/eve/src/TEveEventManager.cxx new file mode 100644 index 0000000000..6cf37132d5 --- /dev/null +++ b/eve/src/TEveEventManager.cxx @@ -0,0 +1,48 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 + +#include +#include + +//______________________________________________________________________________ +// TEveEventManager +// +// Base class for event management and navigation. + +ClassImp(TEveEventManager) + +//______________________________________________________________________________ +TEveEventManager::TEveEventManager(const Text_t* n, const Text_t* t) : + TEveElementList(n, t), + fNewEventCommands() +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveEventManager::AfterNewEventLoaded() +{ + TIter next(&fNewEventCommands); + TObject* o; + while ((o = next())) { + TObjString* s = dynamic_cast(o); + if (s) + gInterpreter->ProcessLine(s->String()); + } +} + +//______________________________________________________________________________ +void TEveEventManager::AddNewEventCommand(const Text_t* cmd) +{ + fNewEventCommands.Add(new TObjString(cmd)); +} diff --git a/eve/src/TEveFrameBox.cxx b/eve/src/TEveFrameBox.cxx new file mode 100644 index 0000000000..12252accfe --- /dev/null +++ b/eve/src/TEveFrameBox.cxx @@ -0,0 +1,168 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include + +//______________________________________________________________________________ +// TEveFrameBox +// +// Description of a 2D or 3D frame that can be used to visually group a set of objects. + +ClassImp(TEveFrameBox) + +//______________________________________________________________________________ +TEveFrameBox::TEveFrameBox() : + fFrameType (FT_None), + fFrameSize (0), + fFramePoints (0), + + fFrameWidth (1), + fFrameColor (1), + fBackColor (0), + fFrameFill (kFALSE), + fDrawBack (kFALSE) +{ + fFrameRGBA[0] = fFrameRGBA[1] = fFrameRGBA[2] = 0; fFrameRGBA[3] = 255; + fBackRGBA [0] = fBackRGBA [1] = fBackRGBA [2] = 255; fBackRGBA [3] = 255; +} + +//______________________________________________________________________________ +TEveFrameBox::~TEveFrameBox() +{ + delete [] fFramePoints; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveFrameBox::SetAAQuadXY(Float_t x, Float_t y, Float_t z, + Float_t dx, Float_t dy) +{ + fFrameType = FT_Quad; + fFrameSize = 12; + delete [] fFramePoints; + fFramePoints = new Float_t [fFrameSize]; + Float_t* p = fFramePoints; + p[0] = x; p[1] = y; p[2] = z; p += 3; + p[0] = x+dx; p[1] = y; p[2] = z; p += 3; + p[0] = x+dx; p[1] = y+dy; p[2] = z; p += 3; + p[0] = x ; p[1] = y+dy; p[2] = z; p += 3; +} + +//______________________________________________________________________________ +void TEveFrameBox::SetAAQuadXZ(Float_t x, Float_t y, Float_t z, + Float_t dx, Float_t dz) +{ + fFrameType = FT_Quad; + fFrameSize = 12; + delete [] fFramePoints; + fFramePoints = new Float_t [fFrameSize]; + Float_t* p = fFramePoints; + p[0] = x; p[1] = y; p[2] = z; p += 3; + p[0] = x+dx; p[1] = y; p[2] = z; p += 3; + p[0] = x+dx; p[1] = y; p[2] = z+dz; p += 3; + p[0] = x ; p[1] = y; p[2] = z+dz; p += 3; +} + +//______________________________________________________________________________ +void TEveFrameBox::SetAABox(Float_t x, Float_t y, Float_t z, + Float_t dx, Float_t dy, Float_t dz) +{ + fFrameType = FT_Box; + fFrameSize = 24; + delete [] fFramePoints; + fFramePoints = new Float_t [fFrameSize]; + + Float_t* p = fFramePoints; + //bottom + p[0] = x; p[1] = y + dy; p[2] = z; p += 3; + p[0] = x + dx; p[1] = y + dy; p[2] = z; p += 3; + p[0] = x + dx; p[1] = y; p[2] = z; p += 3; + p[0] = x; p[1] = y; p[2] = z; p += 3; + //top + p[0] = x; p[1] = y + dy; p[2] = z + dz; p += 3; + p[0] = x + dx; p[1] = y + dy; p[2] = z + dz; p += 3; + p[0] = x + dx; p[1] = y; p[2] = z + dz; p += 3; + p[0] = x; p[1] = y; p[2] = z + dz; +} + +//______________________________________________________________________________ +void TEveFrameBox::SetAABoxCenterHalfSize(Float_t x, Float_t y, Float_t z, + Float_t dx, Float_t dy, Float_t dz) +{ + fFrameType = FT_Box; + fFrameSize = 24; + delete [] fFramePoints; + fFramePoints = new Float_t [fFrameSize]; + + Float_t* p = fFramePoints; + //bottom + p[0] = x - dx; p[1] = y + dy; p[2] = z - dz; p += 3; + p[0] = x + dx; p[1] = y + dy; p[2] = z - dz; p += 3; + p[0] = x + dx; p[1] = y - dy; p[2] = z - dz; p += 3; + p[0] = x - dx; p[1] = y - dy; p[2] = z - dz; p += 3; + //top + p[0] = x - dx; p[1] = y + dy; p[2] = z + dz; p += 3; + p[0] = x + dx; p[1] = y + dy; p[2] = z + dz; p += 3; + p[0] = x + dx; p[1] = y - dy; p[2] = z + dz; p += 3; + p[0] = x - dx; p[1] = y - dy; p[2] = z + dz; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveFrameBox::SetFrameColor(Color_t ci) +{ + fFrameColor = ci; + TEveUtil::ColorFromIdx(ci, fFrameRGBA, kTRUE); +} + +//______________________________________________________________________________ +void TEveFrameBox::SetFrameColor(Pixel_t pix) +{ + SetFrameColor(Color_t(TColor::GetColor(pix))); +} + +//______________________________________________________________________________ +void TEveFrameBox::SetFrameColor(UChar_t r, UChar_t g, UChar_t b, UChar_t a) +{ + fFrameColor = Color_t(TColor::GetColor(r, g, b)); + fFrameRGBA[0] = r; + fFrameRGBA[1] = g; + fFrameRGBA[2] = b; + fFrameRGBA[3] = a; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveFrameBox::SetBackColor(Color_t ci) +{ + fBackColor = ci; + TEveUtil::ColorFromIdx(ci, fBackRGBA, kTRUE); +} + +//______________________________________________________________________________ +void TEveFrameBox::SetBackColor(Pixel_t pix) +{ + SetBackColor(Color_t(TColor::GetColor(pix))); +} + +//______________________________________________________________________________ +void TEveFrameBox::SetBackColor(UChar_t r, UChar_t g, UChar_t b, UChar_t a) +{ + fBackColor = Color_t(TColor::GetColor(r, g, b)); + fBackRGBA[0] = r; + fBackRGBA[1] = g; + fBackRGBA[2] = b; + fBackRGBA[3] = a; +} diff --git a/eve/src/TEveFrameBoxGL.cxx b/eve/src/TEveFrameBoxGL.cxx new file mode 100644 index 0000000000..0f719dd058 --- /dev/null +++ b/eve/src/TEveFrameBoxGL.cxx @@ -0,0 +1,101 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include + +#include + +#include + +//______________________________________________________________________________ +// TEveFrameBoxGL +// +// A class encapsulating GL rendering of TEveFrameBox via a static +// meber function. + +ClassImp(TEveFrameBoxGL) + +//______________________________________________________________________________ +void TEveFrameBoxGL::RenderFrame(const TEveFrameBox& b, Bool_t fillp) +{ + const Float_t* p = b.fFramePoints; + + if (b.fFrameType == TEveFrameBox::FT_Quad) + { + glBegin(fillp ? GL_POLYGON : GL_LINE_LOOP); + glVertex3fv(p); glVertex3fv(p + 3); + glVertex3fv(p + 6); glVertex3fv(p + 9); + glEnd(); + } + else if (b.fFrameType == TEveFrameBox::FT_Box) + { + // !!! frame-fill not implemented for 3D frame. + glBegin(GL_LINE_STRIP); + glVertex3fv(p); glVertex3fv(p + 3); + glVertex3fv(p + 6); glVertex3fv(p + 9); + glVertex3fv(p); + glVertex3fv(p + 12); glVertex3fv(p + 15); + glVertex3fv(p + 18); glVertex3fv(p + 21); + glVertex3fv(p + 12); + glEnd(); + glBegin(GL_LINES); + glVertex3fv(p + 3); glVertex3fv(p + 15); + glVertex3fv(p + 6); glVertex3fv(p + 18); + glVertex3fv(p + 9); glVertex3fv(p + 21); + glEnd(); + } +} + +//______________________________________________________________________________ +void TEveFrameBoxGL::Render(const TEveFrameBox* box) +{ + const TEveFrameBox& b = *box; + + glPushAttrib(GL_POLYGON_BIT | GL_LINE_BIT | GL_ENABLE_BIT); + + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + glDisable(GL_CULL_FACE); + + if (b.fFrameType == TEveFrameBox::FT_Quad && b.fDrawBack) + { + GLboolean lmts; + glGetBooleanv(GL_LIGHT_MODEL_TWO_SIDE, &lmts); + if (!lmts) glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); + + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(2, 2); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + const Float_t* p = b.fFramePoints; + Float_t normal[3]; + TMath::Normal2Plane(p, p+3, p+6, normal); + glNormal3fv(normal); + + glColor4ubv(b.fBackRGBA); + RenderFrame(b, kTRUE); + + if (!lmts) glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); + } + + glDisable(GL_LIGHTING); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_LINE_SMOOTH); + + glLineWidth(b.fFrameWidth); + glColor4ubv(b.fFrameRGBA); + RenderFrame(b, b.fFrameFill); + + glPopAttrib(); +} diff --git a/eve/src/TEveGLText.cxx b/eve/src/TEveGLText.cxx new file mode 100644 index 0000000000..16cec09a88 --- /dev/null +++ b/eve/src/TEveGLText.cxx @@ -0,0 +1,727 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +// The following implementation is based on TexFont API, +// implementation and accompanying programs by Mark J. Kilgard. +// Original license: + +/* Copyright (c) Mark J. Kilgard, 1997. */ +/* This program is freely distributable without licensing fees and is + provided without guarantee or warrantee expressed or implied. This + program is -not- in the public domain. */ + +#include + +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + + +/**********************/ +namespace TEveGLText { +/**********************/ + +TexFont* fgDefaultFont = 0; + +#if 0 +/* Uncomment to debug various scenarios. */ +#undef GL_VERSION_1_1 +#undef GL_EXT_texture_object +#undef GL_EXT_texture +#endif + +int useLuminanceAlpha = 1; + +/* byte swap a 32-bit value */ +#define SWAPL(x, n) { \ + n = ((char *) (x))[0]; \ + ((char *) (x))[0] = ((char *) (x))[3]; \ + ((char *) (x))[3] = n; \ + n = ((char *) (x))[1]; \ + ((char *) (x))[1] = ((char *) (x))[2]; \ + ((char *) (x))[2] = n; } + +/* byte swap a short */ +#define SWAPS(x, n) { \ + n = ((char *) (x))[0]; \ + ((char *) (x))[0] = ((char *) (x))[1]; \ + ((char *) (x))[1] = n; } + +/******************************************************************************/ + +//______________________________________________________________________________ +static TexGlyphVertexInfo* getTCVI(TexFont * txf, int c) +{ + TexGlyphVertexInfo *tgvi; + + /* Automatically substitute uppercase letters with lowercase if not + uppercase available (and vice versa). */ + if ((c >= txf->min_glyph) && (c < txf->min_glyph + txf->range)) { + tgvi = txf->lut[c - txf->min_glyph]; + if (tgvi) { + return tgvi; + } + if (islower(c)) { + c = toupper(c); + if ((c >= txf->min_glyph) && (c < txf->min_glyph + txf->range)) { + return txf->lut[c - txf->min_glyph]; + } + } + if (isupper(c)) { + c = tolower(c); + if ((c >= txf->min_glyph) && (c < txf->min_glyph + txf->range)) { + return txf->lut[c - txf->min_glyph]; + } + } + } + + //fprintf(stderr, "texfont: tried to access unavailable font character \"%c\" (%d)\n", + // isprint(c) ? c : ' ', c); + + tgvi = txf->lut[' ' - txf->min_glyph]; + if (tgvi) return tgvi; + tgvi = txf->lut['_' - txf->min_glyph]; + if (tgvi) return tgvi; + + return 0; +} + +/******************************************************************************/ + +static const char *lastError; + +//______________________________________________________________________________ +const char* txfErrorString(void) +{ + return lastError; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +TexFont* txfLoadFont(const char *filename) +{ + TexFont *txf; + FILE *file; + GLfloat w, h, xstep, ystep; + char fileid[4], tmp; + unsigned char *texbitmap; + int min_glyph, max_glyph; + int endianness, swap, format, stride, width, height; + int i, j, got; + + txf = NULL; + file = fopen(filename, "rb"); + if (file == NULL) { + lastError = "file open failed."; + goto error; + } + txf = (TexFont *) malloc(sizeof(TexFont)); + if (txf == NULL) { + lastError = "out of memory."; + goto error; + } + /* For easy cleanup in error case. */ + txf->texobj = 0; // MT add + txf->tgi = NULL; + txf->tgvi = NULL; + txf->lut = NULL; + txf->teximage = NULL; + + got = fread(fileid, 1, 4, file); + if (got != 4 || strncmp(fileid, "\377txf", 4)) { + lastError = "not a texture font file."; + goto error; + } + assert(sizeof(int) == 4); /* Ensure external file format size. */ + got = fread(&endianness, sizeof(int), 1, file); + if (got == 1 && endianness == 0x12345678) { + swap = 0; + } else if (got == 1 && endianness == 0x78563412) { + swap = 1; + } else { + lastError = "not a texture font file."; + goto error; + } +#define EXPECT(n) if (got != n) { lastError = "premature end of file."; goto error; } + got = fread(&format, sizeof(int), 1, file); + EXPECT(1); + got = fread(&txf->tex_width, sizeof(int), 1, file); + EXPECT(1); + got = fread(&txf->tex_height, sizeof(int), 1, file); + EXPECT(1); + got = fread(&txf->max_ascent, sizeof(int), 1, file); + EXPECT(1); + got = fread(&txf->max_descent, sizeof(int), 1, file); + EXPECT(1); + got = fread(&txf->num_glyphs, sizeof(int), 1, file); + EXPECT(1); + + if (swap) { + SWAPL(&format, tmp); + SWAPL(&txf->tex_width, tmp); + SWAPL(&txf->tex_height, tmp); + SWAPL(&txf->max_ascent, tmp); + SWAPL(&txf->max_descent, tmp); + SWAPL(&txf->num_glyphs, tmp); + } + txf->tgi = (TexGlyphInfo *) malloc(txf->num_glyphs * sizeof(TexGlyphInfo)); + if (txf->tgi == NULL) { + lastError = "out of memory."; + goto error; + } + assert(sizeof(TexGlyphInfo) == 12); /* Ensure external file format size. */ + got = fread(txf->tgi, sizeof(TexGlyphInfo), txf->num_glyphs, file); + EXPECT(txf->num_glyphs); + + if (swap) { + for (i = 0; i < txf->num_glyphs; i++) { + SWAPS(&txf->tgi[i].c, tmp); + SWAPS(&txf->tgi[i].x, tmp); + SWAPS(&txf->tgi[i].y, tmp); + } + } + txf->tgvi = (TexGlyphVertexInfo *) + malloc(txf->num_glyphs * sizeof(TexGlyphVertexInfo)); + if (txf->tgvi == NULL) { + lastError = "out of memory."; + goto error; + } + w = txf->tex_width; + h = txf->tex_height; + txf->max_width = 0; + xstep = 0.5 / w; + ystep = 0.5 / h; + for (i = 0; i < txf->num_glyphs; i++) { + TexGlyphInfo *tgi; + + tgi = &txf->tgi[i]; + txf->tgvi[i].t0[0] = tgi->x / w - xstep; // MT - xstep + txf->tgvi[i].t0[1] = tgi->y / h - ystep; // MT - ystep + txf->tgvi[i].v0[0] = tgi->xoffset; + txf->tgvi[i].v0[1] = tgi->yoffset; + txf->tgvi[i].t1[0] = (tgi->x + tgi->width) / w + xstep; + txf->tgvi[i].t1[1] = tgi->y / h - ystep; // MT - ystep + txf->tgvi[i].v1[0] = tgi->xoffset + tgi->width; + txf->tgvi[i].v1[1] = tgi->yoffset; + txf->tgvi[i].t2[0] = (tgi->x + tgi->width) / w + xstep; + txf->tgvi[i].t2[1] = (tgi->y + tgi->height) / h + ystep; + txf->tgvi[i].v2[0] = tgi->xoffset + tgi->width; + txf->tgvi[i].v2[1] = tgi->yoffset + tgi->height; + txf->tgvi[i].t3[0] = tgi->x / w - xstep; // MT - xstep + txf->tgvi[i].t3[1] = (tgi->y + tgi->height) / h + ystep; + txf->tgvi[i].v3[0] = tgi->xoffset; + txf->tgvi[i].v3[1] = tgi->yoffset + tgi->height; + txf->tgvi[i].advance = tgi->advance; + + if(tgi->width > txf->max_width) txf->max_width = tgi->width; + } + + min_glyph = txf->tgi[0].c; + max_glyph = txf->tgi[0].c; + for (i = 1; i < txf->num_glyphs; i++) { + if (txf->tgi[i].c < min_glyph) { + min_glyph = txf->tgi[i].c; + } + if (txf->tgi[i].c > max_glyph) { + max_glyph = txf->tgi[i].c; + } + } + txf->min_glyph = min_glyph; + txf->range = max_glyph - min_glyph + 1; + + txf->lut = (TexGlyphVertexInfo **) + calloc(txf->range, sizeof(TexGlyphVertexInfo *)); + if (txf->lut == NULL) { + lastError = "out of memory."; + goto error; + } + for (i = 0; i < txf->num_glyphs; i++) { + txf->lut[txf->tgi[i].c - txf->min_glyph] = &txf->tgvi[i]; + } + + switch (format) { + case TXF_FORMAT_BYTE: + if (useLuminanceAlpha) { + unsigned char *orig; + + orig = (unsigned char *) malloc(txf->tex_width * txf->tex_height); + if (orig == NULL) { + lastError = "out of memory."; + goto error; + } + got = fread(orig, 1, txf->tex_width * txf->tex_height, file); + EXPECT(txf->tex_width * txf->tex_height); + txf->teximage = (unsigned char *) + malloc(2 * txf->tex_width * txf->tex_height); + if (txf->teximage == NULL) { + lastError = "out of memory."; + goto error; + } + for (i = 0; i < txf->tex_width * txf->tex_height; i++) { + txf->teximage[i * 2] = orig[i]; + txf->teximage[i * 2 + 1] = orig[i]; + } + free(orig); + } else { + txf->teximage = (unsigned char *) + malloc(txf->tex_width * txf->tex_height); + if (txf->teximage == NULL) { + lastError = "out of memory."; + goto error; + } + got = fread(txf->teximage, 1, txf->tex_width * txf->tex_height, file); + EXPECT(txf->tex_width * txf->tex_height); + } + break; + case TXF_FORMAT_BITMAP: + width = txf->tex_width; + height = txf->tex_height; + stride = (width + 7) >> 3; + texbitmap = (unsigned char *) malloc(stride * height); + if (texbitmap == NULL) { + lastError = "out of memory."; + goto error; + } + got = fread(texbitmap, 1, stride * height, file); + EXPECT(stride * height); + if (useLuminanceAlpha) { + txf->teximage = (unsigned char *) calloc(width * height * 2, 1); + if (txf->teximage == NULL) { + lastError = "out of memory."; + goto error; + } + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + if (texbitmap[i * stride + (j >> 3)] & (1 << (j & 7))) { + txf->teximage[(i * width + j) * 2] = 255; + txf->teximage[(i * width + j) * 2 + 1] = 255; + } + } + } + } else { + txf->teximage = (unsigned char *) calloc(width * height, 1); + if (txf->teximage == NULL) { + lastError = "out of memory."; + goto error; + } + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + if (texbitmap[i * stride + (j >> 3)] & (1 << (j & 7))) { + txf->teximage[i * width + j] = 255; + } + } + } + } + free(texbitmap); + break; + } + + fclose(file); + return txf; + +error: + + if (txf) { + if (txf->tgi) + free(txf->tgi); + if (txf->tgvi) + free(txf->tgvi); + if (txf->lut) + free(txf->lut); + if (txf->teximage) + free(txf->teximage); + free(txf); + } + if (file) + fclose(file); + return NULL; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +GLuint txfEstablishTexture(TexFont * txf, GLuint texobj, + GLboolean setupMipmaps) +{ + if (txf->texobj == 0) { + if (texobj == 0) { + glGenTextures(1, &txf->texobj); + } else { + txf->texobj = texobj; + } + } + glBindTexture(GL_TEXTURE_2D, txf->texobj); + + if (useLuminanceAlpha) { + if (setupMipmaps) { + gluBuild2DMipmaps(GL_TEXTURE_2D, GL_LUMINANCE_ALPHA, + txf->tex_width, txf->tex_height, + GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, txf->teximage); + } else { + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, + txf->tex_width, txf->tex_height, 0, + GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, txf->teximage); + } + } else { + if (setupMipmaps) { + gluBuild2DMipmaps(GL_TEXTURE_2D, GL_INTENSITY4, + txf->tex_width, txf->tex_height, + GL_LUMINANCE, GL_UNSIGNED_BYTE, txf->teximage); + } else { + glTexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY4, + txf->tex_width, txf->tex_height, 0, + GL_LUMINANCE, GL_UNSIGNED_BYTE, txf->teximage); + } + } + + // MT: tried changing MIN/MAG filters ... bad idea. + + return txf->texobj; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void txfBindFontTexture(TexFont * txf) +{ + glBindTexture(GL_TEXTURE_2D, txf->texobj); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void txfUnloadFont(TexFont * txf) +{ + if (txf->texobj) { + glDeleteTextures(1, &txf->texobj); + } + if (txf->teximage) { + free(txf->teximage); + } + free(txf->tgi); + free(txf->tgvi); + free(txf->lut); + free(txf); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void txfGetStringMetrics(TexFont * txf, const char *TString, int len, + int &width, int &max_ascent, int &max_descent) +{ + TexGlyphVertexInfo *tgvi; + int w, i; + int ma = 0, md = 0; + + w = 0; + for (i = 0; i < len; i++) { + if (TString[i] == 27) { + switch (TString[i + 1]) { + case 'M': + i += 4; + break; + case 'T': + i += 7; + break; + case 'L': + i += 7; + break; + case 'F': + i += 13; + break; + } + } else { + tgvi = getTCVI(txf, TString[i]); + w += int(tgvi->advance); + ma = TMath::Max(ma, (int)( tgvi->v3[1])); + md = TMath::Max(md, (int)(-tgvi->v0[1])); + } + } + width = w; + max_ascent = ma; // txf->max_ascent; + max_descent = md; // txf->max_descent; + // printf("%d %d %d %d\n", txf->max_ascent, txf->max_descent, ma, md); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void txfRenderGlyph(TexFont * txf, int c) +{ + TexGlyphVertexInfo *tgvi; + + tgvi = getTCVI(txf, c); + glBegin(GL_QUADS); + glTexCoord2fv(tgvi->t0); + glVertex2sv(tgvi->v0); + glTexCoord2fv(tgvi->t1); + glVertex2sv(tgvi->v1); + glTexCoord2fv(tgvi->t2); + glVertex2sv(tgvi->v2); + glTexCoord2fv(tgvi->t3); + glVertex2sv(tgvi->v3); + glEnd(); + glTranslatef(tgvi->advance, 0.0, 0.0); +} + +//______________________________________________________________________________ +void txfRenderString(TexFont * txf, const char *TString, int len, + bool keep_pos) +{ + int i; + if(keep_pos) glPushMatrix(); + for (i = 0; i < len; i++) { + txfRenderGlyph(txf, TString[i]); + } + if(keep_pos) glPopMatrix(); +} + +//______________________________________________________________________________ +void txfRenderString(TexFont * txf, const char *TString, int len, + GLfloat maxx, GLfloat fadew, + bool keep_pos) +{ + GLfloat x = 0, xg0, xg1, yg0, yg1, f0, f1; + fadew *= txf->max_width; + GLfloat xfade = maxx - fadew; + + GLfloat col[4]; + glGetFloatv(GL_CURRENT_COLOR, col); + + glBegin(GL_QUADS); + for (int i = 0; i < len; i++) { + + TexGlyphVertexInfo *tgvi; + + tgvi = getTCVI(txf, TString[i]); + + xg0 = x + tgvi->v0[0]; + xg1 = x + tgvi->v1[0]; + yg0 = tgvi->v0[1]; + yg1 = tgvi->v2[1]; + + if(xg1 > xfade) { + f0 = 1; if(xg0 > xfade) f0 *= 1 - (xg0-xfade)/fadew; + f1 = 1 - (xg1-xfade)/fadew; + + // printf("XX %s %c %f %f x(%f,%f) y(%f,%f)\n", + // TString, TString[i], f0, f1, + // xg0, xg1,yg0, yg1); + + glColor4f(f0*col[0], f0*col[1], f0*col[2], f0*col[3]); + glTexCoord2fv(tgvi->t0); glVertex2f(xg0, yg0); + glColor4f(f1*col[0], f1*col[1], f1*col[2], f1*col[3]); + glTexCoord2fv(tgvi->t1); glVertex2f(xg1, yg0); + glTexCoord2fv(tgvi->t2); glVertex2f(xg1, yg1); + glColor4f(f0*col[0], f0*col[1], f0*col[2], f0*col[3]); + glTexCoord2fv(tgvi->t3); glVertex2f(xg0, yg1); + } else { + glTexCoord2fv(tgvi->t0); glVertex2f(xg0, yg0); + glTexCoord2fv(tgvi->t1); glVertex2f(xg1, yg0); + glTexCoord2fv(tgvi->t2); glVertex2f(xg1, yg1); + glTexCoord2fv(tgvi->t3); glVertex2f(xg0, yg1); + } + + x += tgvi->advance; + if(x > maxx) break; + } + glEnd(); + + if(!keep_pos) glTranslatef(x, 0.0, 0.0); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void txfRenderGlyphZW(TexFont * txf, int c, float z, float w) +{ + TexGlyphVertexInfo *tgvi; + + tgvi = getTCVI(txf, c); + glBegin(GL_QUADS); + glTexCoord2fv(tgvi->t0); + glVertex4f(tgvi->v0[0], tgvi->v0[1], z, w); + glTexCoord2fv(tgvi->t1); + glVertex4f(tgvi->v1[0], tgvi->v1[1], z, w); + glTexCoord2fv(tgvi->t2); + glVertex4f(tgvi->v2[0], tgvi->v2[1], z, w); + glTexCoord2fv(tgvi->t3); + glVertex4f(tgvi->v3[0], tgvi->v3[1], z, w); + glEnd(); + glTranslatef(tgvi->advance, 0.0, 0.0); +} + +//______________________________________________________________________________ +void txfRenderStringZW(TexFont * txf, const char *TString, int len, + float z, float w, bool keep_pos) +{ + int i; + + if(keep_pos) glPushMatrix(); + for (i = 0; i < len; i++) { + txfRenderGlyphZW(txf, TString[i], z, w); + } + if(keep_pos) glPopMatrix(); +} + +/******************************************************************************/ + +enum { + MONO, TOP_BOTTOM, LEFT_RIGHT, FOUR +}; + +/******************************************************************************/ + +//______________________________________________________________________________ +void txfRenderFancyString(TexFont * txf, char *TString, int len) +{ + TexGlyphVertexInfo *tgvi; + GLubyte c[4][3]; + int mode = MONO; + int i; + + for (i = 0; i < len; i++) { + if (TString[i] == 27) { + switch (TString[i + 1]) { + case 'M': + mode = MONO; + glColor3ubv((GLubyte *) & TString[i + 2]); + i += 4; + break; + case 'T': + mode = TOP_BOTTOM; + memcpy(c, &TString[i + 2], 6); + i += 7; + break; + case 'L': + mode = LEFT_RIGHT; + memcpy(c, &TString[i + 2], 6); + i += 7; + break; + case 'F': + mode = FOUR; + memcpy(c, &TString[i + 2], 12); + i += 13; + break; + } + } else { + switch (mode) { + case MONO: + txfRenderGlyph(txf, TString[i]); + break; + case TOP_BOTTOM: + tgvi = getTCVI(txf, TString[i]); + glBegin(GL_QUADS); + glColor3ubv(c[0]); + glTexCoord2fv(tgvi->t0); + glVertex2sv(tgvi->v0); + glTexCoord2fv(tgvi->t1); + glVertex2sv(tgvi->v1); + glColor3ubv(c[1]); + glTexCoord2fv(tgvi->t2); + glVertex2sv(tgvi->v2); + glTexCoord2fv(tgvi->t3); + glVertex2sv(tgvi->v3); + glEnd(); + glTranslatef(tgvi->advance, 0.0, 0.0); + break; + case LEFT_RIGHT: + tgvi = getTCVI(txf, TString[i]); + glBegin(GL_QUADS); + glColor3ubv(c[0]); + glTexCoord2fv(tgvi->t0); + glVertex2sv(tgvi->v0); + glColor3ubv(c[1]); + glTexCoord2fv(tgvi->t1); + glVertex2sv(tgvi->v1); + glColor3ubv(c[1]); + glTexCoord2fv(tgvi->t2); + glVertex2sv(tgvi->v2); + glColor3ubv(c[0]); + glTexCoord2fv(tgvi->t3); + glVertex2sv(tgvi->v3); + glEnd(); + glTranslatef(tgvi->advance, 0.0, 0.0); + break; + case FOUR: + tgvi = getTCVI(txf, TString[i]); + glBegin(GL_QUADS); + glColor3ubv(c[0]); + glTexCoord2fv(tgvi->t0); + glVertex2sv(tgvi->v0); + glColor3ubv(c[1]); + glTexCoord2fv(tgvi->t1); + glVertex2sv(tgvi->v1); + glColor3ubv(c[2]); + glTexCoord2fv(tgvi->t2); + glVertex2sv(tgvi->v2); + glColor3ubv(c[3]); + glTexCoord2fv(tgvi->t3); + glVertex2sv(tgvi->v3); + glEnd(); + glTranslatef(tgvi->advance, 0.0, 0.0); + break; + } + } + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +int txfInFont(TexFont * txf, int c) +{ + /* NOTE: No uppercase/lowercase substituion. */ + if ((c >= txf->min_glyph) && (c < txf->min_glyph + txf->range)) { + if (txf->lut[c - txf->min_glyph]) { + return 1; + } + } + return 0; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +bool LoadDefaultFont( TString file) +{ + static const TEveException _eh("TEveGLText::LoadFont "); + + if(fgDefaultFont) { + txfUnloadFont(fgDefaultFont); + fgDefaultFont = 0; + } + + fgDefaultFont = TEveGLText::txfLoadFont(file.Data()); + if(fgDefaultFont != 0) { + txfEstablishTexture(fgDefaultFont, 0, GL_TRUE); + return true; + } + else { + throw(_eh + Form("Error loading font from file '%s': %s", + file.Data(), txfErrorString())); + } + + return false; +} + +} // end TEveGLText diff --git a/eve/src/TEveGLUtil.cxx b/eve/src/TEveGLUtil.cxx new file mode 100644 index 0000000000..fb5c39e8db --- /dev/null +++ b/eve/src/TEveGLUtil.cxx @@ -0,0 +1,215 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include + +#include +#include +#include + +//______________________________________________________________________________ +// TEveGLUtil +// +// Commonly used utilities for GL rendering. + +ClassImp(TEveGLUtil) + +//______________________________________________________________________________ +void TEveGLUtil::RenderLine(const TAttLine& aline, Float_t* p, Int_t n, + Bool_t /*selection*/, Bool_t /*sec_selection*/) +{ + if(n == 0) return; + + glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT); + glDisable(GL_LIGHTING); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + UChar_t color[4]; + TEveUtil::ColorFromIdx(aline.GetLineColor(), color); + glColor4ubv(color); + glLineWidth(aline.GetLineWidth()); + if (aline.GetLineStyle() > 1) { + Int_t fac = 1; + UShort_t pat = 0xffff; + switch (aline.GetLineStyle()) { + case 2: pat = 0x3333; break; + case 3: pat = 0x5555; break; + case 4: pat = 0xf040; break; + case 5: pat = 0xf4f4; break; + case 6: pat = 0xf111; break; + case 7: pat = 0xf0f0; break; + case 8: pat = 0xff11; break; + case 9: pat = 0x3fff; break; + case 10: pat = 0x08ff; fac = 2; break; + } + + glLineStipple(1, pat); + glEnable(GL_LINE_STIPPLE); + } + + Float_t* tp = p; + glBegin(GL_LINE_STRIP); + for (Int_t i=0; i sPickRadius) + { + changePM = kTRUE; + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + Float_t pm[16]; + glGetFloatv(GL_PROJECTION_MATRIX, pm); + Float_t scale = (Float_t) sPickRadius / size; + for (Int_t i=0; i<=12; i+=4) { + pm[i] *= scale; pm[i+1] *= scale; + } + glLoadMatrixf(pm); + } + + Float_t* p = op; + if (sec_selection) + { + glPushName(0); + for (Int_t i=0; i maxChunk) + { + glDrawArrays(GL_POINTS, ndone, maxChunk); + nleft -= maxChunk; + ndone += maxChunk; + } + glDrawArrays(GL_POINTS, ndone, nleft); + } + glPopClientAttrib(); + } + + if (changePM) + { + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + } + +} + +//______________________________________________________________________________ +void TEveGLUtil::RenderCrosses(const TAttMarker& marker, Float_t* op, Int_t n, + Bool_t sec_selection) +{ + // Render markers as crosses. + // + if (marker.GetMarkerStyle() == 28) + { + glEnable(GL_BLEND); + glEnable(GL_LINE_SMOOTH); + glLineWidth(2); + } + else + { + glDisable(GL_LINE_SMOOTH); + } + + // cross dim + const Float_t d = 2*marker.GetMarkerSize(); + Float_t* p = op; + if (sec_selection) + { + glPushName(0); + for (Int_t i=0; i + +#include +#include +#include +#include + + +//______________________________________________________________________________ +// TEveGValuatorBase +// +// Base class for composite GUI elements for setting of numeric +// values. + +ClassImp(TEveGValuatorBase) + +//______________________________________________________________________________ +TEveGValuatorBase::TEveGValuatorBase(const TGWindow *p, const char* name, + UInt_t w, UInt_t h) : + TGCompositeFrame(p, w, h), + + fLabelWidth (0), + fAlignRight (kFALSE), + fShowSlider (kTRUE), + + fNELength (5), + fNEHeight (20), + + fLabel (0) +{ + SetName(name); +} + +//______________________________________________________________________________ +// TEveGValuator +// +// Composite GUI element for single value selection (supports label, +// number-entry and slider). + +ClassImp(TEveGValuator) + +//______________________________________________________________________________ +TEveGValuator::TEveGValuator(const TGWindow *p, const char* title, + UInt_t w, UInt_t h) : + TEveGValuatorBase(p, title, w, h), + + fValue (0), + fMin (0), + fMax (0), + + fSliderNewLine (kFALSE), + fSliderDivs (-1), + fEntry (0), + fSlider (0) +{} + +//______________________________________________________________________________ +void TEveGValuator::Build(Bool_t connect) +{ + TGCompositeFrame *hf1, *hfs; + if(fShowSlider && fSliderNewLine) { + SetLayoutManager(new TGVerticalLayout(this)); + hf1 = new TGHorizontalFrame(this); + hf1->SetLayoutManager(new TGHorizontalLayout(hf1)); + AddFrame(hf1, new TGLayoutHints(kLHintsTop, 0,0,0,0)); + hfs = new TGHorizontalFrame(this); + hfs->SetLayoutManager(new TGHorizontalLayout(hfs)); + AddFrame(hfs, new TGLayoutHints(kLHintsTop, 0,0,0,0)); + } else { + hf1 = this; + hfs = this; + SetLayoutManager(new TGHorizontalLayout(this)); + } + + // label + { + TGLayoutHints *labh, *labfrh; + if(fAlignRight) { + labh = new TGLayoutHints(kLHintsRight | kLHintsBottom, 4,0,0,0); + labfrh = new TGLayoutHints(kLHintsRight); + } else { + labh = new TGLayoutHints(kLHintsLeft | kLHintsBottom, 0,4,0,0); + labfrh = new TGLayoutHints(kLHintsLeft); + } + TGCompositeFrame *labfr = + new TGHorizontalFrame(hf1, fLabelWidth, fNEHeight, + fLabelWidth != 0 ? kFixedSize : kFixedHeight); + fLabel = new TGLabel(labfr, fName); + labfr->AddFrame(fLabel, labh); + hf1->AddFrame(labfr, labfrh); + } + + // number-entry + TGLayoutHints* elh = new TGLayoutHints(kLHintsLeft, 0,0,0,0); + fEntry = new TGNumberEntry(hf1, 0, fNELength); + fEntry->SetHeight(fNEHeight); + fEntry->GetNumberEntry()->SetToolTipText("Enter Slider Value"); + hf1->AddFrame(fEntry, elh); + + fEntry->Associate(this); + if (connect) + fEntry->Connect("ValueSet(Long_t)", + "TEveGValuator", this, "EntryCallback()"); + + // slider + if(fShowSlider) { + fSlider = new TGHSlider(hfs, GetWidth(), kSlider1 | kScaleBoth); + hfs->AddFrame(fSlider, new TGLayoutHints(kLHintsLeft|kLHintsTop, 1,1,0,0)); + + fSlider->Associate(this); + if (connect) + fSlider->Connect("PositionChanged(Int_t)", + "TEveGValuator", this, "SliderCallback()"); + } +} + +//______________________________________________________________________________ +void TEveGValuator::SetLimits(Float_t min, Float_t max, Int_t npos, + TGNumberFormat::EStyle nef) +{ + fMin = Float_t(min); + fMax = Float_t(max); + fEntry->SetFormat(nef); + fEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, min, max); + + if(fSlider) { + fSliderDivs = npos - 1; + fSlider->SetRange(0, fSliderDivs); + } +} + +//______________________________________________________________________________ +void TEveGValuator::SetLimits(Int_t min, Int_t max) +{ + fMin = Float_t(min); + fMax = Float_t(max); + fEntry->SetFormat(TGNumberFormat::kNESInteger); + fEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, min, max); + + if(fSlider) { + fSliderDivs = max - min; + fSlider->SetRange(0, fSliderDivs); + } +} + +//______________________________________________________________________________ +Int_t TEveGValuator::CalcSliderPos(Float_t v) +{ + return (Int_t) TMath::Nint((v - fMin)*fSliderDivs/(fMax - fMin)); +} + +//______________________________________________________________________________ +void TEveGValuator::EntryCallback() +{ + fValue = fEntry->GetNumber(); + if(fSlider) { + fSlider->SetPosition(CalcSliderPos(fValue)); + } + ValueSet(fValue); +} + +//______________________________________________________________________________ +void TEveGValuator::SliderCallback() +{ + fValue = fMin + fSlider->GetPosition()*(fMax-fMin)/fSliderDivs; + fEntry->SetNumber(fValue); + ValueSet(fValue); +} + + +//______________________________________________________________________________ +void TEveGValuator::ValueSet(Double_t val) +{ + Emit("ValueSet(Double_t)", val); +} + +//______________________________________________________________________________ +void TEveGValuator::SetValue(Float_t val, Bool_t emit) +{ + fValue = val; + fEntry->SetNumber(fValue); + + if(fSlider){ + fSlider->SetPosition(CalcSliderPos(fValue)); + } + if(emit) + ValueSet(val); +} + +//______________________________________________________________________________ +void TEveGValuator::SetToolTip(const Text_t* tip) +{ + fEntry->GetNumberEntry()->SetToolTipText(tip); +} + +//______________________________________________________________________________ +void TEveGValuator::SetEnabled(Bool_t state) +{ + fEntry->GetNumberEntry()->SetEnabled(state); + fEntry->GetButtonUp()->SetEnabled(state); + fEntry->GetButtonDown()->SetEnabled(state); + if(fSlider) { + if(state) fSlider->MapWindow(); + else fSlider->UnmapWindow(); + } +} + + +/******************************************************************************/ +// TEveGDoubleValuator +// +// Composite GUI element for selection of range (label, two +// number-entries and double-slider). + +ClassImp(TEveGDoubleValuator) + +//______________________________________________________________________________ +TEveGDoubleValuator::TEveGDoubleValuator(const TGWindow *p, const char* title, + UInt_t w, UInt_t h) : + TEveGValuatorBase(p, title, w, h), + + fMinEntry(0), + fMaxEntry(0), + fSlider(0) +{} + +//______________________________________________________________________________ +void TEveGDoubleValuator::Build(Bool_t connect) +{ + TGCompositeFrame *hf1, *hfs; + if(fShowSlider) { + SetLayoutManager(new TGVerticalLayout(this)); + hf1 = new TGHorizontalFrame(this); + hf1->SetLayoutManager(new TGHorizontalLayout(hf1)); + AddFrame(hf1, new TGLayoutHints(kLHintsTop, 0,0,0,0)); + hfs = new TGHorizontalFrame(this); + hfs->SetLayoutManager(new TGHorizontalLayout(hfs)); + AddFrame(hfs, new TGLayoutHints(kLHintsTop, 0,0,0,0)); + } else { + hf1 = this; + hfs = this; + SetLayoutManager(new TGHorizontalLayout(this)); + } + + // label + TGLayoutHints* lh; + if(fAlignRight) + lh = new TGLayoutHints(kLHintsRight | kLHintsBottom, 4,0,0,0); + else + lh = new TGLayoutHints(kLHintsLeft | kLHintsBottom, 0,4,0,0); + + if(fLabelWidth > 0) { + TGCompositeFrame *lf = new TGHorizontalFrame(hf1, fLabelWidth, fNEHeight, kFixedSize); + fLabel = new TGLabel(lf, fName); + lf->AddFrame(fLabel, lh); + // add label frame to top horizontal frame + TGLayoutHints* lfh = new TGLayoutHints(kLHintsLeft, 0,0,0,0); + hf1->AddFrame(lf, lfh); + } else { + fLabel = new TGLabel(hf1, fName); + hf1->AddFrame(fLabel, lh); + } + + // entries + fMinEntry = new TGNumberEntry(hf1, 0, fNELength); + fMinEntry->SetHeight(fNEHeight); + fMinEntry->GetNumberEntry()->SetToolTipText("Enter Slider Min Value"); + hf1->AddFrame(fMinEntry, new TGLayoutHints(kLHintsLeft, 0,0,0,0)); + if (connect) + fMinEntry->Connect("ValueSet(Long_t)", + "TEveGDoubleValuator", this, "MinEntryCallback()"); + fMinEntry->Associate(this); + + fMaxEntry = new TGNumberEntry(hf1, 0, fNELength); + fMaxEntry->SetHeight(fNEHeight); + fMaxEntry->GetNumberEntry()->SetToolTipText("Enter Slider Max Value"); + hf1->AddFrame(fMaxEntry, new TGLayoutHints(kLHintsLeft, 2,0,0,0)); + if (connect) + fMaxEntry->Connect("ValueSet(Long_t)", + "TEveGDoubleValuator", this, "MaxEntryCallback()"); + fMaxEntry->Associate(this); + + // slider + if(fShowSlider) { + fSlider = new TGDoubleHSlider(hfs, GetWidth(), kDoubleScaleBoth); + hfs->AddFrame(fSlider, new TGLayoutHints(kLHintsTop|kLHintsLeft, 0,0,1,0)); + fSlider->Associate(this); + if (connect) + fSlider->Connect("PositionChanged()", + "TEveGDoubleValuator", this, "SliderCallback()"); + } +} + +//______________________________________________________________________________ +void TEveGDoubleValuator::SetLimits(Int_t min, Int_t max) +{ + fMinEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, min, max); + fMinEntry->SetFormat(TGNumberFormat::kNESInteger); + fMaxEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, min, max); + fMaxEntry->SetFormat(TGNumberFormat::kNESInteger); + + if(fSlider) { + fSlider->SetRange(min, max); + } +} + +//______________________________________________________________________________ +void TEveGDoubleValuator::SetLimits(Float_t min, Float_t max, + TGNumberFormat::EStyle nef) +{ + // printf("TEveGDoubleValuator::SetLimits(Float_t min, Float_t max, Int_ \n"); + fMinEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, min, max); + fMinEntry->SetFormat(nef); + fMaxEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, min, max); + fMaxEntry->SetFormat(nef); + + if(fSlider) fSlider->SetRange(min, max); +} + +//______________________________________________________________________________ +void TEveGDoubleValuator::MinEntryCallback() +{ + if(GetMin() > GetMax()) + fMaxEntry->SetNumber(GetMin()); + if(fSlider) fSlider->SetPosition(GetMin(), GetMax()); + ValueSet(); +} + +//______________________________________________________________________________ +void TEveGDoubleValuator::MaxEntryCallback() +{ + if(GetMax() < GetMin()) + fMinEntry->SetNumber(GetMax()); + if(fSlider) fSlider->SetPosition(GetMin(), GetMax()); + ValueSet(); +} + +//______________________________________________________________________________ +void TEveGDoubleValuator::SliderCallback() +{ + Float_t minp, maxp; + fSlider->GetPosition(minp, maxp); + //printf("TEveGDoubleValuator::SliderCallback %f %f\n", minp, maxp); + fMinEntry->SetNumber(minp); + fMaxEntry->SetNumber(maxp); + ValueSet(); +} + +//______________________________________________________________________________ +void TEveGDoubleValuator::SetValues(Float_t min, Float_t max, Bool_t emit) +{ + fMinEntry->SetNumber(min); + fMaxEntry->SetNumber(max); + + if(fSlider) fSlider->SetPosition(min, max); + if(emit) ValueSet(); +} + +//______________________________________________________________________________ +void TEveGDoubleValuator::ValueSet() +{ + Emit("ValueSet()"); +} + + +/******************************************************************************/ +// TEveGTriVecValuator +/******************************************************************************/ + +//______________________________________________________________________________ +TEveGTriVecValuator::TEveGTriVecValuator(const TGWindow *p, const char* name, + UInt_t w, UInt_t h) : + TGCompositeFrame(p, w, h), + + fLabelWidth (0), + fNELength (5), + fNEHeight (20) +{ + SetName(name); +} + +//______________________________________________________________________________ +TEveGTriVecValuator::~TEveGTriVecValuator() +{} + +//______________________________________________________________________________ +void TEveGTriVecValuator::Build(Bool_t vertical, const char* lab0, const char* lab1, const char* lab2) +{ + if (vertical) SetLayoutManager(new TGVerticalLayout(this)); + else SetLayoutManager(new TGHorizontalLayout(this)); + + const char *labs[3] = { lab0, lab1, lab2 }; + TGLayoutHints* lh; + for (Int_t i=0; i<3; ++i) { + fVal[i] = new TEveGValuator(this, labs[i], 10, 0); + fVal[i]->SetLabelWidth(fLabelWidth); + fVal[i]->SetShowSlider(kFALSE); + fVal[i]->SetNELength(fNELength); + fVal[i]->SetNEHeight(fNEHeight); + fVal[i]->Build(); + fVal[i]->Connect + ("ValueSet(Double_t)", "TEveGTriVecValuator", this, "ValueSet()"); + if (vertical) lh = new TGLayoutHints(kLHintsTop, 1, 1, 1, 1); + else lh = new TGLayoutHints(kLHintsLeft|kLHintsExpandX, 1, 1, 1, 1); + AddFrame(fVal[i], lh); + } +} + +//______________________________________________________________________________ +void TEveGTriVecValuator::ValueSet() +{ + Emit("ValueSet()"); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGTriVecValuator::SetLimits(Int_t min, Int_t max) +{ + for (Int_t i=0; i<3; ++i) + fVal[i]->SetLimits(min, max); +} + +//______________________________________________________________________________ +void TEveGTriVecValuator::SetLimits(Float_t min, Float_t max, + TGNumberFormat::EStyle nef) +{ + for (Int_t i=0; i<3; ++i) + fVal[i]->SetLimits(min, max, 0, nef); +} + + diff --git a/eve/src/TEveGedEditor.cxx b/eve/src/TEveGedEditor.cxx new file mode 100644 index 0000000000..c342439654 --- /dev/null +++ b/eve/src/TEveGedEditor.cxx @@ -0,0 +1,119 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include + +#include +#include +#include + +//______________________________________________________________________________ +// TEveGedEditor +// +// Specialization of TGedEditor for proper update propagation to +// TEveManager. + +ClassImp(TEveGedEditor) + +//______________________________________________________________________________ +TEveGedEditor::TEveGedEditor(TCanvas* canvas, Int_t width, Int_t height) : + TGedEditor(canvas), + fRnrElement(0), + fObject (0) +{ + Resize(width, height); + + // Fix priority for TAttMarkerEditor. + TClass* amClass = TClass::GetClass("TAttMarker"); + TClass* edClass = TClass::GetClass("TAttMarkerEditor"); + TGWindow *exroot = (TGWindow*) fClient->GetRoot(); + fClient->SetRoot(fTabContainer); + SetFrameCreator(this); + TGedFrame *frame = reinterpret_cast(edClass->New()); + frame->SetModelClass(amClass); + { + Int_t off = edClass->GetDataMemberOffset("fPriority"); + if(off == 0) + printf("ojej!\n"); + else + * (Int_t*) (((char*)frame) + off) = 1; + } + SetFrameCreator(0); + fClient->SetRoot(exroot); + fFrameMap.Add(amClass, frame); +} + +//______________________________________________________________________________ +TEveElement* TEveGedEditor::GetRnrElement() const +{ + return (fModel == fObject) ? fRnrElement : 0; +} + +//______________________________________________________________________________ +void TEveGedEditor::DisplayElement(TEveElement* re) +{ + fRnrElement = re; + fObject = fRnrElement ? fRnrElement->GetEditorObject() : 0; + TGedEditor::SetModel(fPad, fObject, kButton1Down); +} + +//______________________________________________________________________________ +void TEveGedEditor::DisplayObject(TObject* obj) +{ + fRnrElement = dynamic_cast(obj); + fObject = obj; + TGedEditor::SetModel(fPad, obj, kButton1Down); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGedEditor::SetModel(TVirtualPad* pad, TObject* obj, Int_t event) +{ + // !!!! do something so that such calls from elswhere will also + // now the render element + + fRnrElement = dynamic_cast(obj); + fObject = obj; + TGedEditor::SetModel(pad, obj, event); +} + +//______________________________________________________________________________ +void TEveGedEditor::Update(TGedFrame* /*gframe*/) +{ + // Virtual method from TGedEditor ... called on every change. + + if (fRnrElement) { + fRnrElement->UpdateItems(); + fRnrElement->ElementChanged(); + } + + gEve->Redraw3D(); +} + +/******************************************************************************/ + +/* +// Attempt to enable mouse-wheel in geditor -- failed. +Bool_t TEveGedEditor::HandleButton(Event_t *event) +{ +// Handle mouse button event in container. + +printf("odfjgsf\n"); +if (event->fCode == kButton4 || event->fCode == kButton5) { +return fCan->GetContainer()->HandleButton(event); +} else { +return TGedEditor::HandleButton(event); +} +} +*/ diff --git a/eve/src/TEveGeoNode.cxx b/eve/src/TEveGeoNode.cxx new file mode 100644 index 0000000000..90a3596919 --- /dev/null +++ b/eve/src/TEveGeoNode.cxx @@ -0,0 +1,580 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +//______________________________________________________________________________ +// TEveGeoNode +// +// Wrapper for TGeoNode that allows it to be shown in GUI and controlled as a TEveElement. + +ClassImp(TEveGeoNode) + +//______________________________________________________________________________ +TEveGeoNode::TEveGeoNode(TGeoNode* node) : + TEveElement(), + TObject(), + fNode(node) +{ + // Constructor. + + // Hack!! Should use cint to retrieve TAttLine::fLineColor offset. + char* l = (char*) dynamic_cast(node->GetVolume()); + SetMainColorPtr((Color_t*)(l + sizeof(void*))); + + fRnrSelf = fNode->TGeoAtt::IsVisible(); +} + +//______________________________________________________________________________ +const Text_t* TEveGeoNode::GetName() const { return fNode->GetName(); } +const Text_t* TEveGeoNode::GetTitle() const { return fNode->GetTitle(); } + +/******************************************************************************/ + +Int_t TEveGeoNode::ExpandIntoListTree(TGListTree* ltree, + TGListTreeItem* parent) +{ + // Checks if child-nodes have been imported ... imports them if not. + // Then calls TEveElement::ExpandIntoListTree. + + if(fChildren.empty() && fNode->GetVolume()->GetNdaughters() > 0) { + TIter next(fNode->GetVolume()->GetNodes()); + TGeoNode* dnode; + while((dnode = (TGeoNode*) next()) != 0) { + TEveGeoNode* node_re = new TEveGeoNode(dnode); + AddElement(node_re); + } + } + return TEveElement::ExpandIntoListTree(ltree, parent); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGeoNode::SetRnrSelf(Bool_t rnr) +{ + TEveElement::SetRnrSelf(rnr); + fNode->SetVisibility(rnr); +} + +//______________________________________________________________________________ +void TEveGeoNode::SetRnrChildren(Bool_t rnr) +{ + TEveElement::SetRnrChildren(rnr); + fNode->VisibleDaughters(rnr); +} + +//______________________________________________________________________________ +void TEveGeoNode::SetRnrState(Bool_t rnr) +{ + TEveElement::SetRnrState(rnr); + fNode->SetVisibility(rnr); + fNode->VisibleDaughters(rnr); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGeoNode::SetMainColor(Color_t color) +{ + fNode->GetVolume()->SetLineColor(color); + UpdateItems(); +} + +//______________________________________________________________________________ +void TEveGeoNode::SetMainColor(Pixel_t pixel) +{ + // This one needed for proper calling via CINT (signals). + + SetMainColor(Color_t(TColor::GetColor(pixel))); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGeoNode::UpdateNode(TGeoNode* node) +{ + // Updates all reve-browsers having the node in their contents. + // All 3D-pads updated if any change found. + // + // Should (could?) be optimized with some assumptions about + // volume/node structure (search for parent, know the same node can not + // reoccur on lower level once found). + + static const TEveException eH("TEveGeoNode::UpdateNode "); + + // printf("%s node %s %p\n", eH.Data(), node->GetName(), node); + + if(fNode == node) + UpdateItems(); + + for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i) { + ((TEveGeoNode*)(*i))->UpdateNode(node); + } + +} + +//______________________________________________________________________________ +void TEveGeoNode::UpdateVolume(TGeoVolume* volume) +{ + // Updates all reve-browsers having the volume in their contents. + // All 3D-pads updated if any change found. + // + // Should (could?) be optimized with some assumptions about + // volume/node structure (search for parent, know the same node can not + // reoccur on lower level once found). + + static const TEveException eH("TEveGeoNode::UpdateVolume "); + + // printf("%s volume %s %p\n", eH.Data(), volume->GetName(), volume); + + if(fNode->GetVolume() == volume) + UpdateItems(); + + for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i) { + ((TEveGeoNode*)(*i))->UpdateVolume(volume); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGeoNode::Draw(Option_t* option) +{ + TString opt("SAME"); + opt += option; + fNode->GetVolume()->Draw(opt); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGeoNode::Save(const char* file, const char* name) +{ + TEveGeoShapeExtract* gse = DumpShapeTree(this, 0, 0); + + TFile f(file, "RECREATE"); + gse->Write(name); + f.Close(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +TEveGeoShapeExtract* TEveGeoNode::DumpShapeTree(TEveGeoNode* geon, TEveGeoShapeExtract* parent, Int_t level) +{ + printf("dump_shape_tree %s \n", geon->GetName()); + TGeoNode* tnode = 0; + TGeoVolume* tvolume = 0; + TGeoShape* tshape = 0; + + tnode = geon->GetNode(); + if(tnode == 0) { + printf("Null node for %s; assuming it's a holder and descending.\n", geon->GetName()); + goto do_dump; + } + + tvolume = tnode->GetVolume(); + if(tvolume == 0) { + printf("Null volume for %s; skipping.\n", geon->GetName()); + return 0; + } + + tshape = tvolume->GetShape(); + +do_dump: + // transformation + TEveTrans trans; + if (parent) if (parent) trans.SetFromArray(parent->GetTrans()); + TGeoMatrix* gm = tnode->GetMatrix(); + const Double_t* rm = gm->GetRotationMatrix(); + const Double_t* tv = gm->GetTranslation(); + TEveTrans t; + t(1,1) = rm[0]; t(1,2) = rm[1]; t(1,3) = rm[2]; + t(2,1) = rm[3]; t(2,2) = rm[4]; t(2,3) = rm[5]; + t(3,1) = rm[6]; t(3,2) = rm[7]; t(3,3) = rm[8]; + t(1,4) = tv[0]; t(2,4) = tv[1]; t(3,4) = tv[2]; + trans *= t; + + TEveGeoShapeExtract* gse = new TEveGeoShapeExtract(geon->GetName(), geon->GetTitle()); + gse->SetTrans(trans.Array()); + Int_t ci = 0; + if(tvolume) ci = tvolume->GetLineColor(); + TColor* c = gROOT->GetColor(ci); + Float_t rgba[4] = {1, 0, 0, 1}; + if (c) { + rgba[0] = c->GetRed(); + rgba[1] = c->GetGreen(); + rgba[2] = c->GetBlue(); + } + gse->SetRGBA(rgba); + Bool_t rnr = geon->GetRnrSelf(); + if(level > gGeoManager->GetVisLevel()) + rnr = kFALSE; + gse->SetRnrSelf(rnr); + gse->SetRnrElements(geon->GetRnrChildren()); + + if(dynamic_cast(tshape)){ + // printf("SetShape(tshape); + level ++; + if ( geon->GetNChildren()) + { + TList* ele = new TList(); + gse->SetElements(ele); + gse->GetElements()->SetOwner(true); + + TEveElement::List_i i = geon->BeginChildren(); + while (i != geon->EndChildren()) { + TEveGeoNode* l = dynamic_cast(*i); + DumpShapeTree(l, gse, level+1); + i++; + } + } + + if(parent) + parent->GetElements()->Add(gse); + + return gse; +} + + +//______________________________________________________________________________ +// TEveGeoTopNode +// +// A wrapper over a TGeoNode, possibly displaced with a global +// trasformation fGlobalTrans (the matrix is owned by this class). +// +// It holds a pointer to TGeoManager and controls for steering of +// TGeoPainter. + +ClassImp(TEveGeoTopNode) + +//______________________________________________________________________________ +TEveGeoTopNode::TEveGeoTopNode(TGeoManager* manager, TGeoNode* node, + Int_t visopt, Int_t vislvl) : + TEveGeoNode (node), + fManager (manager), + fGlobalTrans (), + fVisOption (visopt), + fVisLevel (vislvl) +{ + fRnrSelf = true; +} + +//______________________________________________________________________________ +TEveGeoTopNode::~TEveGeoTopNode() +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGeoTopNode::SetGlobalTrans(const TGeoHMatrix* m) +{ + fGlobalTrans.SetFrom(*m); +} + +//______________________________________________________________________________ +void TEveGeoTopNode::UseNodeTrans() +{ + fGlobalTrans.SetFrom(*fNode->GetMatrix()); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGeoTopNode::SetVisOption(Int_t visopt) +{ + fVisOption = visopt; + gEve->Redraw3D(); +} + +//______________________________________________________________________________ +void TEveGeoTopNode::SetVisLevel(Int_t vislvl) +{ + fVisLevel = vislvl; + gEve->Redraw3D(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGeoTopNode::SetRnrSelf(Bool_t rnr) +{ + // Revert from GeoNode to back to standard behaviour. + TEveElement::SetRnrSelf(rnr); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGeoTopNode::Draw(Option_t* option) +{ + AppendPad(option); +} + +//______________________________________________________________________________ +void TEveGeoTopNode::Paint(Option_t* option) +{ + if(fRnrSelf) { + gGeoManager = fManager; + TVirtualPad* pad = gPad; + gPad = 0; + TGeoVolume* top_volume = fManager->GetTopVolume(); + fManager->SetVisOption(fVisOption); + fManager->SetVisLevel(fVisLevel); + fManager->SetTopVolume(fNode->GetVolume()); + gPad = pad; + TVirtualGeoPainter* vgp = fManager->GetGeomPainter(); + if(vgp != 0) { + TGeoHMatrix geomat; + fGlobalTrans.SetGeoHMatrix(geomat); + vgp->PaintNode(fNode, option, &geomat); + } + fManager->SetTopVolume(top_volume); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGeoTopNode::VolumeVisChanged(TGeoVolume* volume) +{ + static const TEveException eH("TEveGeoTopNode::VolumeVisChanged "); + printf("%s volume %s %p\n", eH.Data(), volume->GetName(), (void*)volume); + UpdateVolume(volume); +} + +//______________________________________________________________________________ +void TEveGeoTopNode::VolumeColChanged(TGeoVolume* volume) +{ + static const TEveException eH("TEveGeoTopNode::VolumeColChanged "); + printf("%s volume %s %p\n", eH.Data(), volume->GetName(), (void*)volume); + UpdateVolume(volume); +} + +//______________________________________________________________________________ +void TEveGeoTopNode::NodeVisChanged(TGeoNode* node) +{ + static const TEveException eH("TEveGeoTopNode::NodeVisChanged "); + printf("%s node %s %p\n", eH.Data(), node->GetName(), (void*)node); + UpdateNode(node); +} + + +//______________________________________________________________________________ +// TEveGeoShape +// +// Wrapper for TGeoShape with absolute positioning and color +// attributes allowing display of extracted TGeoShape's (without an +// active TGeoManager) and simplified geometries (needed for NLT +// projections). + +ClassImp(TEveGeoShape) + +//______________________________________________________________________________ +TEveGeoShape::TEveGeoShape(const Text_t* name, const Text_t* title) : + TEveElement(), + TNamed (name, title), + fHMTrans (), + fColor (0), + fTransparency (0), + fShape (0) +{ + fMainColorPtr = &fColor; +} + +//______________________________________________________________________________ +TEveGeoShape::~TEveGeoShape() +{ + if (fShape) { + fShape->SetUniqueID(fShape->GetUniqueID() - 1); + if (fShape->GetUniqueID() == 0) + delete fShape; + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGeoShape::Paint(Option_t* /*option*/) +{ + if (fShape == 0) + return; + + TBuffer3D& buff = (TBuffer3D&) fShape->GetBuffer3D + (TBuffer3D::kCore, false); + + buff.fID = this; + buff.fColor = fColor; + buff.fTransparency = fTransparency; + fHMTrans.SetBuffer3D(buff); + buff.fLocalFrame = kTRUE; // Always enforce local frame (no geo manager). + + fShape->GetBuffer3D(TBuffer3D::kBoundingBox | TBuffer3D::kShapeSpecific, true); + + Int_t reqSec = gPad->GetViewer3D()->AddObject(buff); + + if (reqSec != TBuffer3D::kNone) { + fShape->GetBuffer3D(reqSec, true); + reqSec = gPad->GetViewer3D()->AddObject(buff); + } + + if (reqSec != TBuffer3D::kNone) + printf("spooky reqSec=%d for %s\n", reqSec, GetName()); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGeoShape::Save(const char* file, const char* name) +{ + TEveGeoShapeExtract* gse = DumpShapeTree(this, 0); + + TFile f(file, "RECREATE"); + gse->Write(name); + f.Close(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +TEveGeoShapeExtract* TEveGeoShape::DumpShapeTree(TEveGeoShape* gsre, TEveGeoShapeExtract* parent) +{ + // printf("dump_shape_tree %s \n", gsre->GetName()); + TEveGeoShapeExtract* she = new TEveGeoShapeExtract(gsre->GetName(), gsre->GetTitle()); + she->SetTrans(gsre->RefHMTrans().Array()); + Int_t ci = gsre->GetColor(); + TColor* c = gROOT->GetColor(ci); + Float_t rgba[4] = {1, 0, 0, 1 - gsre->GetMainTransparency()/100.}; + if (c) + { + rgba[0] = c->GetRed(); + rgba[1] = c->GetGreen(); + rgba[2] = c->GetBlue(); + } + she->SetRGBA(rgba); + she->SetRnrSelf(gsre->GetRnrSelf()); + she->SetRnrElements(gsre->GetRnrChildren()); + she->SetShape(gsre->GetShape()); + if ( gsre->GetNChildren()) + { + TList* ele = new TList(); + she->SetElements(ele); + she->GetElements()->SetOwner(true); + TEveElement::List_i i = gsre->BeginChildren(); + while (i != gsre->EndChildren()) { + TEveGeoShape* l = dynamic_cast(*i); + DumpShapeTree(l, she); + i++; + } + } + if(parent) + parent->GetElements()->Add(she); + + return she; +} + +//______________________________________________________________________________ +TEveGeoShape* TEveGeoShape::ImportShapeExtract(TEveGeoShapeExtract * gse, + TEveElement * parent) +{ + gEve->DisableRedraw(); + TEveGeoShape* gsre = SubImportShapeExtract(gse, parent); + gsre->ElementChanged(); + gEve->EnableRedraw(); + return gsre; +} + + +//______________________________________________________________________________ +TEveGeoShape* TEveGeoShape::SubImportShapeExtract(TEveGeoShapeExtract * gse, + TEveElement * parent) +{ + TEveGeoShape* gsre = new TEveGeoShape(gse->GetName(), gse->GetTitle()); + gsre->fHMTrans.SetFromArray(gse->GetTrans()); + const Float_t* rgba = gse->GetRGBA(); + gsre->fColor = TColor::GetColor(rgba[0], rgba[1], rgba[2]); + gsre->fTransparency = (UChar_t) (100.0f*(1.0f - rgba[3])); + gsre->SetRnrSelf(gse->GetRnrSelf()); + gsre->SetRnrChildren(gse->GetRnrElements()); + gsre->fShape = gse->GetShape(); + if (gsre->fShape) + gsre->fShape->SetUniqueID(gsre->fShape->GetUniqueID() + 1); + + gEve->AddGlobalElement(gsre, parent); + + if (gse->HasElements()) + { + TIter next(gse->GetElements()); + TEveGeoShapeExtract* chld; + while ((chld = (TEveGeoShapeExtract*) next()) != 0) + SubImportShapeExtract(chld, gsre); + } + + return gsre; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +TClass* TEveGeoShape::ProjectedClass() const +{ + return TEvePolygonSetProjected::Class(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +TBuffer3D* TEveGeoShape::MakeBuffer3D() +{ + if(fShape == 0) return 0; + + if(dynamic_cast(fShape)){ + // !!!! TGeoShapeAssembly makes a bad TBuffer3D + return 0; + } + + TBuffer3D* buff = fShape->MakeBuffer3D(); + if (fHMTrans.GetUseTrans()) + { + TEveTrans& mx = RefHMTrans(); + Int_t N = buff->NbPnts(); + Double_t* pnts = buff->fPnts; + for(Int_t k=0; k +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +//______________________________________________________________________________ +// TEveGeoNodeEditor +// +// Editor for TEveGeoNode class. + +ClassImp(TEveGeoNodeEditor) + +//______________________________________________________________________________ +TEveGeoNodeEditor::TEveGeoNodeEditor(const TGWindow *p, + Int_t width, Int_t height, + UInt_t options, Pixel_t back) : + TGedFrame(p,width, height, options | kVerticalFrame, back), + + fNodeRE (0), + + fVizNode(0), + fVizNodeDaughters(0), + fVizVolume(0), + fVizVolumeDaughters(0), + + fTransparency(0) +{ + MakeTitle("GeoNode"); + + // --- Visibility control + + fVizNode = new TGCheckButton(this, "VizNode"); + AddFrame(fVizNode, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0)); + fVizNode->Connect + ("Toggled(Bool_t)", + "TEveGeoNodeEditor", this, "DoVizNode()"); + + fVizNodeDaughters = new TGCheckButton(this, "VizNodeDaughters"); + AddFrame(fVizNodeDaughters, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0)); + fVizNodeDaughters->Connect + ("Toggled(Bool_t)", + "TEveGeoNodeEditor", this, "DoVizNodeDaughters()"); + + fVizVolume = new TGCheckButton(this, "VizVolume"); + AddFrame(fVizVolume, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0)); + fVizVolume->Connect + ("Toggled(Bool_t)", + "TEveGeoNodeEditor", this, "DoVizVolume()"); + + fVizVolumeDaughters = new TGCheckButton(this, "VizVolumeDaughters"); + AddFrame(fVizVolumeDaughters, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0)); + fVizVolumeDaughters->Connect + ("Toggled(Bool_t)", + "TEveGeoNodeEditor", this, "DoVizVolumeDaughters()"); + + + // --- Color props + + { + TGHorizontalFrame* f = new TGHorizontalFrame(this); + TGLabel *l = new TGLabel(f, "Transparency:"); + f->AddFrame(l, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 1, 2, 1, 1)); + fTransparency = new TGNumberEntry(f, 0., 6, -1, + TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, + TGNumberFormat::kNELLimitMinMax, 0, 100); + fTransparency->GetNumberEntry()->SetToolTipText("0 is opaque, 100 fully transparent."); + f->AddFrame(fTransparency, new TGLayoutHints(kLHintsLeft, 1, 1, 1, 1)); + fTransparency->Connect("ValueSet(Long_t)", + "TEveGeoNodeEditor", this, "DoTransparency()"); + AddFrame(f, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1)); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGeoNodeEditor::SetModel(TObject* obj) +{ + fNodeRE = dynamic_cast(obj); + TGeoNode* node = fNodeRE->fNode; + TGeoVolume* vol = node->GetVolume(); + + fVizNode->SetState(node->TGeoAtt::IsVisible() ? kButtonDown : kButtonUp); + fVizNodeDaughters->SetState(node->TGeoAtt::IsVisDaughters() ? kButtonDown : kButtonUp); + fVizVolume->SetState(vol->IsVisible() ? kButtonDown : kButtonUp); + fVizVolumeDaughters->SetState(vol->IsVisDaughters() ? kButtonDown : kButtonUp); + + fTransparency->SetNumber(vol->GetTransparency()); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGeoNodeEditor::DoVizNode() +{ + fNodeRE->SetRnrSelf(fVizNode->IsOn()); + Update(); +} + +//______________________________________________________________________________ +void TEveGeoNodeEditor::DoVizNodeDaughters() +{ + fNodeRE->SetRnrChildren(fVizNodeDaughters->IsOn()); + Update(); +} + +//______________________________________________________________________________ +void TEveGeoNodeEditor::DoVizVolume() +{ + fNodeRE->fNode->GetVolume()->SetVisibility(fVizVolume->IsOn()); + Update(); +} + +//______________________________________________________________________________ +void TEveGeoNodeEditor::DoVizVolumeDaughters() +{ + fNodeRE->fNode->GetVolume()->VisibleDaughters(fVizVolumeDaughters->IsOn()); + Update(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGeoNodeEditor::DoTransparency() +{ + fNodeRE->fNode->GetVolume()->SetTransparency(char(fTransparency->GetNumber())); + Update(); +} + + +//______________________________________________________________________________ +// TEveGeoTopNodeEditor +// +// Editor for TEveGeoTopNode class. + +ClassImp(TEveGeoTopNodeEditor) + +//______________________________________________________________________________ +TEveGeoTopNodeEditor::TEveGeoTopNodeEditor(const TGWindow *p, + Int_t width, Int_t height, + UInt_t options, Pixel_t back) : + TGedFrame(p, width, height, options | kVerticalFrame, back), + + fTopNodeRE (0), + fVisOption (0), + fVisLevel (0) +{ + MakeTitle("GeoTopNode"); + + Int_t labelW = 58; + + fVisOption = new TEveGValuator(this, "VisOption:", 90, 0); + fVisOption->SetLabelWidth(labelW); + fVisOption->SetShowSlider(kFALSE); + fVisOption->SetNELength(4); + fVisOption->Build(); + fVisOption->SetLimits(0, 2, 10, TGNumberFormat::kNESInteger); + fVisOption->SetToolTip("Visualization option passed to TGeoPainter."); + fVisOption->Connect("ValueSet(Double_t)", "TEveGeoTopNodeEditor", this, "DoVisOption()"); + AddFrame(fVisOption, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1)); + + fVisLevel = new TEveGValuator(this, "VisLevel:", 90, 0); + fVisLevel->SetLabelWidth(labelW); + fVisLevel->SetShowSlider(kFALSE); + fVisLevel->SetNELength(4); + fVisLevel->Build(); + fVisLevel->SetLimits(0, 10, 10, TGNumberFormat::kNESInteger); + fVisLevel->SetToolTip("Level (depth) to which the geometry is traversed."); + fVisLevel->Connect("ValueSet(Double_t)", "TEveGeoTopNodeEditor", this, "DoVisLevel()"); + AddFrame(fVisLevel, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1)); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGeoTopNodeEditor::SetModel(TObject* obj) +{ + fTopNodeRE = dynamic_cast(obj); + + fVisOption->SetValue(fTopNodeRE->GetVisOption()); + fVisLevel ->SetValue(fTopNodeRE->GetVisLevel()); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGeoTopNodeEditor::DoVisOption() +{ + fTopNodeRE->SetVisOption(Int_t(fVisOption->GetValue())); + Update(); +} + +//______________________________________________________________________________ +void TEveGeoTopNodeEditor::DoVisLevel() +{ + fTopNodeRE->SetVisLevel(Int_t(fVisLevel->GetValue())); + Update(); +} diff --git a/eve/src/TEveGeoShapeExtract.cxx b/eve/src/TEveGeoShapeExtract.cxx new file mode 100644 index 0000000000..e11b77b9cd --- /dev/null +++ b/eve/src/TEveGeoShapeExtract.cxx @@ -0,0 +1,80 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 + +#include +#include + +//______________________________________________________________________________ +// TEveGeoShapeExtract +// +// Globally positioned TGeoShape with rendering attributes and an +// optional list of daughter shape-extracts. +// +// Vessel to carry hand-picked geometry from gled to reve. +// This class exists in both frameworks. + +ClassImp(TEveGeoShapeExtract) + +//______________________________________________________________________________ +TEveGeoShapeExtract::TEveGeoShapeExtract(const Text_t* n, const Text_t* t) : + TNamed (n,t), + + mRnrSelf (true), + mRnrElements (true), + mShape (0), + mElements (0) +{ + memset(mTrans, 0, sizeof(mTrans)); + mTrans[0] = mTrans[5] = mTrans[10] = mTrans[15] = 1; + mRGBA [0] = mRGBA [1] = mRGBA [2] = mRGBA [3] = 1; +} + +//______________________________________________________________________________ +TEveGeoShapeExtract::~TEveGeoShapeExtract() +{ + delete mShape; + delete mElements; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +Bool_t TEveGeoShapeExtract::HasElements() +{ + return mElements != 0 && mElements->GetSize() > 0; +} + +//______________________________________________________________________________ +void TEveGeoShapeExtract::AddElement(TEveGeoShapeExtract* gse) +{ + if (mElements == 0) + mElements = new TList; + + mElements->Add(gse); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGeoShapeExtract::SetTrans(const Double_t arr[16]) +{ + for(Int_t i=0; i<16; ++i) + mTrans[i] = arr[i]; +} + +//______________________________________________________________________________ +void TEveGeoShapeExtract::SetRGBA (const Float_t arr[4]) +{ + for(Int_t i=0; i<4; ++i) + mRGBA[i] = arr[i]; +} diff --git a/eve/src/TEveGridStepper.cxx b/eve/src/TEveGridStepper.cxx new file mode 100644 index 0000000000..9bb0d54e51 --- /dev/null +++ b/eve/src/TEveGridStepper.cxx @@ -0,0 +1,101 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include + +//______________________________________________________________________________ +// TEveGridStepper +// +// Provide discrete position coordinates for placement of objects on +// regular grids. + +ClassImp(TEveGridStepper) + +//______________________________________________________________________________ +TEveGridStepper::TEveGridStepper(Int_t sm) : + Mode(StepMode_e(sm)), + nx(0), ny(0), nz(0), Nx(0), Ny(0), Nz(0), + Dx(0), Dy(0), Dz(0), Ox(0), Oy(0), Oz(0) +{ + switch(Mode) { + default: + case SM_XYZ: + ls[0] = &Nx; ls[1] = &Ny; ls[2] = &Nz; + ns[0] = &nx; ns[1] = &ny; ns[2] = &nz; + break; + case SM_YXZ: + ls[0] = &Ny; ls[1] = &Nx; ls[2] = &Nz; + ns[0] = &ny; ns[1] = &nx; ns[2] = &nz; + break; + case SM_XZY: + ls[0] = &Nx; ls[1] = &Nz; ls[2] = &Ny; + ns[0] = &nx; ns[1] = &nz; ns[2] = &ny; + break; + } + + nx = ny = nz = 0; + Nx = Ny = Nz = 16; + Dx = Dy = Dz = 1; + Ox = Oy = Oz = 0; +} + +//______________________________________________________________________________ +void TEveGridStepper::Reset() +{ + nx = ny = nz = 0; +} + +//______________________________________________________________________________ +void TEveGridStepper::Subtract(TEveGridStepper& s) +{ + Ox = -(s.Ox + s.nx*s.Dx); + Oy = -(s.Oy + s.ny*s.Dy); + Oz = -(s.Oz + s.nz*s.Dz); +} +/******************************************************************************/ + +//______________________________________________________________________________ +Bool_t TEveGridStepper::Step() +{ + (*ns[0])++; + if (*ns[0] >= *ls[0]) { + *ns[0] = 0; (*ns[1])++; + if (*ns[1] >= *ls[1]) { + *ns[1] = 0; (*ns[2])++; + if (*ns[2] >= *ls[2]) { + return kFALSE; + } + } + } + return kTRUE; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGridStepper::GetPosition(Float_t* p) +{ + p[0] = Ox + nx*Dx; p[1] = Oy + ny*Dy; p[2] = Oz + nz*Dz; +} + +//______________________________________________________________________________ +void TEveGridStepper::SetTrans(TEveTrans* mx) +{ + mx->SetPos(Ox + nx*Dx, Oy + ny*Dy, Oz + nz*Dz); +} + +//______________________________________________________________________________ +void TEveGridStepper::SetTransAdvance(TEveTrans* mx) +{ + SetTrans(mx); + Step(); +} diff --git a/eve/src/TEveGridStepperEditor.cxx b/eve/src/TEveGridStepperEditor.cxx new file mode 100644 index 0000000000..77206fce5d --- /dev/null +++ b/eve/src/TEveGridStepperEditor.cxx @@ -0,0 +1,193 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include + +#include +#include + +#include +#include +#include +#include + +//______________________________________________________________________________ +// TEveGridStepperSubEditor +// +// Sub-editor for TEveGridStepper class. + +ClassImp(TEveGridStepperSubEditor) + +//______________________________________________________________________________ +TEveGridStepperSubEditor::TEveGridStepperSubEditor(const TGWindow *p) : + TGVerticalFrame(p), + fM (0), + + fNx (0), + fNy (0), + fNz (0), + fDx (0), + fDy (0), + fDz (0) +{ + Int_t labelW = 15; + + TGHorizontalFrame* VF = new TGHorizontalFrame(this); + + { + TGGroupFrame* f = new TGGroupFrame(VF, "NumRows", kVerticalFrame); + f->SetWidth(30); + VF->AddFrame(f, new TGLayoutHints(kLHintsTop, 1, 1, 1, 0)); + + fNx = new TEveGValuator(f,"X:", 200, 0); + fNx->SetNELength(3); + fNx->SetLabelWidth(labelW); + fNx->SetShowSlider(kFALSE); + fNx->Build(); + fNx->SetLimits(1, 15); + fNx->Connect("ValueSet(Double_t)", + "TEveGridStepperSubEditor", this, "DoNs()"); + f->AddFrame(fNx, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1)); + + fNy = new TEveGValuator(f,"Y:", 200, 0); + fNy->SetNELength(3); + fNy->SetLabelWidth(labelW); + fNy->SetShowSlider(kFALSE); + fNy->Build(); + fNy->SetLimits(1, 15); + fNy->Connect("ValueSet(Double_t)", + "TEveGridStepperSubEditor", this, "DoNs()"); + f->AddFrame(fNy, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1)); + + fNz = new TEveGValuator(f,"Z:", 200, 0); + fNz->SetNELength(3); + fNz->SetLabelWidth(labelW); + fNz->SetShowSlider(kFALSE); + fNz->Build(); + fNz->SetLimits(1, 15); + fNz->Connect("ValueSet(Double_t)", + "TEveGridStepperSubEditor", this, "DoNs()"); + f->AddFrame(fNz, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1)); + + //AddFrame(f, new TGLayoutHints(kLHintsExpandX, 2, 0, 0, 0)); + } + { + TGGroupFrame* f = new TGGroupFrame(VF, "Step", kVerticalFrame); + f->SetWidth(130); + VF->AddFrame(f, new TGLayoutHints(kLHintsTop, 1, 1, 1, 0)); + + fDx = new TEveGValuator(f,"X:", 200, 0); + fDx->SetNELength(5); + fDx->SetLabelWidth(labelW); + fDx->SetShowSlider(kFALSE); + fDx->Build(); + fDx->SetLimits(0.1, 100, 101, TGNumberFormat::kNESRealOne); + fDx->Connect("ValueSet(Double_t)", + "TEveGridStepperSubEditor", this, "DoDs()"); + f->AddFrame(fDx, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1)); + + fDy = new TEveGValuator(f,"Y:", 200, 0); + fDy->SetNELength(5); + fDy->SetLabelWidth(labelW); + fDy->SetShowSlider(kFALSE); + fDy->Build(); + fDy->SetLimits(0.1, 100, 101, TGNumberFormat::kNESRealOne); + fDy->Connect("ValueSet(Double_t)", + "TEveGridStepperSubEditor", this, "DoDs()"); + f->AddFrame(fDy, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1)); + + fDz = new TEveGValuator(f,"Z:", 200, 0); + fDz->SetNELength(5); + fDz->SetLabelWidth(labelW); + fDz->SetShowSlider(kFALSE); + fDz->Build(); + fDz->SetLimits(0.1, 100, 101, TGNumberFormat::kNESRealOne); + fDz->Connect("ValueSet(Double_t)", + "TEveGridStepperSubEditor", this, "DoDs()"); + f->AddFrame(fDz, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1)); + + //AddFrame(f, new TGLayoutHints(kLHintsExpandX, 2, 0, 0, 0)); + } + AddFrame(VF, new TGLayoutHints(kLHintsExpandX, 2, 0, 0, 0)); +} + +//______________________________________________________________________________ +void TEveGridStepperSubEditor::SetModel(TEveGridStepper* m) +{ + // Set model object. + fM = m; + + fNx->SetValue(m->Nx); + fNy->SetValue(m->Ny); + fNz->SetValue(m->Nz); + + fDx->SetValue(m->Dx); + fDy->SetValue(m->Dy); + fDz->SetValue(m->Dz); +} + +//______________________________________________________________________________ +void TEveGridStepperSubEditor::Changed() +{ + // Emit Changed signal. + + Emit("Changed()"); +} + +//______________________________________________________________________________ +void TEveGridStepperSubEditor::DoNs() +{ + fM->SetNs((Int_t)fNx->GetValue(), (Int_t)fNy->GetValue(), (Int_t)fNz->GetValue()); + Changed(); +} + +//______________________________________________________________________________ +void TEveGridStepperSubEditor::DoDs() +{ + // Set some value from some widget + fM->SetDs(fDx->GetValue(), fDy->GetValue(), fDz->GetValue()); + Changed(); +} + +//______________________________________________________________________________ +// TEveGridStepperEditor +// +// Editor for TEveGridStepper class. + +ClassImp(TEveGridStepperEditor) + +//______________________________________________________________________________ +TEveGridStepperEditor::TEveGridStepperEditor(const TGWindow *p, Int_t width, Int_t height, + UInt_t options, Pixel_t back) : + TGedFrame(p, width, height, options | kVerticalFrame, back), + fM (0), + fSE (0) +{ + // Constructor. + + MakeTitle("TEveGridStepper"); + + fSE = new TEveGridStepperSubEditor(this); + AddFrame(fSE, new TGLayoutHints(kLHintsTop, 2, 0, 2, 2)); + fSE->Connect("Changed()", "TEveGridStepperEditor", this, "Update()"); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveGridStepperEditor::SetModel(TObject* obj) +{ + // Set model object. + fM = dynamic_cast(obj); + fSE->SetModel(fM); +} diff --git a/eve/src/TEveLine.cxx b/eve/src/TEveLine.cxx new file mode 100644 index 0000000000..bcd8a25918 --- /dev/null +++ b/eve/src/TEveLine.cxx @@ -0,0 +1,41 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 + +//______________________________________________________________________________ +// TEveLine +// +// An arbitrary polyline with fixed line and marker attributes. + +ClassImp(TEveLine) + +//______________________________________________________________________________ +TEveLine::TEveLine(Int_t n_points, TreeVarType_e tv_type) : + TEvePointSet(n_points, tv_type), + fRnrLine (kTRUE), + fRnrPoints (kFALSE) +{ + fMainColorPtr = &fLineColor; +} + +//______________________________________________________________________________ +TEveLine::TEveLine(const Text_t* name, Int_t n_points, TreeVarType_e tv_type) : + TEvePointSet(name, n_points, tv_type), + fRnrLine (kTRUE), + fRnrPoints (kFALSE) +{ + fMainColorPtr = &fLineColor; +} + +//______________________________________________________________________________ +TEveLine::~TEveLine() +{} diff --git a/eve/src/TEveLineEditor.cxx b/eve/src/TEveLineEditor.cxx new file mode 100644 index 0000000000..87c7897c2f --- /dev/null +++ b/eve/src/TEveLineEditor.cxx @@ -0,0 +1,84 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include + +#include +#include + +#include +#include +#include +#include +#include + +//______________________________________________________________________________ +// TEveLineEditor +// +// Editor for TEveLine class. + +ClassImp(TEveLineEditor) + +//______________________________________________________________________________ +TEveLineEditor::TEveLineEditor(const TGWindow *p, Int_t width, Int_t height, + UInt_t options, Pixel_t back) : + TGedFrame(p, width, height, options | kVerticalFrame, back), + fM(0), + fRnrLine (0), + fRnrPoints (0) +{ + fPriority = 20; + { + TGHorizontalFrame* f = new TGHorizontalFrame(this); + + fRnrPoints = new TGCheckButton(f, "Draw Marker"); + f->AddFrame(fRnrPoints, new TGLayoutHints(kLHintsLeft, 2,1,0,0)); + fRnrPoints->Connect("Toggled(Bool_t)"," TEveLineEditor", this, "DoRnrPoints()"); + + fRnrLine = new TGCheckButton(f, "Draw TEveLine"); + f->AddFrame(fRnrLine, new TGLayoutHints(kLHintsLeft, 1,2,0,0)); + fRnrLine->Connect("Toggled(Bool_t)", "TEveLineEditor", this, "DoRnrLine()"); + + AddFrame(f, new TGLayoutHints(kLHintsTop, 0,0,2,1)); + } +} + +//______________________________________________________________________________ +TEveLineEditor::~TEveLineEditor() +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveLineEditor::SetModel(TObject* obj) +{ + fM = dynamic_cast(obj); + + fRnrLine ->SetState(fM->fRnrLine ? kButtonDown : kButtonUp); + fRnrPoints->SetState(fM->fRnrPoints ? kButtonDown : kButtonUp); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveLineEditor::DoRnrLine() +{ + fM->SetRnrLine(fRnrLine->IsOn()); + Update(); +} + +//______________________________________________________________________________ +void TEveLineEditor::DoRnrPoints() +{ + fM->SetRnrPoints(fRnrPoints->IsOn()); + Update(); +} diff --git a/eve/src/TEveLineGL.cxx b/eve/src/TEveLineGL.cxx new file mode 100644 index 0000000000..c4d636b66a --- /dev/null +++ b/eve/src/TEveLineGL.cxx @@ -0,0 +1,71 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include + +#include +#include +#include + +//______________________________________________________________________________ +// TEveLineGL +// +// GL-renderer for TEveLine class. + +ClassImp(TEveLineGL) + +//______________________________________________________________________________ +TEveLineGL::TEveLineGL() : TPointSet3DGL(), fM(0) +{ + // Constructor. + + // fDLCache = false; // Disable display list. +} + +//______________________________________________________________________________ +TEveLineGL::~TEveLineGL() +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +Bool_t TEveLineGL::SetModel(TObject* obj, const Option_t* /*opt*/) +{ + // TPointSet3DGL::SetModel(obj); + if(SetModelCheckClass(obj, TEveLine::Class())) { + fM = dynamic_cast(obj); + return kTRUE; + } + return kFALSE; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveLineGL::DirectDraw(TGLRnrCtx & rnrCtx) const +{ + // Direct GL rendering for TEveLine. + + // printf("TEveLineGL::DirectDraw Style %d, LOD %d\n", rnrCtx.Style(), rnrCtx.LOD()); + + if (rnrCtx.DrawPass() == TGLRnrCtx::kPassOutlineLine) + return; + + TEveLine& q = *fM; + if (q.Size() <= 0) return; + + if (q.fRnrLine) + TEveGLUtil::RenderLine(q, q.GetP(), q.Size()); + + if (q.fRnrPoints) + TEveGLUtil::RenderPolyMarkers(q, q.GetP(), q.Size()); +} diff --git a/eve/src/TEveMacro.cxx b/eve/src/TEveMacro.cxx new file mode 100644 index 0000000000..3f651151a3 --- /dev/null +++ b/eve/src/TEveMacro.cxx @@ -0,0 +1,112 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 + +#include +#include +#include + +//______________________________________________________________________________ +// TEveMacro +// +// Sub-class of TMacro, overriding Exec to unload the previous verison +// and cleanup after the execution. + +ClassImp(TEveMacro) + +//______________________________________________________________________________ +TEveMacro::TEveMacro() : TMacro() {} + +TEveMacro::TEveMacro(const TEveMacro& m) : TMacro(m) {} + +TEveMacro::TEveMacro(const char* name) : + TMacro() +{ + if (!name) return; + + fTitle = name; + + char *dot = (char*)strrchr(name, '.'); + char *slash = (char*)strrchr(name, '/'); + if (dot) *dot = 0; + if (slash) fName = slash + 1; + else fName = name; + + ReadFile(fTitle); +} + +/******************************************************************************/ + +#include + +//______________________________________________________________________________ +Long_t TEveMacro::Exec(const char* params, Int_t* error) +{ + Long_t retval = -1; + + if (gROOT->GetGlobalFunction(fName, 0, kTRUE) != 0) + { + gROOT->SetExecutingMacro(kTRUE); + gROOT->SetExecutingMacro(kFALSE); + retval = gROOT->ProcessLine(Form("%s()", fName.Data()), error); + } + else + { + // Copy from TMacro::Exec. Difference is that the file is really placed + // into the /tmp. + TString fname = "/tmp/"; + { + //the current implementation uses a file in the current directory. + //should be replaced by a direct execution from memory by CINT + fname += GetName(); + fname += ".C"; + SaveSource(fname); + //disable a possible call to gROOT->Reset from the executed script + gROOT->SetExecutingMacro(kTRUE); + //execute script in /tmp + TString exec = ".x " + fname; + TString p = params; + if (p == "") p = fParams; + if (p != "") + exec += "(" + p + ")"; + retval = gROOT->ProcessLine(exec, error); + //enable gROOT->Reset + gROOT->SetExecutingMacro(kFALSE); + //delete the temporary file + gSystem->Unlink(fname); + } + } + + //G__unloadfile(fname); + + // In case an exception was thrown (which i do not know how to detect + // the execution of next macros does not succeed. + // However strange this might seem, this solves the problem. + // TTimer::SingleShot(100, "TEveMacro", this, "ResetRoot()"); + // + // 27.8.07 - ok, this does not work any more. Seems I'll have to fix + // this real soon now. + // + // !!!! FIX MACRO HANDLING !!!! + // + + return retval; +} + +#include + +//______________________________________________________________________________ +void TEveMacro::ResetRoot() +{ + // printf ("TEveMacro::ResetRoot doing 'gROOT->Reset()'.\n"); + gROOT->GetApplication()->ProcessLine("gROOT->Reset()"); +} diff --git a/eve/src/TEveManager.cxx b/eve/src/TEveManager.cxx new file mode 100644 index 0000000000..1165d3642b --- /dev/null +++ b/eve/src/TEveManager.cxx @@ -0,0 +1,534 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "TVirtualGL.h" +#include "TPluginManager.h" + +#include + +TEveManager* gEve = 0; + +//______________________________________________________________________________ +// TEveManager +// +// Central aplicat manager for Reve. +// Manages elements, GUI, GL scenes and GL viewers. + +ClassImp(TEveManager) + +//______________________________________________________________________________ +TEveManager::TEveManager(UInt_t w, UInt_t h) : + fBrowser (0), + fEditor (0), + fStatusBar (0), + + fMacroFolder (0), + + fViewers (0), + fScenes (0), + fViewer (0), + fGlobalScene (0), + fEventScene (0), + fCurrentEvent (0), + + fRedrawDisabled (0), + fResetCameras (kFALSE), + fDropLogicals (kFALSE), + fKeepEmptyCont (kFALSE), + fTimerActive (kFALSE), + fRedrawTimer (), + + fGeometries () +{ + // Constructor. + + static const TEveException eH("TEveManager::TEveManager "); + + if (gEve != 0) + throw(eH + "There can be only one!"); + + gEve = this; + + fRedrawTimer.Connect("Timeout()", "TEveManager", this, "DoRedraw3D()"); + fMacroFolder = new TFolder("EVE", "Visualization macros"); + gROOT->GetListOfBrowsables()->Add(fMacroFolder); + + + // Build GUI + fBrowser = new TEveBrowser(w, h); + fStatusBar = fBrowser->GetStatusBar(); + + // ListTreeEditor + fBrowser->StartEmbedding(0); + fLTEFrame = new TEveGListTreeEditorFrame("REVE"); + fBrowser->StopEmbedding(); + fBrowser->SetTabTitle("TEveUtil", 0); + fEditor = fLTEFrame->fEditor; + + // GL viewer + fBrowser->StartEmbedding(1); + TGLSAViewer* glv = new TGLSAViewer(gClient->GetRoot(), 0, fEditor); + //glv->GetFrame()->SetCleanup(kNoCleanup); + glv->ToggleEditObject(); + fBrowser->StopEmbedding(); + fBrowser->SetTabTitle("GLViewer", 1); + + // Finalize it + fBrowser->InitPlugins(); + fBrowser->MapWindow(); + + // -------------------------------- + + fViewers = new TEveViewerList("Viewers"); + fViewers->IncDenyDestroy(); + AddToListTree(fViewers, kTRUE); + + fViewer = new TEveViewer("GL-One"); + fViewer->SetGLViewer(glv); + fViewer->IncDenyDestroy(); + AddElement(fViewer, fViewers); + + fScenes = new TEveSceneList ("Scenes"); + fScenes->IncDenyDestroy(); + AddToListTree(fScenes, kTRUE); + + fGlobalScene = new TEveScene("Geometry scene"); + fGlobalScene->IncDenyDestroy(); + AddElement(fGlobalScene, fScenes); + + fEventScene = new TEveScene("Event scene"); + fEventScene->IncDenyDestroy(); + AddElement(fEventScene, fScenes); + + fViewer->AddScene(fGlobalScene); + fViewer->AddScene(fEventScene); + + /**************************************************************************/ + /**************************************************************************/ + + fEditor->DisplayObject(GetGLViewer()); + + gSystem->ProcessEvents(); +} + +//______________________________________________________________________________ +TEveManager::~TEveManager() +{ + // Destructor. +} + +/******************************************************************************/ + +//______________________________________________________________________________ +TCanvas* TEveManager::AddCanvasTab(const char* name) +{ + // Add a new canvas tab. + + fBrowser->StartEmbedding(1, -1); + TCanvas* c = new TCanvas; + fBrowser->StopEmbedding(); + fBrowser->SetTabTitle(name, 1, -1); + + return c; +} + +//______________________________________________________________________________ +TGWindow* TEveManager::GetMainWindow() const +{ + // Get the main window, i.e. the first created reve-browser. + + return fBrowser; +} + +//______________________________________________________________________________ +TGLViewer* TEveManager::GetGLViewer() const +{ + // Get default TGLViewer. + + return fViewer->GetGLViewer(); +} + +//______________________________________________________________________________ +TEveViewer* TEveManager::SpawnNewViewer(const Text_t* name, const Text_t* title, + Bool_t embed) +{ + // Create a new GL viewer. + + TEveViewer* v = new TEveViewer(name, title); + + if (embed) fBrowser->StartEmbedding(1); + v->SpawnGLViewer(gClient->GetRoot(), embed ? fEditor : 0); + v->IncDenyDestroy(); + if (embed) fBrowser->StopEmbedding(), fBrowser->SetTabTitle(name, 1); + AddElement(v, fViewers); + return v; +} + +//______________________________________________________________________________ +TEveScene* TEveManager::SpawnNewScene(const Text_t* name, const Text_t* title) +{ + // Create a new scene. + + TEveScene* s = new TEveScene(name, title); + AddElement(s, fScenes); + return s; +} + +/******************************************************************************/ +// TEveUtil::Macro management +/******************************************************************************/ + +//______________________________________________________________________________ +TMacro* TEveManager::GetMacro(const Text_t* name) const +{ + return dynamic_cast(fMacroFolder->FindObject(name)); +} + +/******************************************************************************/ +// Editor +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveManager::EditElement(TEveElement* rnr_element) +{ + static const TEveException eH("TEveManager::EditElement "); + + fEditor->DisplayElement(rnr_element); +} + +/******************************************************************************/ +// 3D TEvePad management +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveManager::RegisterRedraw3D() +{ + // Register a request for 3D redraw. + + fRedrawTimer.Start(0, kTRUE); + fTimerActive = true; +} + +//______________________________________________________________________________ +void TEveManager::DoRedraw3D() +{ + // Perform 3D redraw of scenes and viewers whose contents has + // changed. + + // printf("TEveManager::DoRedraw3D redraw triggered\n"); + + fScenes ->RepaintChangedScenes(); + fViewers->RepaintChangedViewers(fResetCameras, fDropLogicals); + + fResetCameras = kFALSE; + fDropLogicals = kFALSE; + + fTimerActive = kFALSE; +} + +//______________________________________________________________________________ +void TEveManager::FullRedraw3D(Bool_t resetCameras, Bool_t dropLogicals) +{ + // Perform 3D redraw of all scenes and viewers. + + fScenes ->RepaintAllScenes(); + fViewers->RepaintAllViewers(resetCameras, dropLogicals); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveManager::ElementChanged(TEveElement* rnr_element) +{ + std::list scenes; + rnr_element->CollectSceneParents(scenes); + ScenesChanged(scenes); +} + +//______________________________________________________________________________ +void TEveManager::ScenesChanged(std::list& scenes) +{ + for (TEveElement::List_i s=scenes.begin(); s!=scenes.end(); ++s) + ((TEveScene*)*s)->Changed(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +int TEveManager::SpawnGuiAndRun(int argc, char **argv) +{ + Int_t w = 1024; + Int_t h = 768; + + TRint theApp("App", &argc, argv); + + TEveUtil::SetupGUI(); + /* gEve = */ new TEveManager(w, h); + +run_loop: + try { + theApp.Run(); + } + catch(TEveException& exc) { + gEve->SetStatusLine(exc.Data()); + fprintf(stderr, "Exception: %s\n", exc.Data()); + goto run_loop; + } + return 0; +} + +//______________________________________________________________________________ +void TEveManager::SpawnGui() +{ + Int_t w = 1024; + Int_t h = 768; + + TEveUtil::SetupGUI(); + /* gEve = */ new TEveManager(w, h); +} + +/******************************************************************************/ +/******************************************************************************/ + +//______________________________________________________________________________ +TGListTree* TEveManager::GetListTree() const +{ + return fLTEFrame->fListTree; +} + +TGListTreeItem* +TEveManager::AddToListTree(TEveElement* re, Bool_t open, TGListTree* lt) +{ + // Add rnr-el as a top-level to a list-tree. + // Please add a single copy of a render-element as a top level + // or we will have to check for that, too. + + if (lt == 0) lt = GetListTree(); + TGListTreeItem* lti = re->AddIntoListTree(lt, (TGListTreeItem*)0); + if (open) lt->OpenItem(lti); + return lti; +} + +//______________________________________________________________________________ +void TEveManager::RemoveFromListTree(TEveElement* re, TGListTree* lt, TGListTreeItem* lti) +{ + // Remove top-level rnr-el from list-tree with specified tree-item. + + static const TEveException eH("TEveManager::RemoveFromListTree "); + + if (lti->GetParent()) + throw(eH + "not a top-level item."); + + re->RemoveFromListTree(lt, 0); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +TGListTreeItem* TEveManager::AddEvent(TEveEventManager* event) +{ + fCurrentEvent = event; + fCurrentEvent->IncDenyDestroy(); + AddElement(fCurrentEvent, fEventScene); + return AddToListTree(event, kTRUE); +} + +//______________________________________________________________________________ +TGListTreeItem* TEveManager::AddElement(TEveElement* rnr_element, + TEveElement* parent) +{ + if (parent == 0) { + if (fCurrentEvent == 0) + AddEvent(new TEveEventManager("Event", "Auto-created event directory")); + parent = fCurrentEvent; + } + + return parent->AddElement(rnr_element); +} + +//______________________________________________________________________________ +TGListTreeItem* TEveManager::AddGlobalElement(TEveElement* rnr_element, + TEveElement* parent) +{ + if (parent == 0) + parent = fGlobalScene; + + return parent->AddElement(rnr_element); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveManager::RemoveElement(TEveElement* rnr_element, + TEveElement* parent) +{ + parent->RemoveElement(rnr_element); +} + +//______________________________________________________________________________ +void TEveManager::PreDeleteElement(TEveElement* rnr_element) +{ + if (fEditor->GetRnrElement() == rnr_element) + fEditor->DisplayObject(0); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveManager::ElementSelect(TEveElement* rnr_element) +{ + EditElement(rnr_element); +} + +//______________________________________________________________________________ +Bool_t TEveManager::ElementPaste(TEveElement* rnr_element) +{ + TEveElement* src = fEditor->GetRnrElement(); + if (src) + return rnr_element->HandleElementPaste(src); + return kFALSE; +} + +//______________________________________________________________________________ +void TEveManager::ElementChecked(TEveElement* rnrEl, Bool_t state) +{ + rnrEl->SetRnrState(state); + + if (fEditor->GetModel() == rnrEl->GetEditorObject()) + fEditor->DisplayElement(rnrEl); + + rnrEl->ElementChanged(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveManager::NotifyBrowser(TGListTreeItem* parent_lti) +{ + TGListTree* lt = GetListTree(); + if (parent_lti) + lt->OpenItem(parent_lti); + lt->ClearViewPort(); +} + +//______________________________________________________________________________ +void TEveManager::NotifyBrowser(TEveElement* parent) +{ + TGListTreeItem* parent_lti = parent ? parent->FindListTreeItem(GetListTree()) : 0; + NotifyBrowser(parent_lti); +} + +/******************************************************************************/ +// GeoManager registration +/******************************************************************************/ + +//______________________________________________________________________________ +TGeoManager* TEveManager::GetGeometry(const TString& filename) +{ + static const TEveException eH("TEveManager::GetGeometry "); + + TString exp_filename = filename; + gSystem->ExpandPathName(exp_filename); + printf("%s loading: '%s' -> '%s'.\n", eH.Data(), + filename.Data(), exp_filename.Data()); + + std::map::iterator g = fGeometries.find(filename); + if (g != fGeometries.end()) { + return g->second; + } else { + if (gSystem->AccessPathName(exp_filename, kReadPermission)) + throw(eH + "file '" + exp_filename + "' not readable."); + gGeoManager = 0; + TGeoManager::Import(filename); + if (gGeoManager == 0) + throw(eH + "GeoManager import failed."); + gGeoManager->GetTopVolume()->VisibleDaughters(1); + + // Import colors exported by Gled, if they exist. + { + TFile f(exp_filename, "READ"); + TObjArray* collist = (TObjArray*) f.Get("ColorList"); + f.Close(); + if (collist != 0) { + TIter next(gGeoManager->GetListOfVolumes()); + TGeoVolume* vol; + while ((vol = (TGeoVolume*) next()) != 0) + { + Int_t oldID = vol->GetLineColor(); + TColor* col = (TColor*)collist->At(oldID); + Float_t r, g, b; + col->GetRGB(r, g, b); + Int_t newID = TColor::GetColor(r,g,b); + vol->SetLineColor(newID); + } + } + } + + fGeometries[filename] = gGeoManager; + return gGeoManager; + } +} + +/******************************************************************************/ +// Testing exceptions +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveManager::SetStatusLine(const char* text) +{ + fStatusBar->SetText(text); +} + +//______________________________________________________________________________ +void TEveManager::ThrowException(const char* text) +{ + static const TEveException eH("TEveManager::ThrowException "); + + throw(eH + text); +} diff --git a/eve/src/TEvePad.cxx b/eve/src/TEvePad.cxx new file mode 100644 index 0000000000..4ea1d1b805 --- /dev/null +++ b/eve/src/TEvePad.cxx @@ -0,0 +1,38 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include + +//______________________________________________________________________________ +// TEvePad +// +// This was intended as a TPad wrapper to allow smart updates of +// groups of pads. Uses THashList instead of TList for faster removal +// of objects from the pad. + +ClassImp(TEvePad) + +//______________________________________________________________________________ +TEvePad::TEvePad() +{ + fPrimitives = new THashList; +} + +//______________________________________________________________________________ +TEvePad::TEvePad(const char *name, const char *title, Double_t xlow, + Double_t ylow, Double_t xup, Double_t yup, + Color_t color, Short_t bordersize, Short_t bordermode) + : TPad(name,title,xlow,ylow,xup,yup,color,bordersize,bordermode) +{ + delete fPrimitives; + fPrimitives = new THashList; +} diff --git a/eve/src/TEvePointSet.cxx b/eve/src/TEvePointSet.cxx new file mode 100644 index 0000000000..637d8ae2d8 --- /dev/null +++ b/eve/src/TEvePointSet.cxx @@ -0,0 +1,602 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 + +#include +#include + +#include +#include +#include + +#include +#include + +//______________________________________________________________________________ +// TEvePointSet +// +// TEvePointSet is a render-element holding a collection of 3D points with +// optional per-point TRef and an arbitrary number of integer ids (to +// be used for signal, volume-id, track-id, etc). +// +// 3D point representation is implemented in base-class TPolyMarker3D. +// Per-point TRef is implemented in base-class TPointSet3D. +// +// By using the TEvePointSelector the points and integer ids can be +// filled directly from a TTree holding the source data. +// Setting of per-point TRef's is not supported. +// +// TEvePointSet is a TEveProjectable: it can be projected by using the +// TEveProjectionManager class. + +ClassImp(TEvePointSet) + +//______________________________________________________________________________ +TEvePointSet::TEvePointSet(Int_t n_points, TreeVarType_e tv_type) : + TEveElement(fMarkerColor), + TPointSet3D(n_points), + TEvePointSelectorConsumer(tv_type), + + fTitle (), + fIntIds (0), + fIntIdsPerPoint (0) +{ + // Constructor. + + fMarkerStyle = 20; +} + +//______________________________________________________________________________ +TEvePointSet::TEvePointSet(const Text_t* name, Int_t n_points, TreeVarType_e tv_type) : + TEveElement(fMarkerColor), + TPointSet3D(n_points), + TEvePointSelectorConsumer(tv_type), + + fTitle (), + fIntIds (0), + fIntIdsPerPoint (0) +{ + // Constructor. + + fMarkerStyle = 20; + SetName(name); +} + +//______________________________________________________________________________ +TEvePointSet::~TEvePointSet() +{ + // Destructor. + + delete fIntIds; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEvePointSet::ComputeBBox() +{ + // Override of virtual method from TAttBBox. + + TPointSet3D::ComputeBBox(); + AssertBBoxExtents(0.1); +} + +//______________________________________________________________________________ +void TEvePointSet::Reset(Int_t n_points, Int_t n_int_ids) +{ + // Drop all data and set-up the data structures to recive new data. + // n_points specifies the initial size of the arrays. + // n_int_ids specifies the number of integer ids per point. + + delete [] fP; fP = 0; + fN = n_points; + if(fN) fP = new Float_t [3*fN]; + memset(fP, 0, 3*fN*sizeof(Float_t)); + fLastPoint = -1; + ClearIds(); + delete fIntIds; fIntIds = 0; + fIntIdsPerPoint = n_int_ids; + if (fIntIdsPerPoint > 0) fIntIds = new TArrayI(fIntIdsPerPoint*fN); + ResetBBox(); +} + +//______________________________________________________________________________ +Int_t TEvePointSet::GrowFor(Int_t n_points) +{ + // Resizes internal array to allow additional n_points to be stored. + // Returns the old size which is also the location where one can + // start storing new data. + // The caller is *obliged* to fill the new point slots. + + Int_t old_size = Size(); + Int_t new_size = old_size + n_points; + SetPoint(new_size - 1, 0, 0, 0); + if (fIntIds) + fIntIds->Set(fIntIdsPerPoint * new_size); + return old_size; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +inline void TEvePointSet::AssertIntIdsSize() +{ + // Assert that size of IntId array is compatible with the size of + // the point array. + + Int_t exp_size = GetN()*fIntIdsPerPoint; + if (fIntIds->GetSize() < exp_size) + fIntIds->Set(exp_size); +} + +//______________________________________________________________________________ +Int_t* TEvePointSet::GetPointIntIds(Int_t p) const +{ + // Return a pointer to integer ids of point with index p. + // Existence of integer id array is checked, 0 is returned if it + // does not exist. + // Validity of p is *not* checked. + + if (fIntIds) + return fIntIds->GetArray() + p*fIntIdsPerPoint; + return 0; +} + +//______________________________________________________________________________ +Int_t TEvePointSet::GetPointIntId(Int_t p, Int_t i) const +{ + // Return i-th integer id of point with index p. + // Existence of integer id array is checked, kMinInt is returned if + // it does not exist. + // Validity of p and i is *not* checked. + + if (fIntIds) + return * (fIntIds->GetArray() + p*fIntIdsPerPoint + i); + return kMinInt; +} + +//______________________________________________________________________________ +void TEvePointSet::SetPointIntIds(Int_t* ids) +{ + // Set integer ids for the last point that was registerd (most + // probably via TPolyMarker3D::SetNextPoint(x,y,z)). + + SetPointIntIds(fLastPoint, ids); +} + +//______________________________________________________________________________ +void TEvePointSet::SetPointIntIds(Int_t n, Int_t* ids) +{ + // Set integer ids for point with index n. + + if (!fIntIds) return; + AssertIntIdsSize(); + Int_t* x = fIntIds->GetArray() + n*fIntIdsPerPoint; + for (Int_t i=0; i 0) { + fIntIdsPerPoint = subIdNum; + if (!fIntIds) + fIntIds = new TArrayI(fIntIdsPerPoint*GetN()); + else + fIntIds->Set(fIntIdsPerPoint*GetN()); + } else { + delete fIntIds; fIntIds = 0; + fIntIdsPerPoint = 0; + } +} + +//______________________________________________________________________________ +void TEvePointSet::TakeAction(TEvePointSelector* sel) +{ + // Called from TEvePointSelector when internal arrays of the tree-selector + // are filled up and need to be processed. + // Virtual from TEvePointSelectorConsumer. + + static const TEveException eH("TEvePointSet::TakeAction "); + + if(sel == 0) + throw(eH + "selector is ."); + + Int_t n = sel->GetNfill(); + Int_t beg = GrowFor(n); + + // printf("TEvePointSet::TakeAction beg=%d n=%d size=%d nsubid=%d dim=%d\n", + // beg, n, Size(), sel->GetSubIdNum(), sel->GetDimension()); + + Double_t *vx = sel->GetV1(), *vy = sel->GetV2(), *vz = sel->GetV3(); + Float_t *p = fP + 3*beg; + + switch(fSourceCS) { + case TVT_XYZ: + while(n-- > 0) { + p[0] = *vx; p[1] = *vy; p[2] = *vz; + p += 3; + ++vx; ++vy; ++vz; + } + break; + case TVT_RPhiZ: + while(n-- > 0) { + p[0] = *vx * TMath::Cos(*vy); p[1] = *vx * TMath::Sin(*vy); p[2] = *vz; + p += 3; + ++vx; ++vy; ++vz; + } + break; + default: + throw(eH + "unknown tree variable type."); + } + + if (fIntIds) { + Double_t** subarr = new Double_t* [fIntIdsPerPoint]; + for (Int_t i=0; iGetVal(sel->GetDimension() - fIntIdsPerPoint + i); + if (subarr[i] == 0) + throw(eH + "sub-id array not available."); + } + Int_t* ids = fIntIds->GetArray() + fIntIdsPerPoint*beg; + n = sel->GetNfill(); + while (n-- > 0) { + for (Int_t i=0; iGetRnrSelf()) + (*i)->GetObject()->Paint(option); + } + } +} + +//______________________________________________________________________________ +void TEvePointSetArray::RemoveElementLocal(TEveElement* el) +{ + // Virtual from TEveElement, provide bin management. + + for (Int_t i=0; i((*i)->GetObject()); + if (m && m->GetMarkerColor() == fMarkerColor) + m->SetMarkerColor(tcolor); + } + TAttMarker::SetMarkerColor(tcolor); +} + +//______________________________________________________________________________ +void TEvePointSetArray::SetMarkerStyle(Style_t mstyle) +{ + for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) { + TAttMarker* m = dynamic_cast((*i)->GetObject()); + if (m && m->GetMarkerStyle() == fMarkerStyle) + m->SetMarkerStyle(mstyle); + } + TAttMarker::SetMarkerStyle(mstyle); +} + +//______________________________________________________________________________ +void TEvePointSetArray::SetMarkerSize(Size_t msize) +{ + for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) { + TAttMarker* m = dynamic_cast((*i)->GetObject()); + if (m && m->GetMarkerSize() == fMarkerSize) + m->SetMarkerSize(msize); + } + TAttMarker::SetMarkerSize(msize); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEvePointSetArray::TakeAction(TEvePointSelector* sel) +{ + // Called from TEvePointSelector when internal arrays of the tree-selector + // are filled up and need to be processed. + // Virtual from TEvePointSelectorConsumer. + + static const TEveException eH("TEvePointSetArray::TakeAction "); + + if (sel == 0) + throw(eH + "selector is ."); + + Int_t n = sel->GetNfill(); + + // printf("TEvePointSetArray::TakeAction n=%d\n", n); + + Double_t *vx = sel->GetV1(), *vy = sel->GetV2(), *vz = sel->GetV3(); + Double_t *qq = sel->GetV4(); + + if(qq == 0) + throw(eH + "requires 4-d varexp."); + + switch(fSourceCS) { + case TVT_XYZ: + while(n-- > 0) { + Fill(*vx, *vy, *vz, *qq); + ++vx; ++vy; ++vz; ++qq; + } + break; + case TVT_RPhiZ: + while(n-- > 0) { + Fill(*vx * TMath::Cos(*vy), *vx * TMath::Sin(*vy), *vz, *qq); + ++vx; ++vy; ++vz; ++qq; + } + break; + default: + throw(eH + "unknown tree variable type."); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEvePointSetArray::InitBins(const Text_t* quant_name, + Int_t nbins, Double_t min, Double_t max, + Bool_t addRe) +{ + static const TEveException eH("TEvePointSetArray::InitBins "); + + if (nbins < 1) throw(eH + "nbins < 1."); + if (min > max) throw(eH + "min > max."); + + RemoveElements(); + + fQuantName = quant_name; + fNBins = nbins; + fLastBin = -1; + fMin = fCurMin = min; + fMax = fCurMax = max; + fBinWidth = (fMax - fMin)/fNBins; + + fBins = new TEvePointSet*[fNBins]; + for (Int_t i=0; iSetMarkerColor(fMarkerColor); + fBins[i]->SetMarkerStyle(fMarkerStyle); + fBins[i]->SetMarkerSize(fMarkerSize); + if (addRe) + gEve->AddElement(fBins[i], this); + else + AddElement(fBins[i]); + } +} + +//______________________________________________________________________________ +void TEvePointSetArray::Fill(Double_t x, Double_t y, Double_t z, Double_t quant) +{ + fLastBin = Int_t( (quant - fMin)/fBinWidth ); + if (fLastBin >= 0 && fLastBin < fNBins && fBins[fLastBin] != 0) + fBins[fLastBin]->SetNextPoint(x, y, z); + else + fLastBin = -1; +} + +//______________________________________________________________________________ +void TEvePointSetArray::SetPointId(TObject* id) +{ + if (fLastBin >= 0) + fBins[fLastBin]->SetPointId(id); +} + +//______________________________________________________________________________ +void TEvePointSetArray::CloseBins() +{ + for (Int_t i=0; ifN = fBins[i]->fLastPoint; + + fBins[i]->ComputeBBox(); + } + } + fLastBin = -1; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEvePointSetArray::SetOwnIds(Bool_t o) +{ + for (Int_t i=0; iSetOwnIds(o); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEvePointSetArray::SetRange(Double_t min, Double_t max) +{ + using namespace TMath; + + fCurMin = min; fCurMax = max; + Int_t low_b = (Int_t) Max(Double_t(0), Floor((min-fMin)/fBinWidth)); + Int_t high_b = (Int_t) Min(Double_t(fNBins-1), Ceil((max-fMin)/fBinWidth)); + for (Int_t i=0; iSetRnrSelf(i>=low_b && i<=high_b); + } +} + + +/******************************************************************************/ +/******************************************************************************/ + +//______________________________________________________________________________ +// TEvePointSetProjected +// +// Projected copy of a TEvePointSet. + +ClassImp(TEvePointSetProjected) + +//______________________________________________________________________________ +TEvePointSetProjected::TEvePointSetProjected() : + TEvePointSet (), + TEveProjected () +{ + // Default contructor. +} + +//______________________________________________________________________________ +void TEvePointSetProjected::SetProjection(TEveProjectionManager* proj, TEveProjectable* model) +{ + TEveProjected::SetProjection(proj, model); + + * (TAttMarker*)this = * dynamic_cast(fProjectable); +} + +//______________________________________________________________________________ +void TEvePointSetProjected::UpdateProjection() +{ + TEveProjection& proj = * fProjector->GetProjection(); + TEvePointSet & ps = * dynamic_cast(fProjectable); + + Int_t n = ps.GetN(); + Reset(n); + Float_t *o = ps.GetP(), *p = GetP(); + for (Int_t i = 0; i < n; ++i, o+=3, p+=3) + { + p[0] = o[0]; p[1] = o[1]; p[2] = o[2]; + proj.ProjectPoint(p[0], p[1], p[2]); + p[2] = fDepth; + } + fLastPoint = n - 1; +} diff --git a/eve/src/TEvePointSetArrayEditor.cxx b/eve/src/TEvePointSetArrayEditor.cxx new file mode 100644 index 0000000000..1f49e67e7f --- /dev/null +++ b/eve/src/TEvePointSetArrayEditor.cxx @@ -0,0 +1,86 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +//______________________________________________________________________________ +// TEvePointSetArrayEditor +// +// Editor for TEvePointSetArray class. + +ClassImp(TEvePointSetArrayEditor) + +//______________________________________________________________________________ +TEvePointSetArrayEditor::TEvePointSetArrayEditor(const TGWindow *p, + Int_t width, Int_t height, + UInt_t options, Pixel_t back) : + TGedFrame(p,width, height, options | kVerticalFrame, back), + fM(0), + fRange(0) +{ + // Constructor. + + fM = 0; + MakeTitle("TEvePointSetArray"); + + fRange = new TEveGDoubleValuator(this,"Range", 200, 0); + fRange->SetNELength(6); + //fRange->SetLabelWidth(labelW); + fRange->Build(); + fRange->GetSlider()->SetWidth(224); + fRange->Connect("ValueSet()", + "TEvePointSetArrayEditor", this, "DoRange()"); + AddFrame(fRange, new TGLayoutHints(kLHintsTop, 1, 1, 2, 1)); +} + +//______________________________________________________________________________ +TEvePointSetArrayEditor::~TEvePointSetArrayEditor() +{ + // Destructor. +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEvePointSetArrayEditor::SetModel(TObject* obj) +{ + // Set model object. + + fM = dynamic_cast(obj); + + // printf("FullRange(%f, %f) Selected(%f,%f)\n", + // fM->GetMin(), fM->GetMax(), fM->GetCurMin(), fM->GetCurMax()); + + fRange->SetLimits(fM->fMin, fM->fMax, TGNumberFormat::kNESRealTwo); + fRange->SetValues(fM->fCurMin, fM->fCurMax); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEvePointSetArrayEditor::DoRange() +{ + // Slot for setting the range of the separating quantity. + + fM->SetRange(fRange->GetMin(), fRange->GetMax()); + Update(); +} diff --git a/eve/src/TEvePointSetProjectedGL.cxx b/eve/src/TEvePointSetProjectedGL.cxx new file mode 100644 index 0000000000..6c0b7293f2 --- /dev/null +++ b/eve/src/TEvePointSetProjectedGL.cxx @@ -0,0 +1,33 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 + +//______________________________________________________________________________ +// TEvePointSetProjectedGL +// +// GL-renderer for TEvePointSetProjected class. +// +// A hack around a bug in fglrx that makes rendering of projected pointsets +// terribly slow with display-lists on when rendering as crosses. + +ClassImp(TEvePointSetProjectedGL) + +//______________________________________________________________________________ +TEvePointSetProjectedGL::TEvePointSetProjectedGL() : TPointSet3DGL() +{ + // Contructor. + fDLCache = kFALSE; // Disable display list. +} + +//______________________________________________________________________________ +TEvePointSetProjectedGL::~TEvePointSetProjectedGL() +{} diff --git a/eve/src/TEvePolygonSetProjected.cxx b/eve/src/TEvePolygonSetProjected.cxx new file mode 100644 index 0000000000..6944ee33f3 --- /dev/null +++ b/eve/src/TEvePolygonSetProjected.cxx @@ -0,0 +1,473 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include +#include + +#include +#include +#include +#include + +#include + +namespace +{ +struct Seg +{ + Int_t v1; + Int_t v2; + + Seg(Int_t i1=-1, Int_t i2=-1):v1(i1), v2(i2){}; +}; +typedef std::list::iterator It_t; +} + + +//______________________________________________________________________________ +// TEvePolygonSetProjected +// +// A set of projected polygons. +// Used for storage of projected geometrical shapes. +// +// Internal struct Polygon_t holds only indices into the master vertex +// array in TEvePolygonSetProjected. + +ClassImp(TEvePolygonSetProjected) + +//______________________________________________________________________________ +TEvePolygonSetProjected::TEvePolygonSetProjected(const Text_t* n, const Text_t* t) : + TEveElementList(n, t), + + fBuff(0), + fIdxMap(0), + + fSurf(0), + + fNPnts(0), + fPnts(0), + + fFillColor(5), + fLineColor(3), + fLineWidth(1), + fTransparency (0) +{ + SetMainColorPtr(&fFillColor); +} + +//______________________________________________________________________________ +TEvePolygonSetProjected::~TEvePolygonSetProjected() +{ + ClearPolygonSet(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEvePolygonSetProjected::ClearPolygonSet() +{ + // delete polygon vertex indices + Int_t* p; + for (vpPolygon_i i = fPols.begin(); i!= fPols.end(); i++) + { + p = (*i).fPnts; delete [] p; + } + fPols.clear(); + + // delete reduced points + delete [] fPnts; fPnts = 0; fNPnts = 0; + fSurf = 0; +} + +//______________________________________________________________________________ +void TEvePolygonSetProjected::SetProjection(TEveProjectionManager* proj, TEveProjectable* model) +{ + TEveProjected::SetProjection(proj, model); + TEveGeoShape* gre = dynamic_cast(model); + + fBuff = gre->MakeBuffer3D(); + if(fBuff) + { + Color_t color = gre->GetMainColor(); + SetMainColor(color); + SetLineColor((Color_t)TColor::GetColorBright(color)); + SetMainTransparency(gre->GetMainTransparency()); + } +} + +//______________________________________________________________________________ +void TEvePolygonSetProjected::UpdateProjection() +{ + if(fBuff == 0) return; + + // drop polygons, and projected/reduced points + ClearPolygonSet(); + ProjectBuffer3D(); +} + +//______________________________________________________________________________ +Bool_t TEvePolygonSetProjected::IsFirstIdxHead(Int_t s0, Int_t s1) +{ + Int_t v0 = fBuff->fSegs[3*s0 + 1]; + Int_t v2 = fBuff->fSegs[3*s1 + 1]; + Int_t v3 = fBuff->fSegs[3*s1 + 2]; + if(v0 != v2 && v0 != v3 ) + return kTRUE; + else + return kFALSE; +} + +//______________________________________________________________________________ +void TEvePolygonSetProjected::ProjectAndReducePoints() +{ + TEveProjection* projection = fProjector->GetProjection(); + + Int_t N = fBuff->NbPnts(); + TEveVector* pnts = new TEveVector[N]; + for(Int_t i = 0; ifPnts[3*i],fBuff->fPnts[3*i+1], fBuff->fPnts[3*i+2]); + projection->ProjectPoint(pnts[i].x, pnts[i].y, pnts[i].z, TEveProjection::PP_Plane); + } + fIdxMap = new Int_t[N]; + Int_t* ra = new Int_t[N]; // list of reduced vertices + for(UInt_t v = 0; v < (UInt_t)N; ++v) + { + fIdxMap[v] = -1; + for(Int_t k = 0; k < fNPnts; ++k) + { + if(pnts[v].SquareDistance(pnts[ra[k]]) < TEveProjection::fgEps*TEveProjection::fgEps) + { + fIdxMap[v] = k; + break; + } + } + // have not found a point inside epsilon, add new point in scaled array + if(fIdxMap[v] == -1) + { + fIdxMap[v] = fNPnts; + ra[fNPnts] = v; + ++fNPnts; + } + // printf("(%f, %f) vertex map %d -> %d \n", pnts[v*2], pnts[v*2 + 1], v, fIdxMap[v]); + } + + // create an array of scaled points + fPnts = new TEveVector[fNPnts]; + for(Int_t idx = 0; idx < fNPnts; ++idx) + { + Int_t i = ra[idx]; + projection->ProjectPoint(pnts[i].x, pnts[i].y, pnts[i].z, TEveProjection::PP_Distort); + fPnts[idx].Set(pnts[i]); + } + delete [] ra; + delete [] pnts; + // printf("reduced %d points of %d\n", fNPnts, N); +} + +//______________________________________________________________________________ +void TEvePolygonSetProjected::AddPolygon(std::list& pp, vpPolygon_t& pols) +{ + if(pp.size() <= 2) return; + + // dimension of bbox + Float_t bbox[] = { 1e6, -1e6, 1e6, -1e6, 1e6, -1e6 }; + for (std::list::iterator u = pp.begin(); u!= pp.end(); u++) + { + Int_t idx = *u; + if(fPnts[idx].x < bbox[0]) bbox[0] = fPnts[idx].x; + if(fPnts[idx].x > bbox[1]) bbox[1] = fPnts[idx].x; + + if(fPnts[idx].y < bbox[2]) bbox[2] = fPnts[idx].y; + if(fPnts[idx].y > bbox[3]) bbox[3] = fPnts[idx].y; + } + Float_t eps = 2*TEveProjection::fgEps; + if((bbox[1]-bbox[0])::iterator u = pp.begin(); + Int_t pidx = P.FindPoint(*u); + if (pidx < 0) + continue; + while (u != pp.end()) + { + if ((*u) != P.fPnts[pidx]) + break; + ++u; + if (++pidx >= P.fNPnts) pidx = 0; + } + if (u == pp.end()) return; + } + + // printf("add %d Polygon points %d \n", pols.size(), pp.size()); + Int_t* pv = new Int_t[pp.size()]; + Int_t count=0; + for( std::list::iterator u = pp.begin(); u!= pp.end(); u++){ + pv[count] = *u; + count++; + } + pols.push_back(Polygon_t(pp.size(), pv)); + fSurf += (bbox[1]-bbox[0])*(bbox[3]-bbox[2]); + // printf("Add Surf %f\n",( bbox[1]-bbox[0])*(bbox[3]-bbox[2])); +} // AddPolygon + +//______________________________________________________________________________ +void TEvePolygonSetProjected::MakePolygonsFromBP() +{ + // build polygons from sorted list of segments : buff->fPols + + // printf("START TEvePolygonSetProjected::MakePolygonsFromBP\n"); + TEveProjection* projection = fProjector->GetProjection(); + Int_t* bpols = fBuff->fPols; + for(UInt_t pi = 0; pi< fBuff->NbPols(); pi++) + { + std::list pp; // points in current polygon + UInt_t Nseg = bpols[1]; + Int_t* seg = &bpols[2]; + // start idx in the fist segment depends of second segment + Int_t tail, head; + Bool_t h = IsFirstIdxHead(seg[0], seg[1]); + if(h) { + head = fIdxMap[fBuff->fSegs[3*seg[0] + 1]]; + tail = fIdxMap[fBuff->fSegs[3*seg[0] + 2]]; + } + else { + head = fIdxMap[fBuff->fSegs[3*seg[0] + 2]]; + tail = fIdxMap[fBuff->fSegs[3*seg[0] + 1]]; + } + pp.push_back(head); + // printf("start idx head %d, tail %d\n", head, tail); + std::list segs; + for(UInt_t s = 1; s < Nseg; ++s) + segs.push_back(Seg(fBuff->fSegs[3*seg[s] + 1],fBuff->fSegs[3*seg[s] + 2])); + + + Bool_t accepted = kFALSE; + for(std::list::iterator it = segs.begin(); it != segs.end(); it++ ) + { + Int_t mv1 = fIdxMap[(*it).v1]; + Int_t mv2 = fIdxMap[(*it).v2]; + accepted = projection->AcceptSegment(fPnts[mv1], fPnts[mv2], TEveProjection::fgEps); + + if(accepted == kFALSE) + { + pp.clear(); + break; + } + if(tail != pp.back()) pp.push_back(tail); + tail = (mv1 == tail) ? mv2 :mv1; + } + // DirectDraw implementation: last and first vertices should not be equal + if(pp.empty() == kFALSE) + { + if(pp.front() == pp.back()) pp.pop_front(); + AddPolygon(pp, fPolsBP); + } + bpols += (Nseg+2); + } +} + +//______________________________________________________________________________ +void TEvePolygonSetProjected::MakePolygonsFromBS() +{ + // builds polygons from the set of buffer segments + + // create your own list of segments according to reduced and projected points + std::list segs; + std::list::iterator it; + TEveProjection* projection = fProjector->GetProjection(); + for(UInt_t s = 0; s < fBuff->NbSegs(); ++s) + { + Bool_t duplicate = kFALSE; + Int_t vo1, vo2; // idx from fBuff segment + Int_t vor1, vor2; // mapped idx + vo1 = fBuff->fSegs[3*s + 1]; + vo2 = fBuff->fSegs[3*s + 2]; //... skip color info + vor1 = fIdxMap[vo1]; + vor2 = fIdxMap[vo2]; + if(vor1 == vor2) continue; + // check duplicate + for(it = segs.begin(); it != segs.end(); it++ ){ + Int_t vv1 = (*it).v1; + Int_t vv2 = (*it).v2; + if((vv1 == vor1 && vv2 == vor2 )||(vv1 == vor2 && vv2 == vor1 )){ + duplicate = kTRUE; + continue; + } + } + if(duplicate == kFALSE && projection->AcceptSegment(fPnts[vor1], fPnts[vor2], TEveProjection::fgEps)) + { + segs.push_back(Seg(vor1, vor2)); + } + } + + // build polygons from segment pool + while(segs.empty() == kFALSE) + { + // printf("Start building polygon %d from %d segments in POOL \n", pols.size(), segs.size()); + std::list pp; // points in current polygon + pp.push_back(segs.front().v1); + Int_t tail = segs.front().v2; + segs.pop_front(); + Bool_t match = kTRUE; + while(match && segs.empty() == kFALSE) + { + // printf("second loop search tail %d \n",tail); + for(It_t k=segs.begin(); k!=segs.end(); ++k){ + Int_t cv1 = (*k).v1; + Int_t cv2 = (*k).v2; + if( cv1 == tail || cv2 == tail){ + // printf("found point %d in %d,%d \n", tail, cv1, cv2); + pp.push_back(tail); + tail = (cv1 == tail)? cv2:cv1; + It_t to_erase = k--; + segs.erase(to_erase); + match = kTRUE; + break; + } + else + { + match = kFALSE; + } + } // end for loop in the segment pool + if(tail == pp.front()) + break; + }; + AddPolygon(pp, fPolsBS); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEvePolygonSetProjected::ProjectBuffer3D() +{ + //DumpBuffer3D(); + ProjectAndReducePoints(); + TEveProjection::GeoMode_e mode = fProjector->GetProjection()->GetGeoMode(); + + switch (mode) + { + case TEveProjection::GM_Polygons : + { + MakePolygonsFromBP(); + fPolsBP.swap(fPols); + break; + } + case TEveProjection::GM_Segments : + { + MakePolygonsFromBS(); + fPolsBS.swap(fPols); + break; + } + case TEveProjection::GM_Unknown: + { + Float_t BPsurf = fSurf; + fSurf = 0; + MakePolygonsFromBS(); + if(fSurf < BPsurf) + { + fPolsBP.swap(fPols); + fPolsBS.clear(); + } + else + { + fPolsBS.swap(fPols); + fPolsBP.clear(); + } + } + default: + break; + } + + delete [] fIdxMap; + ResetBBox(); +} + +//______________________________________________________________________________ +void TEvePolygonSetProjected::ComputeBBox() +{ + BBoxInit(); + for(Int_t pi = 0; piGetViewer3D()->AddObject(buffer); + if (reqSections == TBuffer3D::kNone) { + return; + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEvePolygonSetProjected::DumpPolys() const +{ + printf("TEvePolygonSetProjected %ld polygons\n", fPols.size()); + for (vpPolygon_ci i = fPols.begin(); i!= fPols.end(); i++) + { + Int_t N = (*i).fNPnts; + printf("polygon %d points :\n", N); + for(Int_t vi = 0; vifPols; + + for(UInt_t pi = 0; pi< fBuff->NbPols(); pi++) + { + UInt_t Nseg = bpols[1]; + printf("%d polygon of %d has %d segments \n", pi,fBuff->NbPols(),Nseg); + + Int_t* seg = &bpols[2]; + for(UInt_t a=0; afSegs[3*seg[a]+ 1]; + Int_t a2 = fBuff->fSegs[3*seg[a]+ 2]; + printf("(%d, %d) \n", a1, a2); + printf("ORIG points :(%f, %f, %f) (%f, %f, %f)\n", + fBuff->fPnts[3*a1],fBuff->fPnts[3*a1+1], fBuff->fPnts[3*a1+2], + fBuff->fPnts[3*a2],fBuff->fPnts[3*a2+1], fBuff->fPnts[3*a2+2]); + } + printf("\n"); + bpols += (Nseg+2); + } +} diff --git a/eve/src/TEvePolygonSetProjectedEditor.cxx b/eve/src/TEvePolygonSetProjectedEditor.cxx new file mode 100644 index 0000000000..d3991afe1e --- /dev/null +++ b/eve/src/TEvePolygonSetProjectedEditor.cxx @@ -0,0 +1,83 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include + +#include + +#include +#include +#include +#include + +ClassImp(TEvePolygonSetProjectedEditor) + +//______________________________________________________________________________ +TEvePolygonSetProjectedEditor::TEvePolygonSetProjectedEditor(const TGWindow *p, + Int_t width, Int_t height, + UInt_t options, Pixel_t back) : + TGedFrame(p, width, height, options | kVerticalFrame, back), + fPS(0), + fLineWidth(0), + fLineColor(0) +{ + MakeTitle("TEvePolygonSetProjected"); + + { + TGCompositeFrame *f = new TGCompositeFrame(this, 80, 20, kHorizontalFrame); + + TGLabel *l = new TGLabel(f, "LineColor:"); + f->AddFrame(l, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 25, 2, 1, 1)); + fLineColor = new TGColorSelect(f, 0, -1); + fLineColor->Connect("ColorSelected(Pixel_t)", "TEvePolygonSetProjectedEditor", this, "DoLineColor(Pixel_t)"); + f->AddFrame(fLineColor, new TGLayoutHints(kLHintsLeft, 1, 1, 1, 1)); + + fLineWidth = new TGNumberEntry(f, 0., 6, -1, + TGNumberFormat::kNESRealOne, TGNumberFormat::kNEAPositive, + TGNumberFormat::kNELLimitMinMax, 0.1, 2000.0); + fLineWidth->GetNumberEntry()->SetToolTipText("TEveLine witdth of outline."); + fLineWidth->Connect("ValueSet(Long_t)", "TEvePolygonSetProjectedEditor", this, "DoLineWidth()"); + f->AddFrame(fLineWidth, new TGLayoutHints(kLHintsLeft, 1, 1, 1, 1)); + + AddFrame(f, new TGLayoutHints(kLHintsTop, 1, 1, 0, 0)); + } +} + +//______________________________________________________________________________ +TEvePolygonSetProjectedEditor::~TEvePolygonSetProjectedEditor() +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEvePolygonSetProjectedEditor::SetModel(TObject* obj) +{ + fPS = dynamic_cast(obj); + fLineWidth->SetNumber(fPS->fLineWidth); + fLineColor->SetColor(TColor::Number2Pixel(fPS->GetLineColor()), kFALSE); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEvePolygonSetProjectedEditor::DoLineWidth() +{ + fPS->fLineWidth = fLineWidth->GetNumber(); + Update(); +} + +//______________________________________________________________________________ +void TEvePolygonSetProjectedEditor::DoLineColor(Pixel_t pixel) +{ + fPS->SetLineColor(pixel); + Update(); +} diff --git a/eve/src/TEvePolygonSetProjectedGL.cxx b/eve/src/TEvePolygonSetProjectedGL.cxx new file mode 100644 index 0000000000..bf53a08851 --- /dev/null +++ b/eve/src/TEvePolygonSetProjectedGL.cxx @@ -0,0 +1,161 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include + +#include +#include + +//______________________________________________________________________________ +// TEvePolygonSetProjectedGL +// +// GL-renderer for TEvePolygonSetProjected class. + +ClassImp(TEvePolygonSetProjectedGL) + +//______________________________________________________________________________ +TEvePolygonSetProjectedGL::TEvePolygonSetProjectedGL() : TGLObject() +{ + // Constructor + + // fDLCache = false; // Disable DL. +} + +//______________________________________________________________________________ +TEvePolygonSetProjectedGL::~TEvePolygonSetProjectedGL() +{} + +/******************************************************************************/ +Bool_t TEvePolygonSetProjectedGL::SetModel(TObject* obj, const Option_t* /*opt*/) +{ + return SetModelCheckClass(obj, TEvePolygonSetProjected::Class()); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEvePolygonSetProjectedGL::SetBBox() +{ + SetAxisAlignedBBox(((TEvePolygonSetProjected*)fExternalObj)->AssertBBox()); +} + +/******************************************************************************/ +static GLUtriangulatorObj *GetTesselator() +{ + static struct Init { + Init() + { +#if defined(R__WIN32) + typedef void (CALLBACK *tessfuncptr_t)(); +#elif defined(R__AIXGCC) + typedef void (*tessfuncptr_t)(...); +#else + typedef void (*tessfuncptr_t)(); +#endif + fTess = gluNewTess(); + + if (!fTess) { + Error("GetTesselator::Init", "could not create tesselation object"); + } else { + gluTessCallback(fTess, (GLenum)GLU_BEGIN, (tessfuncptr_t)glBegin); + gluTessCallback(fTess, (GLenum)GLU_END, (tessfuncptr_t)glEnd); + gluTessCallback(fTess, (GLenum)GLU_VERTEX, (tessfuncptr_t)glVertex3fv); + } + } + ~Init() + { + if(fTess) + gluDeleteTess(fTess); + } + GLUtriangulatorObj *fTess; + }singleton; + + return singleton.fTess; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEvePolygonSetProjectedGL::DirectDraw(TGLRnrCtx & /*rnrCtx*/) const +{ + // printf("TEvePolygonSetProjectedGL::DirectDraw %s \n",fExternalObj->GetName() ); + TEvePolygonSetProjected& PS = * (TEvePolygonSetProjected*) fExternalObj; + if(PS.fPols.size() == 0) return; + + glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_POLYGON_BIT); + + glDisable(GL_LIGHTING); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glDisable(GL_CULL_FACE); + + // polygons + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(1.,1.); + GLUtriangulatorObj *tessObj = GetTesselator(); + + TEveVector* pnts = PS.fPnts; + for (TEvePolygonSetProjected::vpPolygon_ci i = PS.fPols.begin(); i!= PS.fPols.end(); i++) + { + Int_t vi; //current vertex index of curent polygon + Int_t N = (*i).fNPnts; // number of points in current polygon + if(N < 4) + { + glBegin(GL_POLYGON); + for(Int_t k=0; k +#include + +//______________________________________________________________________________ +// TEveProjectable +// +// Abstract base-class for non-linear projectable objects. +// +// Via ProjectedClass() method it returns a TClass instance for the +// projected class and keeps references to the projected objects. +// +// See also TEveProjectionManager::ImportElements(). + +ClassImp(TEveProjectable) + +//______________________________________________________________________________ +TEveProjectable::TEveProjectable() +{ + // Comstructor. +} + +//______________________________________________________________________________ +TEveProjectable::~TEveProjectable() +{ + // Destructor. + // Force projected replicas to unreference *this. + + while ( ! fProjectedList.empty()) + { + fProjectedList.front()->UnRefProjectable(this); + } +} + + +//______________________________________________________________________________ +// TEveProjected +// +// Abstract base class for classes that hold results of a non-linear +// projection transformation. +// + +ClassImp(TEveProjected) + +//______________________________________________________________________________ +TEveProjected::TEveProjected() : + fProjector (0), + fProjectable (0), + fDepth (0) +{ + // Constructor. +} + +//______________________________________________________________________________ +TEveProjected::~TEveProjected() +{ + // Destructor. + // If fProjectable is non-null, *this is removed from its list of + // projected replicas. + + if (fProjectable) fProjectable->RemoveProjected(this); +} + +//______________________________________________________________________________ +void TEveProjected::SetProjection(TEveProjectionManager* proj, TEveProjectable* model) +{ + fProjector = proj; + if (fProjectable) fProjectable->RemoveProjected(this); + fProjectable = model; + if (fProjectable) fProjectable->AddProjected(this); +} + +//______________________________________________________________________________ +void TEveProjected::UnRefProjectable(TEveProjectable* assumed_parent) +{ + static const TEveException eH("TEveProjected::UnRefProjectable "); + + if (fProjectable != assumed_parent) { + Warning(eH, "mismatch between assumed and real model. This is a bug."); + assumed_parent->RemoveProjected(this); + return; + } + + if (fProjectable) { + fProjectable->RemoveProjected(this); + fProjectable = 0; + } +} diff --git a/eve/src/TEveProjectionManager.cxx b/eve/src/TEveProjectionManager.cxx new file mode 100644 index 0000000000..22fa0a4c39 --- /dev/null +++ b/eve/src/TEveProjectionManager.cxx @@ -0,0 +1,256 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include + +#include "TBuffer3D.h" +#include "TBuffer3DTypes.h" +#include +#include + +#include + +//______________________________________________________________________________ +// TEveProjectionManager +// +// Manager class for steering of projections and managing projected +// objects. +// +// Recursively projects TEveElement's and draws axis in the projected +// scene. It enables to interactivly set TEveProjection parameters +// and updates projected scene accordingly. + +ClassImp(TEveProjectionManager) + +//______________________________________________________________________________ +TEveProjectionManager::TEveProjectionManager(): + TEveElementList("TEveProjectionManager",""), + + fProjection (0), + + fDrawCenter(kFALSE), + fDrawOrigin(kFALSE), + + fSplitInfoMode(0), + fSplitInfoLevel(1), + fAxisColor(0), + + fCurrentDepth(0) +{ + // Constructor. + + fProjection = new TEveCircularFishEyeProjection(fCenter); + UpdateName(); +} + +//______________________________________________________________________________ +TEveProjectionManager::~TEveProjectionManager() +{ + // Destructor. + + if(fProjection) delete fProjection; +} + +//______________________________________________________________________________ +void TEveProjectionManager::UpdateName() +{ + // Updates name to have consitent information with prjection. + + SetName(Form ("%s (%3.1f)", fProjection->GetName(), fProjection->GetDistortion()*1000)); + UpdateItems(); +} + +//______________________________________________________________________________ +void TEveProjectionManager::SetProjection(TEveProjection::PType_e type, Float_t distort) +{ + // Set projection type and distortion. + + static const TEveException eH("TEveProjectionManager::SetProjection "); + + delete fProjection; + fProjection = 0; + + switch (type) + { + case TEveProjection::PT_CFishEye: + { + fProjection = new TEveCircularFishEyeProjection(fCenter); + break; + } + case TEveProjection::PT_RhoZ: + { + fProjection = new TEveRhoZProjection(fCenter); + break; + } + default: + throw(eH + "projection type not valid."); + break; + } + fProjection->SetDistortion(distort); + UpdateName(); +} +//______________________________________________________________________________ +void TEveProjectionManager::SetCenter(Float_t x, Float_t y, Float_t z) +{ + // Set projection center and rebuild projected scene. + + fCenter.Set(x, y, z); + fProjection->SetCenter(fCenter); + ProjectChildren(); +} + +//______________________________________________________________________________ +Bool_t TEveProjectionManager::HandleElementPaste(TEveElement* el) +{ + // React to element being pasted or dnd-ed. + // Return true if redraw is needed (virtual method). + + size_t n_children = fChildren.size(); + ImportElements(el); + return n_children != fChildren.size(); +} + +//______________________________________________________________________________ +Bool_t TEveProjectionManager::ShouldImport(TEveElement* rnr_el) +{ + // Returns true if rnr_el or any of its children is NTLProjectable. + + if (rnr_el->IsA()->InheritsFrom(TEveProjectable::Class())) + return kTRUE; + for (List_i i=rnr_el->BeginChildren(); i!=rnr_el->EndChildren(); ++i) + if (ShouldImport(*i)) + return kTRUE; + return kFALSE; +} + +//______________________________________________________________________________ +void TEveProjectionManager::ImportElementsRecurse(TEveElement* rnr_el, TEveElement* parent) +{ + // If rnr_el is TEveProjectable add projected instance else add plain TEveElementList + // to parent. Call same function on rnr_el children. + + if (ShouldImport(rnr_el)) + { + TEveElement *new_re = 0; + TEveProjected *new_pr = 0; + TEveProjectable *pble = dynamic_cast(rnr_el); + if (pble) + { + new_re = (TEveElement*) pble->ProjectedClass()->New(); + new_pr = dynamic_cast(new_re); + new_pr->SetProjection(this, pble); + new_pr->SetDepth(fCurrentDepth); + } + else + { + new_re = new TEveElementList; + } + TObject *tobj = rnr_el->GetObject(); + new_re->SetRnrElNameTitle(Form("NLT %s", tobj->GetName()), + tobj->GetTitle()); + new_re->SetRnrSelf (rnr_el->GetRnrSelf()); + new_re->SetRnrChildren(rnr_el->GetRnrChildren()); + gEve->AddElement(new_re, parent); + + for (List_i i=rnr_el->BeginChildren(); i!=rnr_el->EndChildren(); ++i) + ImportElementsRecurse(*i, new_re); + } +} + +//______________________________________________________________________________ +void TEveProjectionManager::ImportElements(TEveElement* rnr_el) +{ + // Recursively import elements and update projection on the projected objects. + + ImportElementsRecurse(rnr_el, this); + ProjectChildren(); +} + +//______________________________________________________________________________ +void TEveProjectionManager::ProjectChildrenRecurse(TEveElement* rnr_el) +{ + // Go recursively through rnr_el tree and call UpdateProjection() on TEveProjected. + + TEveProjected* pted = dynamic_cast(rnr_el); + if (pted) + { + pted->UpdateProjection(); + TAttBBox* bb = dynamic_cast(pted); + if(bb) + { + Float_t* b = bb->AssertBBox(); + BBoxCheckPoint(b[0], b[2], b[4]); + BBoxCheckPoint(b[1], b[3], b[5]); + } + rnr_el->ElementChanged(kFALSE); + } + + for (List_i i=rnr_el->BeginChildren(); i!=rnr_el->EndChildren(); ++i) + ProjectChildrenRecurse(*i); +} + +//______________________________________________________________________________ +void TEveProjectionManager::ProjectChildren() +{ + // Project children recursevly, update BBox and notify ReveManger + // the scenes have chenged. + + BBoxZero(); + ProjectChildrenRecurse(this); + AssertBBoxExtents(0.1); + { + using namespace TMath; + fBBox[0] = 10.0f * Floor(fBBox[0]/10.0f); + fBBox[1] = 10.0f * Ceil (fBBox[1]/10.0f); + fBBox[2] = 10.0f * Floor(fBBox[2]/10.0f); + fBBox[3] = 10.0f * Ceil (fBBox[3]/10.0f); + } + + List_t scenes; + CollectSceneParentsFromChildren(scenes, 0); + gEve->ScenesChanged(scenes); +} + +//______________________________________________________________________________ +void TEveProjectionManager::Paint(Option_t* /*option*/) +{ + // Paint this object. Only direct rendering is supported. + + static const TEveException eH("TEveProjectionManager::Paint "); + TBuffer3D buff(TBuffer3DTypes::kGeneric); + + // Section kCore + buff.fID = this; + buff.fColor = fAxisColor; + buff.fTransparency = 0; + buff.SetSectionsValid(TBuffer3D::kCore); + + Int_t reqSections = gPad->GetViewer3D()->AddObject(buff); + if (reqSections != TBuffer3D::kNone) + Error(eH, "only direct GL rendering supported."); +} + +//______________________________________________________________________________ +void TEveProjectionManager::ComputeBBox() +{ + // Virtual from TAttBBox; fill bounding-box information. + + static const TEveException eH("TEveProjectionManager::ComputeBBox "); + + if(GetNChildren() == 0) { + BBoxZero(); + return; + } + + BBoxInit(); +} diff --git a/eve/src/TEveProjectionManagerEditor.cxx b/eve/src/TEveProjectionManagerEditor.cxx new file mode 100644 index 0000000000..9f2587980d --- /dev/null +++ b/eve/src/TEveProjectionManagerEditor.cxx @@ -0,0 +1,335 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include + +#include + +#include +#include +#include +#include +#include +#include + +//______________________________________________________________________________ +// TEveProjectionManagerEditor +// +// GUI editor for TEveProjectionManager class. +// + +ClassImp(TEveProjectionManagerEditor) + +//______________________________________________________________________________ +TEveProjectionManagerEditor::TEveProjectionManagerEditor(const TGWindow *p, + Int_t width, Int_t height, + UInt_t options, Pixel_t back) : + TGedFrame(p, width, height, options | kVerticalFrame, back), + fM(0), + + fType(0), + fDistortion(0), + fFixedRadius(0), + fCurrentDepth(0), + + fCenterFrame(0), + fDrawCenter(0), + fCenterX(0), + fCenterY(0), + fCenterZ(0), + + fAxisColor(0), + fSIMode(0), + fSILevel(0) +{ + // Constructor. + + MakeTitle("TEveProjection"); + { + TGHorizontalFrame* f = new TGHorizontalFrame(this); + TGLabel* lab = new TGLabel(f, "Type"); + f->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsBottom, 1, 31, 1, 2)); + fType = new TGComboBox(f); + fType->AddEntry("CFishEye", TEveProjection::PT_CFishEye); + fType->AddEntry("RhoZ", TEveProjection::PT_RhoZ); + TGListBox* lb = fType->GetListBox(); + lb->Resize(lb->GetWidth(), 2*18); + fType->Resize(80, 20); + fType->Connect("Selected(Int_t)", "TEveProjectionManagerEditor", + this, "DoType(Int_t)"); + f->AddFrame(fType, new TGLayoutHints(kLHintsTop, 1, 1, 2, 4)); + AddFrame(f); + } + + Int_t labelW = 60; + fDistortion = new TEveGValuator(this, "Distortion:", 90, 0); + fDistortion->SetNELength(5); + fDistortion->SetLabelWidth(labelW); + fDistortion->Build(); + fDistortion->SetLimits(0, 50, 101, TGNumberFormat::kNESRealTwo); + fDistortion->Connect("ValueSet(Double_t)", "TEveProjectionManagerEditor", + this, "DoDistortion()"); + AddFrame(fDistortion, new TGLayoutHints(kLHintsTop, 1, 1, 1, 0)); + + + fFixedRadius = new TEveGValuator(this, "FixedR:", 90, 0); + fFixedRadius->SetNELength(5); + fFixedRadius->SetLabelWidth(labelW); + fFixedRadius->Build(); + fFixedRadius->SetLimits(0, 1000, 101, TGNumberFormat::kNESRealOne); + fFixedRadius->SetToolTip("Radius not scaled by distotion."); + fFixedRadius->Connect("ValueSet(Double_t)", "TEveProjectionManagerEditor", + this, "DoFixedRadius()"); + AddFrame(fFixedRadius, new TGLayoutHints(kLHintsTop, 1, 1, 1, 0)); + + + fCurrentDepth = new TEveGValuator(this, "CurrentZ:", 90, 0); + fCurrentDepth->SetNELength(5); + fCurrentDepth->SetLabelWidth(labelW); + fCurrentDepth->Build(); + fCurrentDepth->SetLimits(-300, 300, 601, TGNumberFormat::kNESRealOne); + fCurrentDepth->SetToolTip("Z coordinate of incoming projected object."); + fCurrentDepth->Connect("ValueSet(Double_t)", "TEveProjectionManagerEditor", + this, "DoCurrentDepth()"); + AddFrame(fCurrentDepth, new TGLayoutHints(kLHintsTop, 1, 1, 1, 0)); + + /**************************************************************************/ + MakeTitle("Axis"); + { + TGHorizontalFrame* hf1 = new TGHorizontalFrame(this); + + TGCompositeFrame *labfr = + new TGHorizontalFrame(hf1, 60, 15, kFixedSize); + TGLabel* l = new TGLabel(labfr, "Color"); + labfr->AddFrame(l, new TGLayoutHints(kLHintsLeft|kLHintsBottom)); + hf1->AddFrame(labfr, new TGLayoutHints(kLHintsLeft|kLHintsBottom)); + + + fAxisColor = new TGColorSelect(hf1, 0, -1); + hf1->AddFrame(fAxisColor, new TGLayoutHints(kLHintsLeft, 2, 0, 1, 1)); + fAxisColor->Connect + ("ColorSelected(Pixel_t)", + "TEveProjectionManagerEditor", this, "DoAxisColor(Pixel_t)"); + + AddFrame(hf1); + } + { + TGHorizontalFrame* f = new TGHorizontalFrame(this); + TGLabel* lab = new TGLabel(f, "StepMode"); + f->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsBottom, 1, 6, 1, 2)); + fSIMode = new TGComboBox(f, "Position"); + fSIMode->AddEntry("Value", 1); + fSIMode->AddEntry("Position", 0); + fSIMode->GetTextEntry()->SetToolTipText("Set tick-marks on equidistant values/screen position."); + TGListBox* lb = fSIMode->GetListBox(); + lb->Resize(lb->GetWidth(), 2*18); + fSIMode->Resize(80, 20); + fSIMode->Connect("Selected(Int_t)", "TEveProjectionManagerEditor", + this, "DoSplitInfoMode(Int_t)"); + f->AddFrame(fSIMode, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1)); + AddFrame(f); + } + { + TGHorizontalFrame* f = new TGHorizontalFrame(this); + TGLabel* lab = new TGLabel(f, "SplitLevel"); + f->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsBottom, 1, 8, 1, 2)); + + fSILevel = new TGNumberEntry(f, 0, 3, -1,TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, + TGNumberFormat::kNELLimitMinMax, 0, 7); + fSILevel->GetNumberEntry()->SetToolTipText("Number of tick-marks TMath::Power(2, level)."); + fSILevel->Connect("ValueSet(Long_t)", "TEveProjectionManagerEditor", this, "DoSplitInfoLevel()"); + f->AddFrame(fSILevel, new TGLayoutHints(kLHintsTop, 1, 1, 1, 2)); + AddFrame(f, new TGLayoutHints(kLHintsTop, 0, 0, 0, 3) ); + } + + /**************************************************************************/ + // center tab + fCenterFrame = CreateEditorTabSubFrame("Center"); + + TGCompositeFrame *title1 = new TGCompositeFrame(fCenterFrame, 180, 10, + kHorizontalFrame | + kLHintsExpandX | + kFixedWidth | + kOwnBackground); + title1->AddFrame(new TGLabel(title1, "Distortion Center"), + new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); + title1->AddFrame(new TGHorizontal3DLine(title1), + new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7)); + fCenterFrame->AddFrame(title1, new TGLayoutHints(kLHintsTop, 0, 0, 2, 0)); + + + { + + TGHorizontalFrame* hf1 = new TGHorizontalFrame(fCenterFrame); + + fDrawOrigin = new TGCheckButton(hf1, "DrawOrigin"); + hf1->AddFrame(fDrawOrigin, new TGLayoutHints(kLHintsLeft, 2,1,0,4)); + fDrawOrigin->Connect("Toggled(Bool_t)"," TEveProjectionManagerEditor", this, "DoDrawOrigin()"); + + + fDrawCenter = new TGCheckButton(hf1, "DrawCenter"); + hf1->AddFrame(fDrawCenter, new TGLayoutHints(kLHintsLeft, 2,1,0,4)); + fDrawCenter->Connect("Toggled(Bool_t)"," TEveProjectionManagerEditor", this, "DoDrawCenter()"); + + fCenterFrame->AddFrame(hf1, new TGLayoutHints(kLHintsTop, 0,0,0,0)); + + } + + Int_t nel = 8; + fCenterX = new TEveGValuator(fCenterFrame, "CenterX:", 90, 0); + fCenterX->SetNELength(nel); + fCenterX->SetLabelWidth(labelW); + fCenterX->Build(); + fCenterX->SetLimits(-5, 5, 501, TGNumberFormat::kNESRealThree); + fCenterX->SetToolTip("Origin of the projection."); + fCenterX->Connect("ValueSet(Double_t)", "TEveProjectionManagerEditor", + this, "DoCenter()"); + fCenterFrame->AddFrame(fCenterX, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1)); + + fCenterY = new TEveGValuator(fCenterFrame, "CenterY:", 90, 0); + fCenterY->SetNELength(nel); + fCenterY->SetLabelWidth(labelW); + fCenterY->Build(); + fCenterY->SetLimits(-5, 5, 501, TGNumberFormat::kNESRealThree); + fCenterY->SetToolTip("Origin of the projection."); + fCenterY->Connect("ValueSet(Double_t)", "TEveProjectionManagerEditor", + this, "DoCenter()"); + fCenterFrame->AddFrame(fCenterY, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1)); + + fCenterZ = new TEveGValuator(fCenterFrame, "CenterZ:", 90, 0); + fCenterZ->SetNELength(nel); + fCenterZ->SetLabelWidth(labelW); + fCenterZ->Build(); + fCenterZ->SetLimits(-25, 25, 501, TGNumberFormat::kNESRealThree); + fCenterZ->SetToolTip("Origin of the projection."); + fCenterZ->Connect("ValueSet(Double_t)", "TEveProjectionManagerEditor", + this, "DoCenter()"); + fCenterFrame->AddFrame(fCenterZ, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1)); +} + +//______________________________________________________________________________ +void TEveProjectionManagerEditor::SetModel(TObject* obj) +{ + // Set model object. + + fM = dynamic_cast(obj); + + fAxisColor->SetColor(TColor::Number2Pixel(fM->GetAxisColor()), kFALSE); + fSIMode->Select(fM->GetSplitInfoMode(), kFALSE); + fSILevel->SetNumber(fM->GetSplitInfoLevel()); + + fType->Select(fM->GetProjection()->GetType(), kFALSE); + fDistortion->SetValue(1000.0f * fM->GetProjection()->GetDistortion()); + fFixedRadius->SetValue(fM->GetProjection()->GetFixedRadius()); + fCurrentDepth->SetValue(fM->GetCurrentDepth()); + + fDrawCenter->SetState(fM->GetDrawCenter() ? kButtonDown : kButtonUp); + fDrawOrigin->SetState(fM->GetDrawOrigin() ? kButtonDown : kButtonUp); + fCenterX->SetValue(fM->GetCenter().x); + fCenterY->SetValue(fM->GetCenter().y); + fCenterZ->SetValue(fM->GetCenter().z); +} + +//______________________________________________________________________________ +void TEveProjectionManagerEditor::DoType(Int_t type) +{ + // Slot for setting of projection type. + + fM->SetProjection((TEveProjection::PType_e)type, 0.001f * fDistortion->GetValue()); + fM->ProjectChildren(); + Update(); +} + +//______________________________________________________________________________ +void TEveProjectionManagerEditor::DoDistortion() +{ + // Slot for setting distortion. + + fM->GetProjection()->SetDistortion(0.001f * fDistortion->GetValue()); + fM->UpdateName(); + fM->ProjectChildren(); + Update(); +} + +//______________________________________________________________________________ +void TEveProjectionManagerEditor::DoFixedRadius() +{ + // Slot for setting fixed radius. + + fM->GetProjection()->SetFixedRadius(fFixedRadius->GetValue()); + fM->ProjectChildren(); + Update(); +} + +//______________________________________________________________________________ +void TEveProjectionManagerEditor::DoCurrentDepth() +{ + // Slot for setting current depth. + + fM->SetCurrentDepth(fCurrentDepth->GetValue()); + fM->ProjectChildren(); + Update(); +} + +//______________________________________________________________________________ +void TEveProjectionManagerEditor::DoCenter() +{ + // Slot for setting center of distortion. + + fM->SetCenter(fCenterX->GetValue(), fCenterY->GetValue(), fCenterZ->GetValue()); + Update(); +} + +//______________________________________________________________________________ +void TEveProjectionManagerEditor::DoDrawOrigin() +{ + // Slot for setting draw of origin. + + fM->SetDrawOrigin(fDrawOrigin->IsOn()); + Update(); +} + +//______________________________________________________________________________ +void TEveProjectionManagerEditor::DoDrawCenter() +{ + // Slot for setting draw of center. + + fM->SetDrawCenter(fDrawCenter->IsOn()); + Update(); +} + +//______________________________________________________________________________ +void TEveProjectionManagerEditor::DoSplitInfoMode(Int_t type) +{ + // Slot for setting split info mode. + + fM->SetSplitInfoMode(type); + Update(); +} + +//______________________________________________________________________________ +void TEveProjectionManagerEditor::DoSplitInfoLevel() +{ + // Slot for setting tick-mark density. + + fM->SetSplitInfoLevel((Int_t)fSILevel->GetNumber()); + Update(); +} + +//______________________________________________________________________________ +void TEveProjectionManagerEditor::DoAxisColor(Pixel_t pixel) +{ + // Slot for setting axis color. + + fM->SetAxisColor(Color_t(TColor::GetColor(pixel))); + Update(); +} diff --git a/eve/src/TEveProjectionManagerGL.cxx b/eve/src/TEveProjectionManagerGL.cxx new file mode 100644 index 0000000000..b8a60d3a8f --- /dev/null +++ b/eve/src/TEveProjectionManagerGL.cxx @@ -0,0 +1,315 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include + +#include +#include +#include +#include + +#include + +//______________________________________________________________________________ +// TEveProjectionManagerGL +// +// GL-renderer for TEveProjectionManager. + +ClassImp(TEveProjectionManagerGL) + +//______________________________________________________________________________ +TEveProjectionManagerGL::TEveProjectionManagerGL() : + TGLObject(), + + fRange(300), + fLabelSize(0.02), + fLabelOff(0.018), + fTMSize(0.02), + + fM(0), + fText(0) +{ + fDLCache = kFALSE; // Disable display list. + fText = new TGLText(); + fText->SetGLTextFont(40); + fText->SetTextColor(0); +} + +//______________________________________________________________________________ +TEveProjectionManagerGL::~TEveProjectionManagerGL() +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +const char* TEveProjectionManagerGL::GetText(Float_t x) const +{ + using namespace TMath; + // TODO: Form could be replaced with own version of printf + if ( Abs(x) > 1000 ) + { + Float_t v = 10*TMath::Nint(x/10.0f); + return Form("%.0f", v); + } + else if( Abs(x) > 100 ) + { + Float_t v = TMath::Nint(x); + return Form("%.0f", v); + } + else if ( Abs(x) > 10 ) + { + return Form("%.1f", x); + } + else if ( Abs(x) > 1 ) + { + return Form("%.2f", x); + } + else + { + return Form("%.3f", x); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveProjectionManagerGL::SetRange(Float_t pos, Int_t ax) const +{ + using namespace TMath; + Float_t limit = fM->GetProjection()->GetLimit(ax, pos > 0 ? kTRUE: kFALSE); + // printf("TEveProjectionManagerGL::SetRange pos %f range %f \n", pos, limit ); + if ( fM->GetProjection()->GetDistortion() > 0.001 && Abs(pos) > Abs(limit *0.97)) + { + fPos.push_back(limit *0.7); + fVals.push_back(fM->GetProjection()->GetValForScreenPos(ax, fPos.back())); + // printf("bbox value out of limit:: val %f, pos %f\n", limit, fVals.back()); + } + else + { + fPos.push_back(pos); + fVals.push_back(fM->GetProjection()->GetValForScreenPos(ax, fPos.back())); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveProjectionManagerGL::DrawTickMarks(Float_t tm) const +{ + glBegin(GL_LINES); + for( std::list::iterator pi = fPos.begin(); pi!= fPos.end(); pi++) + { + glVertex3f(*pi, 0, 0.); + glVertex3f(*pi, tm, 0.); + } + glEnd(); +} + +//______________________________________________________________________________ +void TEveProjectionManagerGL::DrawHInfo() const +{ + Float_t tms = fTMSize*fRange; + DrawTickMarks(-tms); + + glPushMatrix(); + glRotatef(-90, 1, 0, 0); + glTranslatef(0, 0, -tms -fLabelOff*fRange); + const char* txt; + Float_t llx, lly, llz, urx, ury, urz; + std::list::iterator vi = fVals.begin(); + for( std::list::iterator pi = fPos.begin(); pi!= fPos.end(); pi++) + { + txt = GetText(*vi); + fText->BBox(txt, llx, lly, llz, urx, ury, urz); + fText->PaintGLText(*pi -(urx-llx)*fText->GetTextSize()*0.5, 0, 0, txt); + vi++; + } + glPopMatrix(); + + fPos.clear(); fVals.clear(); +} + +//______________________________________________________________________________ +void TEveProjectionManagerGL::DrawVInfo() const +{ + Float_t tms = fTMSize*fRange; + glRotatef(90, 0, 0, 1); + DrawTickMarks(tms); + glRotatef(-90, 0, 0, 1); + + glPushMatrix(); + glRotatef(-90, 1, 0, 0); + glTranslatef(-fLabelOff*fRange -tms, 0, 0); + const char* txt; + Float_t llx, lly, llz, urx, ury, urz; + std::list::iterator vi = fVals.begin(); + for( std::list::iterator pi = fPos.begin(); pi!= fPos.end(); pi++) + { + txt= GetText(*vi); + fText->BBox(txt, llx, lly, llz, urx, ury, urz); + fText->PaintGLText(-(urx-llx)*fText->GetTextSize(), 0, *pi - (ury - lly)*fText->GetTextSize()*0.5, txt); + vi++; + } + glPopMatrix(); + + fPos.clear(); fVals.clear(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveProjectionManagerGL::SplitInterval(Int_t ax) const +{ + if (fM->GetSplitInfoLevel()) + { + if(fM->GetSplitInfoMode()) + SplitIntervalByVal(fVals.front(), fVals.back(), ax, 0); + else + SplitIntervalByPos(fPos.front(), fPos.back(), ax, 0); + } +} + +//______________________________________________________________________________ +void TEveProjectionManagerGL::SplitIntervalByPos(Float_t minp, Float_t maxp, Int_t ax, Int_t level) const +{ + Float_t p = (minp+maxp)*0.5; + fPos.push_back(p); + Float_t v = fM->GetProjection()->GetValForScreenPos(ax, p); + fVals.push_back(v); + // printf("level %d position %f value %f\n", level, p,v); + level++; + if(levelGetSplitInfoLevel()) + { + SplitIntervalByPos(minp, p , ax, level); + SplitIntervalByPos(p, maxp, ax, level); + } +} + +//______________________________________________________________________________ +void TEveProjectionManagerGL::SplitIntervalByVal(Float_t minv, Float_t maxv, Int_t ax, Int_t level) const +{ + Float_t v = (minv+maxv)*0.5; + fVals.push_back(v); + Float_t p = fM->GetProjection()->GetScreenVal(ax, v); + fPos.push_back(p); + //printf("level %d position %f value %f MINMAX val(%f, %f)\n", level, p,v, minv, maxv); + level++; + if(levelGetSplitInfoLevel()) + { + SplitIntervalByVal(minv, v , ax, level); + SplitIntervalByVal(v, maxv, ax, level); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveProjectionManagerGL::DirectDraw(TGLRnrCtx & /*rnrCtx*/) const +{ + // printf("TEveProjectionManagerGL::DirectDraw %d\n.", fM->GetMainColor()); + GLboolean lightp; + glGetBooleanv(GL_LIGHTING, &lightp); + if (lightp) glDisable(GL_LIGHTING); + + Float_t* bbox = fM->GetBBox(); + fRange = bbox[1] - bbox[0]; + // printf("bbox %f, %f\n", bbox[0], bbox[1]); + TEveVector zeroPos; + fM->GetProjection()->ProjectVector(zeroPos); + fText->SetTextSize(fLabelSize*fRange); + fText->SetTextColor(fM->GetAxisColor()); + + { // horizontal + glPushMatrix(); + glTranslatef(0, bbox[2], 0); + // left + SetRange(bbox[0], 0); + fPos.push_back(zeroPos.x); fVals.push_back(0); + SplitInterval(0); + DrawHInfo(); + // right + fPos.push_back(zeroPos.x); fVals.push_back(0); + SetRange(bbox[1], 0); + SplitInterval(0); fVals.pop_front(); fPos.pop_front(); + DrawHInfo(); + glPopMatrix(); + } + { // vertical + glPushMatrix(); + glTranslatef(bbox[0], 0, 0); + // bottom + fPos.push_back(zeroPos.y);fVals.push_back(0); + SetRange(bbox[2], 1); + SplitInterval(1); + DrawVInfo(); + // top + fPos.push_back(zeroPos.y); fVals.push_back(0); + SetRange(bbox[3], 1); + SplitInterval(1);fPos.pop_front(); fVals.pop_front(); + DrawVInfo(); + glPopMatrix(); + } + + // body + glBegin(GL_LINES); + glVertex3f(bbox[0], bbox[2], 0.); + glVertex3f(bbox[1], bbox[2], 0.); + glVertex3f(bbox[0], bbox[2], 0.); + glVertex3f(bbox[0], bbox[3], 0.); + glEnd(); + + Float_t d = 10; + if(fM->GetDrawCenter()) + { + Float_t* c = fM->GetProjection()->GetProjectedCenter(); + glColor3f(1., 0., 0.); + glBegin(GL_LINES); + glVertex3f(c[0] +d, c[1], c[2]); glVertex3f(c[0] - d, c[1] , c[2]); + glVertex3f(c[0] , c[1] +d, c[2]); glVertex3f(c[0] , c[1] -d, c[2]); + glVertex3f(c[0] , c[1], c[2] + d); glVertex3f(c[0] , c[1] , c[2] - d); + glEnd(); + + } + + if(fM->GetDrawOrigin()) + { + TEveVector zero; + fM->GetProjection()->ProjectVector(zero); + glColor3f(1., 1., 1.); + glBegin(GL_LINES); + glVertex3f(zero[0] +d, zero[1], zero[2]); glVertex3f(zero[0] - d, zero[1] , zero[2]); + glVertex3f(zero[0] , zero[1] +d, zero[2]); glVertex3f(zero[0] , zero[1] -d, zero[2]); + glVertex3f(zero[0] , zero[1], zero[2] + d); glVertex3f(zero[0] , zero[1] , zero[2] - d); + glEnd(); + } + if (lightp) glEnable(GL_LIGHTING); +} + + +/******************************************************************************/ + +//______________________________________________________________________________ +Bool_t TEveProjectionManagerGL::SetModel(TObject* obj, const Option_t* /*opt*/) +{ + if(SetModelCheckClass(obj, TEveProjectionManager::Class())) { + fM = dynamic_cast(obj); + return kTRUE; + } + return kFALSE; +} + +//______________________________________________________________________________ +void TEveProjectionManagerGL::SetBBox() +{ + // !! This ok if master sub-classed from TAttBBox + SetAxisAlignedBBox(((TEveProjectionManager*)fExternalObj)->AssertBBox()); +} diff --git a/eve/src/TEveProjections.cxx b/eve/src/TEveProjections.cxx new file mode 100644 index 0000000000..8d5a88e5c1 --- /dev/null +++ b/eve/src/TEveProjections.cxx @@ -0,0 +1,278 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include + +//______________________________________________________________________________ +// TEveProjection +// +// Base-class for non-linear projections. +// +// Enables to define an external center of distortion and a scale to +// fixate a bounding box of a projected point. + +ClassImp(TEveProjection) + +Float_t TEveProjection::fgEps = 0.005f; + +//______________________________________________________________________________ +TEveProjection::TEveProjection(TEveVector& center) : + fType(PT_Unknown), + fGeoMode(GM_Unknown), + fName(0), + fCenter(center.x, center.y, center.z), + fDistortion(0.0f), + fFixedRadius(300), + fScale(1.0f) +{ + // Constructor. +} + +//______________________________________________________________________________ +void TEveProjection::ProjectVector(TEveVector& v) +{ + // Project TEveVector. + + ProjectPoint(v.x, v.y, v.z); +} + +//______________________________________________________________________________ +void TEveProjection::UpdateLimit() +{ + // Update convergence in +inf and -inf. + + if ( fDistortion == 0.0f ) + return; + + Float_t lim = 1.0f/fDistortion + fFixedRadius; + Float_t* c = GetProjectedCenter(); + fUpLimit.Set(lim + c[0], lim + c[1], c[2]); + fLowLimit.Set(-lim + c[0], -lim + c[1], c[2]); +} + +//______________________________________________________________________________ +void TEveProjection::SetDistortion(Float_t d) +{ + // Set distortion. + + fDistortion=d; + fScale = 1+fFixedRadius*fDistortion; + UpdateLimit(); +} + +//______________________________________________________________________________ +void TEveProjection::SetFixedRadius(Float_t r) +{ + // Set fixed radius. + + fFixedRadius=r; + fScale = 1 + fFixedRadius*fDistortion; + UpdateLimit(); +} + +//______________________________________________________________________________ +void TEveProjection::SetDirectionalVector(Int_t screenAxis, TEveVector& vec) +{ + // Get vector for axis in a projected space. + + for (Int_t i=0; i<3; i++) + { + vec[i] = (i==screenAxis) ? 1. : 0.; + } +} + +//______________________________________________________________________________ +Float_t TEveProjection::GetValForScreenPos(Int_t i, Float_t sv) +{ + // Inverse projection. + + static const TEveException eH("TEveProjection::GetValForScreenPos "); + + Float_t xL, xM, xR; + TEveVector V, DirVec; + SetDirectionalVector(i, DirVec); + if (fDistortion > 0.0f && ((sv > 0 && sv > fUpLimit[i]) || (sv < 0 && sv < fLowLimit[i]))) + throw(eH + Form("screen value '%f' out of limit '%f'.", sv, sv > 0 ? fUpLimit[i] : fLowLimit[i])); + + TEveVector zero; ProjectVector(zero); + // search from -/+ infinity according to sign of screen value + if (sv > zero[i]) + { + xL = 0; xR = 1000; + while (1) + { + V.Mult(DirVec, xR); ProjectVector(V); + // printf("positive projected %f, value %f,xL, xR ( %f, %f)\n", V[i], sv, xL, xR); + if (V[i] > sv || V[i] == sv) break; + xL = xR; xR *= 2; + } + } + else if (sv < zero[i]) + { + xR = 0; xL = -1000; + while (1) + { + V.Mult(DirVec, xL); ProjectVector(V); + // printf("negative projected %f, value %f,xL, xR ( %f, %f)\n", V[i], sv, xL, xR); + if (V[i] < sv || V[i] == sv) break; + xR = xL; xL *= 2; + } + } + else + { + return 0.0f; + } + + do + { + xM = 0.5f * (xL + xR); + V.Mult(DirVec, xM); + ProjectVector(V); + if (V[i] > sv) + xR = xM; + else + xL = xM; + } while(TMath::Abs(V[i] - sv) >= fgEps); + + return xM; +} + +//______________________________________________________________________________ +Float_t TEveProjection::GetScreenVal(Int_t i, Float_t x) +{ + // Project point on given axis and return projected value. + + TEveVector dv; + SetDirectionalVector(i, dv); dv = dv*x; + ProjectVector(dv); + return dv[i]; +} + + +//______________________________________________________________________________ +// TEveRhoZProjection +// +// Transformation from 3D to 2D. X axis represent Z coordinate. Y axis have value of +// radius with a sign of Y coordinate. + +ClassImp(TEveRhoZProjection) + +//______________________________________________________________________________ +void TEveRhoZProjection::SetCenter(TEveVector& v) +{ + // Set center of distortion (virtual method). + + fCenter = v; + + Float_t R = TMath::Sqrt(v.x*v.x+v.y*v.y); + fProjectedCenter.x = fCenter.z; + fProjectedCenter.y = TMath::Sign(R, fCenter.y); + fProjectedCenter.z = 0; + UpdateLimit(); +} + +//______________________________________________________________________________ +void TEveRhoZProjection::ProjectPoint(Float_t& x, Float_t& y, Float_t& z, PProc_e proc ) +{ + // Project point. + + using namespace TMath; + + if(proc == PP_Plane || proc == PP_Full) + { + // project + y = Sign((Float_t)Sqrt(x*x+y*y), y); + x = z; + } + if(proc == PP_Distort || proc == PP_Full) + { + // move to center + x -= fProjectedCenter.x; + y -= fProjectedCenter.y; + // distort + y = (y*fScale) / (1.0f + Abs(y)*fDistortion); + x = (x*fScale) / (1.0f + Abs(x)*fDistortion); + // move back from center + x += fProjectedCenter.x; + y += fProjectedCenter.y; + } + z = 0.0f; +} + +//______________________________________________________________________________ +void TEveRhoZProjection::SetDirectionalVector(Int_t screenAxis, TEveVector& vec) +{ + // Get direction in the unprojected space for axis index in the projected space. + // This is virtual method from base-class TEveProjection. + + if(screenAxis == 0) + vec.Set(0., 0., 1); + else if (screenAxis == 1) + vec.Set(0., 1., 0); + +} +//______________________________________________________________________________ +Bool_t TEveRhoZProjection::AcceptSegment(TEveVector& v1, TEveVector& v2, Float_t tolerance) +{ + // Check if segment of two projected points is valid. + + Float_t a = fProjectedCenter.y; + Bool_t val = kTRUE; + if((v1.y < a && v2.y > a) || (v1.y > a && v2.y < a)) + { + val = kFALSE; + if (tolerance > 0) + { + Float_t a1 = TMath::Abs(v1.y - a), a2 = TMath::Abs(v2.y - a); + if (a1 < a2) + { + if (a1 < tolerance) { v1.y = a; val = kTRUE; } + } + else + { + if (a2 < tolerance) { v2.y = a; val = kTRUE; } + } + } + } + return val; +} + + +//______________________________________________________________________________ +// TEveCircularFishEyeProjection +// +// XY projection with distortion around given center. + +ClassImp(TEveCircularFishEyeProjection) + +//______________________________________________________________________________ +void TEveCircularFishEyeProjection::ProjectPoint(Float_t& x, Float_t& y, Float_t& z, + PProc_e proc) +{ + // Project point. + + using namespace TMath; + + if (proc != PP_Plane) + { + x -= fCenter.x; + y -= fCenter.y; + Float_t phi = x == 0.0 && y == 0.0 ? 0.0 : ATan2(y,x); + Float_t R = Sqrt(x*x+y*y); + // distort + Float_t NR = (R*fScale) / (1.0f + R*fDistortion); + x = NR*Cos(phi) + fCenter.x; + y = NR*Sin(phi) + fCenter.y; + } + z = 0.0f; +} + diff --git a/eve/src/TEveQuadSet.cxx b/eve/src/TEveQuadSet.cxx new file mode 100644 index 0000000000..787f04aa74 --- /dev/null +++ b/eve/src/TEveQuadSet.cxx @@ -0,0 +1,473 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 + +#include + +#include + +#include +#include +#include +#include + +#include +#include + +//______________________________________________________________________________ +// TEveQuadSet +// +// Supports various internal formats that result in rendering of a +// set of planar (lines, rectangles, hegagons with shared normal) objects. +// +// Names of internal structures and their variables use A, B and C as +// names for coordinate value-holders. Typical assignment is A->X, +// B->Y, C->Z but each render mode can override this convention and +// impose y or x as a fixed (third or C) coordinate. Alphabetic order +// is obeyed in this correspondence. +// +// For quad modes the deltas are expected to be positive. +// For line modes negative deltas are ok. + +ClassImp(TEveQuadSet) + +//______________________________________________________________________________ +TEveQuadSet::TEveQuadSet(const Text_t* n, const Text_t* t) : + TEveDigitSet (n, t), + + fQuadType (QT_Undef), + fDefWidth (1), + fDefHeight (1), + fDefCoord (0) +{} + +//______________________________________________________________________________ +TEveQuadSet::TEveQuadSet(QuadType_e quadType, Bool_t valIsCol, Int_t chunkSize, + const Text_t* n, const Text_t* t) : + TEveDigitSet (n, t), + + fQuadType (QT_Undef), + fDefWidth (1), + fDefHeight (1), + fDefCoord (0) +{ + Reset(quadType, valIsCol, chunkSize); +} + +//______________________________________________________________________________ +TEveQuadSet::~TEveQuadSet() +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +Int_t TEveQuadSet::SizeofAtom(TEveQuadSet::QuadType_e qt) +{ + static const TEveException eH("TEveQuadSet::SizeofAtom "); + + switch (qt) { + case QT_Undef: return 0; + case QT_FreeQuad: return sizeof(QFreeQuad); + case QT_RectangleXY: + case QT_RectangleXZ: + case QT_RectangleYZ: return sizeof(QRect); + case QT_RectangleXYFixedDim: return sizeof(QRectFixDim); + case QT_RectangleXYFixedZ: + case QT_RectangleXZFixedY: + case QT_RectangleYZFixedX: return sizeof(QRectFixC); + case QT_RectangleXYFixedDimZ: + case QT_RectangleXZFixedDimY: + case QT_RectangleYZFixedDimX: return sizeof(QRectFixDimC); + case QT_LineXZFixedY: + case QT_LineXYFixedZ: return sizeof(QLineFixC); + case QT_HexagonXY: + case QT_HexagonYX: return sizeof(QHex); + default: throw(eH + "unexpected atom type."); + } + return 0; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveQuadSet::Reset(TEveQuadSet::QuadType_e quadType, Bool_t valIsCol, Int_t chunkSize) +{ + fQuadType = quadType; + fValueIsColor = valIsCol; + fDefaultValue = valIsCol ? 0 : kMinInt; + if (fOwnIds) + ReleaseIds(); + fPlex.Reset(SizeofAtom(fQuadType), chunkSize); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveQuadSet::AddQuad(Float_t* verts) +{ + static const TEveException eH("TEveQuadSet::AddQuad "); + + if (fQuadType != QT_FreeQuad) + throw(eH + "expect free quad-type."); + + QFreeQuad* fq = (QFreeQuad*) NewDigit(); + memcpy(fq->fVertices, verts, sizeof(fq->fVertices)); +} + +//______________________________________________________________________________ +void TEveQuadSet::AddQuad(Float_t a, Float_t b) +{ + AddQuad(a, b, fDefCoord, fDefWidth, fDefHeight); +} + +//______________________________________________________________________________ +void TEveQuadSet::AddQuad(Float_t a, Float_t b, Float_t c) +{ + AddQuad(a, b, c, fDefWidth, fDefHeight); +} + +//______________________________________________________________________________ +void TEveQuadSet::AddQuad(Float_t a, Float_t b, Float_t w, Float_t h) +{ + AddQuad(a, b, fDefCoord, w, h); +} + +//______________________________________________________________________________ +void TEveQuadSet::AddQuad(Float_t a, Float_t b, Float_t c, Float_t w, Float_t h) +{ + static const TEveException eH("TEveQuadSet::AddAAQuad "); + + QOrigin& fq = * (QOrigin*) NewDigit(); + fq.fA = a; fq.fB = b; + switch (fQuadType) + { + case QT_RectangleXY: + case QT_RectangleXZ: + case QT_RectangleYZ: + { + QRect& q = (QRect&) fq; + q.fC = c; q.fW = w; q.fH = h; + break; + } + + case QT_RectangleXYFixedDim: + { + QRectFixDim& q = (QRectFixDim&) fq; + q.fC = c; + break; + } + + case QT_RectangleXYFixedZ: + case QT_RectangleXZFixedY: + case QT_RectangleYZFixedX: + { + QRectFixC& q = (QRectFixC&) fq; + q.fW = w; q.fH = h; + break; + } + + case QT_RectangleXYFixedDimZ: + case QT_RectangleXZFixedDimY: + case QT_RectangleYZFixedDimX: + { + break; + } + + default: + throw(eH + "expect axis-aligned quad-type."); + } +} + +//______________________________________________________________________________ +void TEveQuadSet::AddLine(Float_t a, Float_t b, Float_t w, Float_t h) +{ + static const TEveException eH("TEveQuadSet::AddLine "); + + QOrigin& fq = * (QOrigin*) NewDigit(); + fq.fA = a; fq.fB = b; + switch (fQuadType) + { + case QT_LineXZFixedY: + case QT_LineXYFixedZ: { + QLineFixC& q = (QLineFixC&) fq; + q.fDx = w; q.fDy = h; + break; + } + default: + throw(eH + "expect line quad-type."); + } +} + +//______________________________________________________________________________ +void TEveQuadSet::AddHexagon(Float_t a, Float_t b, Float_t c, Float_t r) +{ + static const TEveException eH("TEveQuadSet::AddHexagon "); + + QOrigin& fq = * (QOrigin*) NewDigit(); + fq.fA = a; fq.fB = b; + switch (fQuadType) + { + case QT_HexagonXY: + case QT_HexagonYX: { + QHex& q = (QHex&) fq; + q.fC = c; q.fR = r; + break; + } + default: + throw(eH + "expect line quad-type."); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveQuadSet::ComputeBBox() +{ + // Fill bounding-box information of the base-class TAttBBox (virtual method). + // If member 'TEveFrameBox* fFrame' is set, frame's corners are used as bbox. + + static const TEveException eH("TEveQuadSet::ComputeBBox "); + + if (fFrame != 0) + { + BBoxInit(); + Int_t n = fFrame->GetFrameSize() / 3; + Float_t *bbps = fFrame->GetFramePoints(); + for (int i=0; ifVertices; + BBoxCheckPoint(p); p += 3; + BBoxCheckPoint(p); p += 3; + BBoxCheckPoint(p); p += 3; + BBoxCheckPoint(p); + } + break; + } + + case QT_RectangleXY: + { + while (qi.next()) { + QRect& q = * (QRect*) qi(); + if(q.fA < fBBox[0]) fBBox[0] = q.fA; + if(q.fA + q.fW > fBBox[1]) fBBox[1] = q.fA + q.fW; + if(q.fB < fBBox[2]) fBBox[2] = q.fB; + if(q.fB + q.fH > fBBox[3]) fBBox[3] = q.fB + q.fH; + if(q.fC < fBBox[4]) fBBox[4] = q.fC; + if(q.fC > fBBox[5]) fBBox[5] = q.fC; + } + break; + } + + case QT_RectangleXZ: + { + while (qi.next()) { + QRect& q = * (QRect*) qi(); + if(q.fA < fBBox[0]) fBBox[0] = q.fA; + if(q.fA + q.fW > fBBox[1]) fBBox[1] = q.fA + q.fW; + if(q.fB < fBBox[4]) fBBox[4] = q.fB; + if(q.fB + q.fH > fBBox[5]) fBBox[5] = q.fB + q.fH; + if(q.fC < fBBox[2]) fBBox[2] = q.fC; + if(q.fC > fBBox[3]) fBBox[3] = q.fC; + } + break; + } + + case QT_RectangleYZ: + { + while (qi.next()) { + QRect& q = * (QRect*) qi(); + if(q.fA < fBBox[2]) fBBox[2] = q.fA; + if(q.fA + q.fW > fBBox[3]) fBBox[3] = q.fA + q.fW; + if(q.fB < fBBox[4]) fBBox[4] = q.fB; + if(q.fB + q.fH > fBBox[5]) fBBox[5] = q.fB + q.fH; + if(q.fC < fBBox[0]) fBBox[0] = q.fC; + if(q.fC > fBBox[1]) fBBox[1] = q.fC; + } + break; + } + + case QT_RectangleXYFixedDim: + { + const Float_t& w = fDefWidth; + const Float_t& h = fDefHeight; + while (qi.next()) { + QRectFixDim& q = * (QRectFixDim*) qi(); + if(q.fA < fBBox[0]) fBBox[0] = q.fA; + if(q.fA + w > fBBox[1]) fBBox[1] = q.fA + w; + if(q.fB < fBBox[2]) fBBox[2] = q.fB; + if(q.fB + h > fBBox[3]) fBBox[3] = q.fB + h; + if(q.fC < fBBox[4]) fBBox[4] = q.fC; + if(q.fC > fBBox[5]) fBBox[5] = q.fC; + } + break; + } + + case QT_RectangleXYFixedZ: + { + while (qi.next()) { + QRectFixC& q = * (QRectFixC*) qi(); + if(q.fA < fBBox[0]) fBBox[0] = q.fA; + if(q.fA + q.fW > fBBox[1]) fBBox[1] = q.fA + q.fW; + if(q.fB < fBBox[2]) fBBox[2] = q.fB; + if(q.fB + q.fH > fBBox[3]) fBBox[3] = q.fB + q.fH; + } + break; + } + + case QT_RectangleXZFixedY: + { + while (qi.next()) { + QRectFixC& q = * (QRectFixC*) qi(); + if(q.fA < fBBox[0]) fBBox[0] = q.fA; + if(q.fA + q.fW > fBBox[1]) fBBox[1] = q.fA + q.fW; + if(q.fB < fBBox[4]) fBBox[4] = q.fB; + if(q.fB + q.fH > fBBox[5]) fBBox[5] = q.fB + q.fH; + } + break; + } + + case QT_RectangleYZFixedX: + { + while (qi.next()) { + QRectFixC& q = * (QRectFixC*) qi(); + if(q.fA < fBBox[2]) fBBox[2] = q.fA; + if(q.fA + q.fW > fBBox[3]) fBBox[3] = q.fA + q.fW; + if(q.fB < fBBox[4]) fBBox[4] = q.fB; + if(q.fB + q.fH > fBBox[5]) fBBox[5] = q.fB + q.fH; + } + break; + } + + case QT_RectangleXYFixedDimZ: + { + const Float_t& w = fDefWidth; + const Float_t& h = fDefHeight; + while (qi.next()) { + QRectFixDimC& q = * (QRectFixDimC*) qi(); + if(q.fA < fBBox[0]) fBBox[0] = q.fA; + if(q.fA + w > fBBox[1]) fBBox[1] = q.fA + w; + if(q.fB < fBBox[2]) fBBox[2] = q.fB; + if(q.fB + h > fBBox[3]) fBBox[3] = q.fB + h; + } + break; + } + + case QT_RectangleXZFixedDimY: + { + const Float_t& w = fDefWidth; + const Float_t& h = fDefHeight; + while (qi.next()) { + QRectFixDimC& q = * (QRectFixDimC*) qi(); + if(q.fA < fBBox[0]) fBBox[0] = q.fA; + if(q.fA + w > fBBox[1]) fBBox[1] = q.fA + w; + if(q.fB < fBBox[4]) fBBox[4] = q.fB; + if(q.fB + h > fBBox[5]) fBBox[5] = q.fB + h; + } + break; + } + + case QT_RectangleYZFixedDimX: + { + const Float_t& w = fDefWidth; + const Float_t& h = fDefHeight; + while (qi.next()) { + QRectFixDimC& q = * (QRectFixDimC*) qi(); + if(q.fA < fBBox[2]) fBBox[2] = q.fA; + if(q.fA + w > fBBox[3]) fBBox[3] = q.fA + w; + if(q.fB < fBBox[4]) fBBox[4] = q.fB; + if(q.fB + h > fBBox[5]) fBBox[5] = q.fB + h; + } + break; + } + + // TEveLine modes + + case QT_LineXYFixedZ: + { + while (qi.next()) { + QLineFixC& q = * (QLineFixC*) qi(); + BBoxCheckPoint(q.fA, q.fB, fDefCoord); + BBoxCheckPoint(q.fA + q.fDx, q.fB + q.fDy, fDefCoord); + } + break; + } + + case QT_LineXZFixedY: + { + while (qi.next()) { + QLineFixC& q = * (QLineFixC*) qi(); + BBoxCheckPoint(q.fA, fDefCoord, q.fB); + BBoxCheckPoint(q.fA + q.fDx, fDefCoord, q.fB + q.fDy); + } + break; + } + + // Hexagon modes + + // Ignore 'slight' difference, assume square box for both cases. + case QT_HexagonXY: + case QT_HexagonYX: + { + while (qi.next()) { + QHex& q = * (QHex*) qi(); + BBoxCheckPoint(q.fA-q.fR, q.fB-q.fR, q.fC); + BBoxCheckPoint(q.fA+q.fR, q.fB+q.fR, q.fC); + } + break; + } + + default: + { + throw(eH + "unsupported quad-type."); + } + + } // end switch quad-type + } // end if frame ... else ... + + AssertBBoxExtents(0.001); +} diff --git a/eve/src/TEveQuadSetGL.cxx b/eve/src/TEveQuadSetGL.cxx new file mode 100644 index 0000000000..0606a346d7 --- /dev/null +++ b/eve/src/TEveQuadSetGL.cxx @@ -0,0 +1,521 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 + +#include +#include + +#include +#include +#include + +//______________________________________________________________________________ +// TEveQuadSetGL +// +// GL-renderer for TEveQuadSet class. + +ClassImp(TEveQuadSetGL) + +/******************************************************************************/ + +TEveQuadSetGL::TEveQuadSetGL() : TGLObject(), fM(0) +{ + // fDLCache = false; // Disable DL. +} + +//______________________________________________________________________________ +TEveQuadSetGL::~TEveQuadSetGL() +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +Bool_t TEveQuadSetGL::ShouldDLCache(const TGLRnrCtx & rnrCtx) const +{ + if (rnrCtx.DrawPass() == TGLRnrCtx::kPassOutlineLine) + return kFALSE; + return TGLObject::ShouldDLCache(rnrCtx); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +Bool_t TEveQuadSetGL::SetModel(TObject* obj, const Option_t* /*opt*/) +{ + Bool_t ok = SetModelCheckClass(obj, TEveQuadSet::Class()); + fM = ok ? dynamic_cast(obj) : 0; + return ok; +} + +//______________________________________________________________________________ +void TEveQuadSetGL::SetBBox() +{ + SetAxisAlignedBBox(fM->AssertBBox()); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +inline Bool_t TEveQuadSetGL::SetupColor(const TEveDigitSet::DigitBase& q) const +{ + if (fM->fValueIsColor) + { + glColor4ubv((UChar_t*) & q.fValue); + return kTRUE; + } + else + { + UChar_t c[4]; + Bool_t visible = fM->fPalette->ColorFromValue(q.fValue, fM->fDefaultValue, c); + if (visible) + glColor4ubv(c); + return visible; + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveQuadSetGL::DirectDraw(TGLRnrCtx & rnrCtx) const +{ + static const TEveException eH("TEveQuadSetGL::DirectDraw "); + + // printf("QuadSetGLRenderer::DirectDraw Style %d, LOD %d\n", rnrCtx.Style(), rnrCtx.LOD()); + + if (rnrCtx.DrawPass() == TGLRnrCtx::kPassOutlineLine) + return; + + TEveQuadSet& mQ = * fM; + + if (mQ.fFrame != 0 && ! rnrCtx.SecSelection()) + TEveFrameBoxGL::Render(mQ.fFrame); + + if (mQ.fPlex.Size() == 0) + return; + if ( ! mQ.fValueIsColor && mQ.fPalette == 0) + { + mQ.AssertPalette(); + } + + glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + glDisable(GL_CULL_FACE); + + if (mQ.fRenderMode == TEveDigitSet::RM_Fill) + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + else if (mQ.fRenderMode == TEveDigitSet::RM_TEveLine) + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + if (mQ.fDisableLigting) glDisable(GL_LIGHTING); + + if (mQ.fQuadType < TEveQuadSet::QT_Rectangle_End) RenderQuads(rnrCtx); + else if (mQ.fQuadType < TEveQuadSet::QT_Line_End) RenderLines(rnrCtx); + else if (mQ.fQuadType < TEveQuadSet::QT_Hexagon_End) RenderHexagons(rnrCtx); + + glPopAttrib(); + +} + +//______________________________________________________________________________ +void TEveQuadSetGL::RenderQuads(TGLRnrCtx & rnrCtx) const +{ + static const TEveException eH("TEveQuadSetGL::RenderQuads "); + + TEveQuadSet& mQ = * fM; + + GLenum primitiveType; + if (mQ.fRenderMode != TEveDigitSet::RM_TEveLine) + { + primitiveType = GL_QUADS; + if (mQ.fQuadType == TEveQuadSet::QT_FreeQuad) + glEnable(GL_NORMALIZE); + else + glNormal3f(0, 0, 1); + } else { + primitiveType = GL_LINE_LOOP; + } + + TEveChunkManager::iterator qi(mQ.fPlex); + + if (rnrCtx.SecSelection()) glPushName(0); + + switch (mQ.fQuadType) + { + + case TEveQuadSet::QT_FreeQuad: + { + Float_t e1[3], e2[3], normal[3]; + while (qi.next()) { + TEveQuadSet::QFreeQuad& q = * (TEveQuadSet::QFreeQuad*) qi(); + if (SetupColor(q)) + { + Float_t* p = q.fVertices; + e1[0] = p[3] - p[0]; e1[1] = p[4] - p[1]; e1[2] = p[5] - p[2]; + e2[0] = p[6] - p[0]; e2[1] = p[7] - p[1]; e2[2] = p[8] - p[2]; + TMath::Cross(e1, e2, normal); + if (rnrCtx.SecSelection()) glLoadName(qi.index()); + glBegin(primitiveType); + glNormal3fv(normal); + glVertex3fv(p); + glVertex3fv(p + 3); + glVertex3fv(p + 6); + glVertex3fv(p + 9); + glEnd(); + } + } + break; + } + + case TEveQuadSet::QT_RectangleXY: + { + while (qi.next()) { + TEveQuadSet::QRect& q = * (TEveQuadSet::QRect*) qi(); + if (SetupColor(q)) + { + if (rnrCtx.SecSelection()) glLoadName(qi.index()); + glBegin(primitiveType); + glVertex3f(q.fA, q.fB, q.fC); + glVertex3f(q.fA + q.fW, q.fB, q.fC); + glVertex3f(q.fA + q.fW, q.fB + q.fH, q.fC); + glVertex3f(q.fA, q.fB + q.fH, q.fC); + glEnd(); + } + } + break; + } + + case TEveQuadSet::QT_RectangleXZ: + { + while (qi.next()) { + TEveQuadSet::QRect& q = * (TEveQuadSet::QRect*) qi(); + if (SetupColor(q)) + { + if (rnrCtx.SecSelection()) glLoadName(qi.index()); + glBegin(primitiveType); + glVertex3f(q.fA, q.fC, q.fB); + glVertex3f(q.fA + q.fW, q.fC, q.fB); + glVertex3f(q.fA + q.fW, q.fC, q.fB + q.fH); + glVertex3f(q.fA, q.fC, q.fB + q.fH); + glEnd(); + } + } + break; + } + + case TEveQuadSet::QT_RectangleYZ: + { + while (qi.next()) { + TEveQuadSet::QRect& q = * (TEveQuadSet::QRect*) qi(); + if (SetupColor(q)) + { + if (rnrCtx.SecSelection()) glLoadName(qi.index()); + glBegin(primitiveType); + glVertex3f(q.fC, q.fA, q.fB); + glVertex3f(q.fC, q.fA + q.fW, q.fB); + glVertex3f(q.fC, q.fA + q.fW, q.fB + q.fH); + glVertex3f(q.fC, q.fA, q.fB + q.fH); + glEnd(); + } + } + break; + } + + case TEveQuadSet::QT_RectangleXYFixedDim: + { + const Float_t& w = mQ.fDefWidth; + const Float_t& h = mQ.fDefHeight; + while (qi.next()) { + TEveQuadSet::QRectFixDim& q = * (TEveQuadSet::QRectFixDim*) qi(); + if (SetupColor(q)) + { + if (rnrCtx.SecSelection()) glLoadName(qi.index()); + glBegin(primitiveType); + glVertex3f(q.fA, q.fB, q.fC); + glVertex3f(q.fA + w, q.fB, q.fC); + glVertex3f(q.fA + w, q.fB + h, q.fC); + glVertex3f(q.fA, q.fB + h, q.fC); + glEnd(); + } + } + break; + } + + case TEveQuadSet::QT_RectangleXYFixedZ: + { + const Float_t& z = mQ.fDefCoord; + while (qi.next()) { + TEveQuadSet::QRectFixC& q = * (TEveQuadSet::QRectFixC*) qi(); + if (SetupColor(q)) + { + if (rnrCtx.SecSelection()) glLoadName(qi.index()); + glBegin(primitiveType); + glVertex3f(q.fA, q.fB, z); + glVertex3f(q.fA + q.fW, q.fB, z); + glVertex3f(q.fA + q.fW, q.fB + q.fH, z); + glVertex3f(q.fA, q.fB + q.fH, z); + glEnd(); + } + } + break; + } + + case TEveQuadSet::QT_RectangleXZFixedY: + { + const Float_t& y = mQ.fDefCoord; + while (qi.next()) { + TEveQuadSet::QRectFixC& q = * (TEveQuadSet::QRectFixC*) qi(); + if (SetupColor(q)) + { + if (rnrCtx.SecSelection()) glLoadName(qi.index()); + glBegin(primitiveType); + glVertex3f(q.fA, y, q.fB); + glVertex3f(q.fA + q.fW, y, q.fB); + glVertex3f(q.fA + q.fW, y, q.fB + q.fH); + glVertex3f(q.fA, y, q.fB + q.fH); + glEnd(); + } + } + break; + } + + case TEveQuadSet::QT_RectangleYZFixedX: + { + const Float_t& x = mQ.fDefCoord; + while (qi.next()) { + TEveQuadSet::QRectFixC& q = * (TEveQuadSet::QRectFixC*) qi(); + if (SetupColor(q)) + { + if (rnrCtx.SecSelection()) glLoadName(qi.index()); + glBegin(primitiveType); + glVertex3f(x, q.fA, q.fB); + glVertex3f(x, q.fA + q.fW, q.fB); + glVertex3f(x, q.fA + q.fW, q.fB + q.fH); + glVertex3f(x, q.fA, q.fB + q.fH); + glEnd(); + } + } + break; + } + + case TEveQuadSet::QT_RectangleXYFixedDimZ: + { + const Float_t& z = mQ.fDefCoord; + const Float_t& w = mQ.fDefWidth; + const Float_t& h = mQ.fDefHeight; + while (qi.next()) { + TEveQuadSet::QRectFixDimC& q = * (TEveQuadSet::QRectFixDimC*) qi(); + if (SetupColor(q)) + { + if (rnrCtx.SecSelection()) glLoadName(qi.index()); + glBegin(primitiveType); + glVertex3f(q.fA, q.fB, z); + glVertex3f(q.fA + w, q.fB, z); + glVertex3f(q.fA + w, q.fB + h, z); + glVertex3f(q.fA, q.fB + h, z); + glEnd(); + } + } + break; + } + + case TEveQuadSet::QT_RectangleXZFixedDimY: + { + const Float_t& y = mQ.fDefCoord; + const Float_t& w = mQ.fDefWidth; + const Float_t& h = mQ.fDefHeight; + while (qi.next()) { + TEveQuadSet::QRectFixDimC& q = * (TEveQuadSet::QRectFixDimC*) qi(); + if (SetupColor(q)) + { + if (rnrCtx.SecSelection()) glLoadName(qi.index()); + glBegin(primitiveType); + glVertex3f(q.fA, y, q.fB); + glVertex3f(q.fA + w, y, q.fB); + glVertex3f(q.fA + w, y, q.fB + h); + glVertex3f(q.fA, y, q.fB + h); + glEnd(); + } + } + break; + } + + case TEveQuadSet::QT_RectangleYZFixedDimX: + { + const Float_t& x = mQ.fDefCoord; + const Float_t& w = mQ.fDefWidth; + const Float_t& h = mQ.fDefHeight; + while (qi.next()) { + TEveQuadSet::QRectFixDimC& q = * (TEveQuadSet::QRectFixDimC*) qi(); + if (SetupColor(q)) + { + if (rnrCtx.SecSelection()) glLoadName(qi.index()); + glBegin(primitiveType); + glVertex3f(x, q.fA, q.fB); + glVertex3f(x, q.fA + w, q.fB); + glVertex3f(x, q.fA + w, q.fB + h); + glVertex3f(x, q.fA, q.fB + h); + glEnd(); + } + } + break; + } + + default: + throw(eH + "unsupported quad-type."); + + } // end switch quad-type + + if (rnrCtx.SecSelection()) glPopName(); +} + +//______________________________________________________________________________ +void TEveQuadSetGL::RenderLines(TGLRnrCtx & rnrCtx) const +{ + static const TEveException eH("TEveQuadSetGL::RenderLines "); + + TEveQuadSet& mQ = * fM; + + TEveChunkManager::iterator qi(mQ.fPlex); + + if (rnrCtx.SecSelection()) glPushName(0); + + switch (mQ.fQuadType) + { + + case TEveQuadSet::QT_LineXYFixedZ: + { + const Float_t& z = mQ.fDefCoord; + while (qi.next()) { + TEveQuadSet::QLineFixC& q = * (TEveQuadSet::QLineFixC*) qi(); + if (SetupColor(q)) + { + if (rnrCtx.SecSelection()) glLoadName(qi.index()); + glBegin(GL_LINES); + glVertex3f(q.fA, q.fB, z); + glVertex3f(q.fA + q.fDx, q.fB + q.fDy, z); + glEnd(); + } + } + break; + } + + case TEveQuadSet::QT_LineXZFixedY: + { + const Float_t& z = mQ.fDefCoord; + while (qi.next()) { + TEveQuadSet::QLineFixC& q = * (TEveQuadSet::QLineFixC*) qi(); + if (SetupColor(q)) + { + if (rnrCtx.SecSelection()) glLoadName(qi.index()); + glBegin(GL_LINES); + glVertex3f(q.fA, z, q.fB); + glVertex3f(q.fA + q.fDx, z, q.fB + q.fDy); + glEnd(); + } + } + break; + } + + default: + throw(eH + "unsupported quad-type."); + + } + + if (rnrCtx.SecSelection()) glPopName(); +} + +//______________________________________________________________________________ +void TEveQuadSetGL::RenderHexagons(TGLRnrCtx & rnrCtx) const +{ + static const TEveException eH("TEveQuadSetGL::RenderHexagons "); + + const Float_t sqr3hf = 0.5*TMath::Sqrt(3); + + TEveQuadSet& mQ = * fM; + + GLenum primitveType = (mQ.fRenderMode != TEveDigitSet::RM_TEveLine) ? + GL_POLYGON : GL_LINE_LOOP; + + glNormal3f(0, 0, 1); + + TEveChunkManager::iterator qi(mQ.fPlex); + + if (rnrCtx.SecSelection()) glPushName(0); + + switch (mQ.fQuadType) + { + + case TEveQuadSet::QT_HexagonXY: + { + while (qi.next()) { + TEveQuadSet::QHex& q = * (TEveQuadSet::QHex*) qi(); + if (SetupColor(q)) + { + const Float_t rh = q.fR * 0.5; + const Float_t rs = q.fR * sqr3hf; + if (rnrCtx.SecSelection()) glLoadName(qi.index()); + glBegin(primitveType); + glVertex3f( q.fR + q.fA, q.fB, q.fC); + glVertex3f( rh + q.fA, rs + q.fB, q.fC); + glVertex3f( -rh + q.fA, rs + q.fB, q.fC); + glVertex3f(-q.fR + q.fA, q.fB, q.fC); + glVertex3f( -rh + q.fA, -rs + q.fB, q.fC); + glVertex3f( rh + q.fA, -rs + q.fB, q.fC); + glEnd(); + } + } + break; + } + + case TEveQuadSet::QT_HexagonYX: + { + while (qi.next()) { + TEveQuadSet::QHex& q = * (TEveQuadSet::QHex*) qi(); + if (SetupColor(q)) + { + const Float_t rh = q.fR * 0.5; + const Float_t rs = q.fR * sqr3hf; + if (rnrCtx.SecSelection()) glLoadName(qi.index()); + glBegin(primitveType); + glVertex3f( rs + q.fA, rh + q.fB, q.fC); + glVertex3f( q.fA, q.fR + q.fB, q.fC); + glVertex3f(-rs + q.fA, rh + q.fB, q.fC); + glVertex3f(-rs + q.fA, -rh + q.fB, q.fC); + glVertex3f( q.fA, -q.fR + q.fB, q.fC); + glVertex3f( rs + q.fA, -rh + q.fB, q.fC); + glEnd(); + } + } + break; + } + + default: + throw(eH + "unsupported quad-type."); + + } // end switch quad-type + + if (rnrCtx.SecSelection()) glPopName(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveQuadSetGL::ProcessSelection(TGLRnrCtx & /*rnrCtx*/, TGLSelectRecord & rec) +{ + // Processes secondary selection from TGLViewer. + // Calls TPointSet3D::PointSelected(Int_t) with index of selected + // point as an argument. + + if (rec.GetN() < 2) return; + fM->DigitSelected(rec.GetItem(1)); +} diff --git a/eve/src/TEveRGBAPalette.cxx b/eve/src/TEveRGBAPalette.cxx new file mode 100644 index 0000000000..2983eb7bd6 --- /dev/null +++ b/eve/src/TEveRGBAPalette.cxx @@ -0,0 +1,257 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 + +#include +#include +#include +//______________________________________________________________________________ +// TEveRGBAPalette +// + +ClassImp(TEveRGBAPalette) + +//______________________________________________________________________________ +TEveRGBAPalette::TEveRGBAPalette() : + TObject(), + TEveRefCnt(), + + fLowLimit(0), fHighLimit(0), fMinVal(0), fMaxVal(0), fNBins(0), + + fInterpolate (kFALSE), + fShowDefValue (kTRUE), + fUnderflowAction (LA_Cut), + fOverflowAction (LA_Clip), + + fDefaultColor(0), + fUnderColor (1), + fOverColor (2), + fColorArray (0) +{ + SetLimits(0, 1024); + SetMinMax(0, 512); +} + +//______________________________________________________________________________ +TEveRGBAPalette::TEveRGBAPalette(Int_t min, Int_t max, Bool_t interp, Bool_t showdef) : + TObject(), + TEveRefCnt(), + + fLowLimit(0), fHighLimit(0), fMinVal(0), fMaxVal(0), fNBins(0), + + fInterpolate (interp), + fShowDefValue (showdef), + fUnderflowAction (LA_Cut), + fOverflowAction (LA_Clip), + + fDefaultColor(0), + fUnderColor (1), + fOverColor (2), + fColorArray (0) +{ + SetLimits(min, max); + SetMinMax(min, max); +} + +//______________________________________________________________________________ +TEveRGBAPalette::~TEveRGBAPalette() +{ + delete [] fColorArray; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveRGBAPalette::SetupColor(Int_t val, UChar_t* pixel) const +{ + using namespace TMath; + Float_t div = Max(1, fMaxVal - fMinVal); + Int_t nCol = gStyle->GetNumberOfColors(); + + Float_t f; + if (val >= fMaxVal) f = nCol - 1; + else if (val <= fMinVal) f = 0; + else f = (val - fMinVal)/div*(nCol - 1); + + if (fInterpolate) { + Int_t bin = (Int_t) f; + Float_t f1 = f - bin, f2 = 1.0f - f1; + TEveUtil::ColorFromIdx(f1, gStyle->GetColorPalette(bin), + f2, gStyle->GetColorPalette(Min(bin + 1, nCol - 1)), + pixel); + } else { + TEveUtil::ColorFromIdx(gStyle->GetColorPalette((Int_t) Nint(f)), pixel); + } +} + +//______________________________________________________________________________ +void TEveRGBAPalette::SetupColorArray() const +{ + if(fColorArray) // !!!! should reinit anyway, maybe palette in gstyle changed + return; + + // !!!! probably should store original palette for editing ... + + fColorArray = new UChar_t [4 * fNBins]; + UChar_t* p = fColorArray; + for(Int_t v=fMinVal; v<=fMaxVal; ++v, p+=4) + SetupColor(v, p); +} + +//______________________________________________________________________________ +void TEveRGBAPalette::ClearColorArray() +{ + if(fColorArray) { + delete [] fColorArray; + fColorArray = 0; + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveRGBAPalette::SetLimits(Int_t low, Int_t high) +{ + fLowLimit = low; + fHighLimit = high; + Bool_t changed = kFALSE; + if (fMaxVal < fLowLimit) { SetMax(fLowLimit); changed = kTRUE; } + if (fMinVal < fLowLimit) { SetMin(fLowLimit); changed = kTRUE; } + if (fMinVal > fHighLimit) { SetMin(fHighLimit); changed = kTRUE; } + if (fMaxVal > fHighLimit) { SetMax(fHighLimit); changed = kTRUE; } + if (changed) + ClearColorArray(); +} + +//______________________________________________________________________________ +void TEveRGBAPalette::SetLimitsScaleMinMax(Int_t low, Int_t high) +{ + Float_t rng_old = fHighLimit - fLowLimit; + Float_t rng_new = high - low; + + fMinVal = TMath::Nint(low + (fMinVal - fLowLimit)*rng_new/rng_old); + fMaxVal = TMath::Nint(low + (fMaxVal - fLowLimit)*rng_new/rng_old); + fLowLimit = low; + fHighLimit = high; + + fNBins = fMaxVal - fMinVal + 1; + ClearColorArray(); +} + +//______________________________________________________________________________ +void TEveRGBAPalette::SetMin(Int_t min) +{ + fMinVal = TMath::Min(min, fMaxVal); + fNBins = fMaxVal - fMinVal + 1; + ClearColorArray(); +} + +//______________________________________________________________________________ +void TEveRGBAPalette::SetMax(Int_t max) +{ + fMaxVal = TMath::Max(max, fMinVal); + fNBins = fMaxVal - fMinVal + 1; + ClearColorArray(); +} + +//______________________________________________________________________________ +void TEveRGBAPalette::SetMinMax(Int_t min, Int_t max) +{ + fMinVal = min; + fMaxVal = max; + fNBins = fMaxVal - fMinVal + 1; + ClearColorArray(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveRGBAPalette::SetInterpolate(Bool_t b) +{ + fInterpolate = b; + ClearColorArray(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveRGBAPalette::SetDefaultColor(Color_t ci) +{ + fDefaultColor = ci; + TEveUtil::ColorFromIdx(ci, fDefaultRGBA, kTRUE); +} + +//______________________________________________________________________________ +void TEveRGBAPalette::SetDefaultColor(Pixel_t pix) +{ + SetDefaultColor(Color_t(TColor::GetColor(pix))); +} + +//______________________________________________________________________________ +void TEveRGBAPalette::SetDefaultColor(UChar_t r, UChar_t g, UChar_t b, UChar_t a) +{ + fDefaultColor = Color_t(TColor::GetColor(r, g, b)); + fDefaultRGBA[0] = r; + fDefaultRGBA[1] = g; + fDefaultRGBA[2] = b; + fDefaultRGBA[3] = a; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveRGBAPalette::SetUnderColor(Color_t ci) +{ + fUnderColor = ci; + TEveUtil::ColorFromIdx(ci, fUnderRGBA, kTRUE); +} + +//______________________________________________________________________________ +void TEveRGBAPalette::SetUnderColor(Pixel_t pix) +{ + SetUnderColor(Color_t(TColor::GetColor(pix))); +} + +//______________________________________________________________________________ +void TEveRGBAPalette::SetUnderColor(UChar_t r, UChar_t g, UChar_t b, UChar_t a) +{ + fUnderColor = Color_t(TColor::GetColor(r, g, b)); + fUnderRGBA[0] = r; + fUnderRGBA[1] = g; + fUnderRGBA[2] = b; + fUnderRGBA[3] = a; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveRGBAPalette::SetOverColor(Color_t ci) +{ + fOverColor = ci; + TEveUtil::ColorFromIdx(ci, fOverRGBA, kTRUE); +} + +//______________________________________________________________________________ +void TEveRGBAPalette::SetOverColor(Pixel_t pix) +{ + SetOverColor(Color_t(TColor::GetColor(pix))); +} + +//______________________________________________________________________________ +void TEveRGBAPalette::SetOverColor(UChar_t r, UChar_t g, UChar_t b, UChar_t a) +{ + fOverColor = Color_t(TColor::GetColor(r, g, b)); + fOverRGBA[0] = r; + fOverRGBA[1] = g; + fOverRGBA[2] = b; + fOverRGBA[3] = a; +} diff --git a/eve/src/TEveRGBAPaletteEditor.cxx b/eve/src/TEveRGBAPaletteEditor.cxx new file mode 100644 index 0000000000..2b8d245cef --- /dev/null +++ b/eve/src/TEveRGBAPaletteEditor.cxx @@ -0,0 +1,261 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +//______________________________________________________________________________ +// TEveRGBAPaletteSubEditor +// +// Sub-editor for TEveRGBAPalette class. + +ClassImp(TEveRGBAPaletteSubEditor) + +//______________________________________________________________________________ +TEveRGBAPaletteSubEditor::TEveRGBAPaletteSubEditor(const TGWindow* p) : + TGVerticalFrame(p), + + fM(0), + + fUnderflowAction (0), + fUnderColor (0), + fOverflowAction (0), + fOverColor (0), + + fMinMax(0), + + fInterpolate(0), + fShowDefValue(0), + fDefaultColor(0) +{ + // Int_t labelW = 42; + + { + TGHorizontalFrame* f = new TGHorizontalFrame(this); + + fInterpolate = new TGCheckButton(f, "Interpolate"); + f->AddFrame(fInterpolate, new TGLayoutHints(kLHintsLeft, 3, 1, 1, 0)); + fInterpolate->Connect("Toggled(Bool_t)", + "TEveRGBAPaletteSubEditor", this, "DoInterpolate()"); + + AddFrame(f, new TGLayoutHints(kLHintsTop, 1, 1, 1, 0)); + } + + { + TGHorizontalFrame* f = new TGHorizontalFrame(this); + + fShowDefValue = new TGCheckButton(f, "Show default value"); + f->AddFrame(fShowDefValue, new TGLayoutHints(kLHintsLeft, 3, 1, 1, 0)); + fShowDefValue->Connect("Toggled(Bool_t)", + "TEveRGBAPaletteSubEditor", this, "DoShowDefValue()"); + + fDefaultColor = new TGColorSelect(f, 0, -1); + f->AddFrame(fDefaultColor, new TGLayoutHints(kLHintsLeft|kLHintsTop, 3, 1, 0, 2)); + fDefaultColor->Connect("ColorSelected(Pixel_t)", + "TEveRGBAPaletteSubEditor", this, "DoDefaultColor(Pixel_t)"); + + AddFrame(f, new TGLayoutHints(kLHintsTop, 1, 1, 1, 0)); + } + + { // Underflow + TGHorizontalFrame* f = new TGHorizontalFrame(this); + TGLabel* lab = new TGLabel(f, "Underflow:"); + f->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsBottom, 1, 15, 1, 2)); + fUnderflowAction = new TGComboBox(f); + fUnderflowAction->AddEntry("Cut", 0); + fUnderflowAction->AddEntry("Mark", 1); + fUnderflowAction->AddEntry("Clip", 2); + fUnderflowAction->AddEntry("Wrap", 3); + TGListBox* lb = fUnderflowAction->GetListBox(); + lb->Resize(lb->GetWidth(), 4*16); + fUnderflowAction->Resize(59, 20); + fUnderflowAction->Connect("Selected(Int_t)", "TEveRGBAPaletteSubEditor", this, + "DoUnderflowAction(Int_t)"); + f->AddFrame(fUnderflowAction, new TGLayoutHints(kLHintsLeft, 1, 2, 1, 1)); + + fUnderColor = new TGColorSelect(f, 0, -1); + f->AddFrame(fUnderColor, new TGLayoutHints(kLHintsLeft|kLHintsTop, 1, 1, 0, 2)); + fUnderColor->Connect("ColorSelected(Pixel_t)", + "TEveRGBAPaletteSubEditor", this, "DoUnderColor(Pixel_t)"); + + AddFrame(f); + } + + { // Overflow + TGHorizontalFrame* f = new TGHorizontalFrame(this); + TGLabel* lab = new TGLabel(f, "Overflow:"); + f->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsBottom, 1, 20, 1, 2)); + fOverflowAction = new TGComboBox(f); + fOverflowAction->AddEntry("Cut", 0); + fOverflowAction->AddEntry("Mark", 1); + fOverflowAction->AddEntry("Clip", 2); + fOverflowAction->AddEntry("Wrap", 3); + TGListBox* lb = fOverflowAction->GetListBox(); + lb->Resize(lb->GetWidth(), 4*16); + fOverflowAction->Resize(59, 20); + fOverflowAction->Connect("Selected(Int_t)", "TEveRGBAPaletteSubEditor", this, + "DoOverflowAction(Int_t)"); + f->AddFrame(fOverflowAction, new TGLayoutHints(kLHintsLeft, 1, 2, 1, 1)); + + fOverColor = new TGColorSelect(f, 0, -1); + f->AddFrame(fOverColor, new TGLayoutHints(kLHintsLeft|kLHintsTop, 1, 1, 0, 2)); + fOverColor->Connect("ColorSelected(Pixel_t)", + "TEveRGBAPaletteSubEditor", this, "DoOverColor(Pixel_t)"); + + AddFrame(f); + } + + fMinMax = new TEveGDoubleValuator(this,"Main range:", 200, 0); + fMinMax->SetNELength(5); + fMinMax->SetLabelWidth(74); + fMinMax->Build(); + fMinMax->GetSlider()->SetWidth(224); + fMinMax->SetLimits(0, 1023, TGNumberFormat::kNESInteger); + fMinMax->Connect("ValueSet()", + "TEveRGBAPaletteSubEditor", this, "DoMinMax()"); + AddFrame(fMinMax, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1)); + +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveRGBAPaletteSubEditor::SetModel(TEveRGBAPalette* p) +{ + fM = p; + + fMinMax->SetValues(fM->fMinVal, fM->fMaxVal); + fMinMax->SetLimits(fM->fLowLimit, fM->fHighLimit); + + fInterpolate->SetState(fM->fInterpolate ? kButtonDown : kButtonUp); + fShowDefValue->SetState(fM->fShowDefValue ? kButtonDown : kButtonUp); + fDefaultColor->SetColor(TColor::Number2Pixel(fM->GetDefaultColor()), kFALSE); + + fUnderColor->SetColor(TColor::Number2Pixel(fM->GetUnderColor()), kFALSE); + fOverColor->SetColor(TColor::Number2Pixel(fM->GetOverColor()), kFALSE); + + fUnderflowAction->Select(fM->fUnderflowAction, kFALSE); + fOverflowAction->Select(fM->fOverflowAction, kFALSE); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveRGBAPaletteSubEditor::Changed() +{ + Emit("Changed()"); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveRGBAPaletteSubEditor::DoMinMax() +{ + fM->SetMinMax((Int_t) fMinMax->GetMin(), (Int_t) fMinMax->GetMax()); + Changed(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveRGBAPaletteSubEditor::DoInterpolate() +{ + fM->SetInterpolate(fInterpolate->IsOn()); + Changed(); +} + +//______________________________________________________________________________ +void TEveRGBAPaletteSubEditor::DoShowDefValue() +{ + fM->SetShowDefValue(fShowDefValue->IsOn()); + Changed(); +} + +//______________________________________________________________________________ +void TEveRGBAPaletteSubEditor::DoDefaultColor(Pixel_t color) +{ + fM->SetDefaultColor(color); + Changed(); +} + +//______________________________________________________________________________ +void TEveRGBAPaletteSubEditor::DoUnderColor(Pixel_t color) +{ + fM->SetUnderColor(color); + Changed(); +} + +//______________________________________________________________________________ +void TEveRGBAPaletteSubEditor::DoOverColor(Pixel_t color) +{ + fM->SetOverColor(color); + Changed(); +} + +//______________________________________________________________________________ +void TEveRGBAPaletteSubEditor::DoUnderflowAction(Int_t mode) +{ + fM->SetUnderflowAction(mode); + Changed(); +} + +//______________________________________________________________________________ +void TEveRGBAPaletteSubEditor::DoOverflowAction(Int_t mode) +{ + fM->SetOverflowAction(mode); + Changed(); +} + + +//______________________________________________________________________________ +// TEveRGBAPaletteEditor +// +// Editor for TEveRGBAPalette class. + +ClassImp(TEveRGBAPaletteEditor) + +//______________________________________________________________________________ +TEveRGBAPaletteEditor::TEveRGBAPaletteEditor(const TGWindow *p, Int_t width, Int_t height, + UInt_t options, Pixel_t back) : + TGedFrame(p, width, height, options | kVerticalFrame, back), + fM (0), + fSE(0) +{ + MakeTitle("TEveRGBAPalette"); + + fSE = new TEveRGBAPaletteSubEditor(this); + AddFrame(fSE, new TGLayoutHints(kLHintsTop, 2, 0, 2, 2)); + fSE->Connect("Changed()", "TEveRGBAPaletteEditor", this, "Update()"); +} + +//______________________________________________________________________________ +TEveRGBAPaletteEditor::~TEveRGBAPaletteEditor() +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveRGBAPaletteEditor::SetModel(TObject* obj) +{ + fM = dynamic_cast(obj); + fSE->SetModel(fM); +} diff --git a/eve/src/TEveScene.cxx b/eve/src/TEveScene.cxx new file mode 100644 index 0000000000..6e8a0d802a --- /dev/null +++ b/eve/src/TEveScene.cxx @@ -0,0 +1,127 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include + +#include +#include + +//______________________________________________________________________________ +// TEveScene +// +// Reve representation of TGLScene. + +ClassImp(TEveScene) + +//______________________________________________________________________________ +TEveScene::TEveScene(const Text_t* n, const Text_t* t) : + TEveElementList(n, t), + fPad (0), + fGLScene(0), + fChanged (kFALSE), + fSmartRefresh (kTRUE) +{ + fPad = new TEvePad; + fPad->GetListOfPrimitives()->Add(this); + fGLScene = new TGLScenePad(fPad); + fGLScene->SetName(n); + fGLScene->SetAutoDestruct(kFALSE); +} + +//______________________________________________________________________________ +TEveScene::~TEveScene() +{ + gEve->GetViewers()->SceneDestructing(this); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveScene::CollectSceneParents(List_t& scenes) +{ + scenes.push_back(this); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveScene::Repaint() +{ + fGLScene->PadPaint(fPad); + fChanged = kFALSE; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveScene::SetName(const Text_t* n) +{ + TEveElementList::SetName(n); + fGLScene->SetName(n); +} + +//______________________________________________________________________________ +void TEveScene::Paint(Option_t* option) +{ + if (fRnrChildren) + { + for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i) + (*i)->PadPaint(option); + } +} + + +//______________________________________________________________________________ +// TEveSceneList +// +// List of Scenes providing common operations on TEveScene collections. + +ClassImp(TEveSceneList) + +//______________________________________________________________________________ +TEveSceneList::TEveSceneList(const Text_t* n, const Text_t* t) : + TEveElementList(n, t) +{ + SetChildClass(TEveScene::Class()); +} + +//______________________________________________________________________________ +TEveSceneList::~TEveSceneList() +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveSceneList::RepaintChangedScenes() +{ + for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i) + { + TEveScene* s = (TEveScene*) *i; + if (s->IsChanged()) + { + // printf(" TEveScene '%s' changed ... repainting.\n", s->GetName()); + s->Repaint(); + } + } +} + +//______________________________________________________________________________ +void TEveSceneList::RepaintAllScenes() +{ + for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i) + { + TEveScene* s = (TEveScene*) *i; + // printf(" TEveScene '%s' repainting.\n", s->GetName()); + s->Repaint(); + } +} diff --git a/eve/src/TEveSceneInfo.cxx b/eve/src/TEveSceneInfo.cxx new file mode 100644 index 0000000000..8cb5715ce4 --- /dev/null +++ b/eve/src/TEveSceneInfo.cxx @@ -0,0 +1,81 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include + +#include + +//______________________________________________________________________________ +// TEveSceneInfo +// +// TEveUtil representation of TGLSceneInfo. + +ClassImp(TEveSceneInfo) + +//______________________________________________________________________________ +TEveSceneInfo::TEveSceneInfo(TEveViewer* viewer, TEveScene* scene, TGLSceneInfo* sinfo) : + TEveElement (), + TNamed (Form("SI - %s", scene->GetName()), + Form("TEveSceneInfo of scene '%s'", scene->GetName())), + fViewer (viewer), + fScene (scene), + fGLSceneInfo (sinfo) +{} + +//______________________________________________________________________________ +TEveSceneInfo::~TEveSceneInfo() +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +TGLSceneBase* TEveSceneInfo::GetGLScene() const +{ + return fGLSceneInfo->GetScene(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveSceneInfo::SetRnrSelf(Bool_t rnr) +{ + TEveElement::SetRnrSelf(rnr); + fGLSceneInfo->SetActive(fRnrSelf); +} + +//______________________________________________________________________________ +void TEveSceneInfo::SetRnrState(Bool_t rnr) +{ + TEveElement::SetRnrState(rnr); + fGLSceneInfo->SetActive(fRnrSelf); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +Bool_t TEveSceneInfo::AcceptElement(TEveElement* /*el*/) +{ + static const TEveException eH("TEveSceneInfo::AcceptElement "); + + gEve->SetStatusLine(eH + "this class does not accept children."); + return kFALSE; +} + +//______________________________________________________________________________ +Bool_t TEveSceneInfo::HandleElementPaste(TEveElement* /*el*/) +{ + static const TEveException eH("TEveSceneInfo::HandleElementPaste "); + + gEve->SetStatusLine(eH + "this class does not accept children."); + return kFALSE; +} diff --git a/eve/src/TEveStraightLineSet.cxx b/eve/src/TEveStraightLineSet.cxx new file mode 100644 index 0000000000..fde62c9236 --- /dev/null +++ b/eve/src/TEveStraightLineSet.cxx @@ -0,0 +1,186 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 + +#include +#include +#include +#include + +#include +#include + +//______________________________________________________________________________ +// TEveStraightLineSet +// +// Set of straight lines with optional markers along the lines. + +ClassImp(TEveStraightLineSet) + +//______________________________________________________________________________ +TEveStraightLineSet::TEveStraightLineSet(const Text_t* n, const Text_t* t): + TEveElement (), + TNamed (n, t), + + fLinePlex (sizeof(TEveLine), 4), + fMarkerPlex (sizeof(Marker), 8), + fOwnLinesIds (kFALSE), + fOwnMarkersIds (kFALSE), + fRnrMarkers (kTRUE), + fRnrLines (kTRUE), + fLastLine (0), + fTrans (kFALSE), + fHMTrans () +{ + fMainColorPtr = &fLineColor; + fLineColor = 4; + fMarkerColor = 2; + fMarkerStyle = 20; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveStraightLineSet::AddLine(Float_t x1, Float_t y1, Float_t z1, + Float_t x2, Float_t y2, Float_t z2) +{ + fLastLine = new (fLinePlex.NewAtom()) TEveLine(x1, y1, z1, x2, y2, z2); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveStraightLineSet::AddMarker(Int_t line, Float_t pos) +{ + /*Marker* marker = */new (fMarkerPlex.NewAtom()) Marker(line, pos); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveStraightLineSet::ComputeBBox() +{ + static const TEveException eH("TEveStraightLineSet::ComputeBBox "); + if(fLinePlex.Size() == 0) { + BBoxZero(); + return; + } + + BBoxInit(); + + TEveChunkManager::iterator li(fLinePlex); + while (li.next()) { + BBoxCheckPoint(((TEveLine*)li())->fV1); + BBoxCheckPoint(((TEveLine*)li())->fV2); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveStraightLineSet::Paint(Option_t* /*option*/) +{ + static const TEveException eH("TEveStraightLineSet::Paint "); + + TBuffer3D buff(TBuffer3DTypes::kGeneric); + + // Section kCore + buff.fID = this; + buff.fColor = fLineColor; + buff.fTransparency = 0; + buff.fLocalFrame = kFALSE; + fHMTrans.SetBuffer3D(buff); + buff.SetSectionsValid(TBuffer3D::kCore); + + Int_t reqSections = gPad->GetViewer3D()->AddObject(buff); + if (reqSections != TBuffer3D::kNone) + Error(eH, "only direct GL rendering supported."); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +TClass* TEveStraightLineSet::ProjectedClass() const +{ + return TEveStraightLineSetProjected::Class(); +} + + +//______________________________________________________________________________ +// TEveStraightLineSetProjected +// +// Projected copy of a TEveStraightLineSet. + +ClassImp(TEveStraightLineSetProjected) + +//______________________________________________________________________________ + TEveStraightLineSetProjected::TEveStraightLineSetProjected() : TEveStraightLineSet(), TEveProjected () +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveStraightLineSetProjected::SetProjection(TEveProjectionManager* proj, TEveProjectable* model) +{ + TEveProjected::SetProjection(proj, model); + + // copy line and marker attributes + * (TAttMarker*)this = * dynamic_cast(fProjectable); + * (TAttLine*)this = * dynamic_cast(fProjectable); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveStraightLineSetProjected::UpdateProjection() +{ + TEveProjection& proj = * fProjector->GetProjection(); + TEveStraightLineSet& orig = * dynamic_cast(fProjectable); + + // lines + Int_t NL = orig.GetLinePlex().Size(); + fLinePlex.Reset(sizeof(TEveLine), NL); + TEveLine* l; + Float_t p1[3]; + Float_t p2[3]; + TEveChunkManager::iterator li(orig.GetLinePlex()); + + Double_t s1, s2, s3; + orig.RefHMTrans().GetScale(s1, s2, s3); + TEveTrans mx; mx.Scale(s1, s2, s3); + Double_t x, y, z; + orig.RefHMTrans().GetPos(x, y,z); + while (li.next()) + { + l = (TEveLine*) li(); + p1[0] = l->fV1[0]; p1[1] = l->fV1[1]; p1[2] = l->fV1[2]; + p2[0] = l->fV2[0]; p2[1] = l->fV2[1]; p2[2] = l->fV2[2]; + mx.MultiplyIP(p1); + mx.MultiplyIP(p2); + p1[0] += x; p1[1] += y; p1[2] += z; + p2[0] += x; p2[1] += y; p2[2] += z; + proj.ProjectPointFv(p1); + proj.ProjectPointFv(p2); + AddLine(p1[0], p1[1], p1[2], p2[0], p2[1], p2[2]); + } + + // markers + Int_t NM = orig.GetMarkerPlex().Size(); + fMarkerPlex.Reset(sizeof(Marker), NM); + Marker* m; + TEveChunkManager::iterator mi(orig.GetMarkerPlex()); + while (mi.next()) + { + m = (Marker*) mi(); + AddMarker(m->fLineID, m->fPos); + } +} diff --git a/eve/src/TEveStraightLineSetEditor.cxx b/eve/src/TEveStraightLineSetEditor.cxx new file mode 100644 index 0000000000..c5b79cc6f9 --- /dev/null +++ b/eve/src/TEveStraightLineSetEditor.cxx @@ -0,0 +1,88 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include + +#include +#include + +#include +#include +#include +#include +#include + +//______________________________________________________________________________ +// TEveStraightLineSetEditor +// +// Editor for TEveStraightLineSet class. + +ClassImp(TEveStraightLineSetEditor) + +//______________________________________________________________________________ +TEveStraightLineSetEditor::TEveStraightLineSetEditor(const TGWindow *p, Int_t width, Int_t height, + UInt_t options, Pixel_t back) : + TGedFrame(p, width, height, options | kVerticalFrame, back), + fM(0) + // Initialize widget pointers to 0 +{ + MakeTitle("TEveStraightLineSet"); + + TGHorizontalFrame* frame = new TGHorizontalFrame(this); + + fRnrMarkers = new TGCheckButton(frame, "RnrMarkers"); + frame->AddFrame(fRnrMarkers, new TGLayoutHints(kLHintsLeft, 1, 2, 1, 1)); + fRnrMarkers->Connect + ("Toggled(Bool_t)", + "TEveStraightLineSetEditor", this, "DoRnrMarkers()"); + + fRnrLines = new TGCheckButton(frame, "RnrLines"); + frame->AddFrame(fRnrLines, new TGLayoutHints(kLHintsLeft, 2, 1, 1, 1)); + fRnrLines->Connect + ("Toggled(Bool_t)", + "TEveStraightLineSetEditor", this, "DoRnrLines()"); + + AddFrame(frame, new TGLayoutHints(kLHintsTop, 0, 0, 0, 0)); +} + +TEveStraightLineSetEditor::~TEveStraightLineSetEditor() +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveStraightLineSetEditor::SetModel(TObject* obj) +{ + fM = dynamic_cast(obj); + + // Set values of widgets + fRnrMarkers->SetState(fM->GetRnrMarkers() ? kButtonDown : kButtonUp); + fRnrLines->SetState(fM->GetRnrLines() ? kButtonDown : kButtonUp); +} + +/******************************************************************************/ + +// Implements callback/slot methods + +//______________________________________________________________________________ +void TEveStraightLineSetEditor::DoRnrMarkers() +{ + fM->SetRnrMarkers(fRnrMarkers->IsOn()); + Update(); +} + +//______________________________________________________________________________ +void TEveStraightLineSetEditor::DoRnrLines() +{ + fM->SetRnrLines(fRnrLines->IsOn()); + Update(); +} diff --git a/eve/src/TEveStraightLineSetGL.cxx b/eve/src/TEveStraightLineSetGL.cxx new file mode 100644 index 0000000000..fd1f0fc469 --- /dev/null +++ b/eve/src/TEveStraightLineSetGL.cxx @@ -0,0 +1,188 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include + +#include +#include + +#include + +//______________________________________________________________________________ +// TEveStraightLineSetGL +// +// GL-renderer for TEveStraightLineSet class. + +ClassImp(TEveStraightLineSetGL) + +//______________________________________________________________________________ +TEveStraightLineSetGL::TEveStraightLineSetGL() : TGLObject(), fM(0) +{ + // Constructor. + + // fDLCache = false; // Disable display list. +} + +//______________________________________________________________________________ +TEveStraightLineSetGL::~TEveStraightLineSetGL() +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +Bool_t TEveStraightLineSetGL::SetModel(TObject* obj, const Option_t* /*opt*/) +{ + if(SetModelCheckClass(obj, TEveStraightLineSet::Class())) { + fM = dynamic_cast(obj); + return kTRUE; + } + return kFALSE; +} + +//______________________________________________________________________________ +void TEveStraightLineSetGL::SetBBox() +{ + // !! This ok if master sub-classed from TAttBBox + SetAxisAlignedBBox(((TEveStraightLineSet*)fExternalObj)->AssertBBox()); +} + +//______________________________________________________________________________ +Bool_t TEveStraightLineSetGL::ShouldCache(TGLRnrCtx & rnrCtx) const +{ + // Override from TGLDrawable. + // To account for large point-sizes we modify the projection matrix + // during selection and thus we need a direct draw. + + if (rnrCtx.Selection()) return kFALSE; + return fDLCache; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveStraightLineSetGL::DirectDraw(TGLRnrCtx & rnrCtx) const +{ + // printf("TEveStraightLineSetGL::DirectDraw Style %d, LOD %d\n", flags.Style(), flags.LOD()); + + TEveStraightLineSet& mL = * fM; + + glPushAttrib(GL_POINT_BIT | GL_LINE_BIT | GL_ENABLE_BIT); + + // lines + TEveGLUtil::GL_Capability_Switch lights_off(GL_LIGHTING, false); + if(mL.GetRnrLines() && mL.GetLinePlex().Size() > 0) + { + glDisable(GL_LIGHTING); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + UChar_t color[4]; + TEveUtil::ColorFromIdx(mL.GetLineColor(), color); + glColor4ubv(color); + glLineWidth(mL.GetLineWidth()); + if (mL.GetLineStyle() > 1) { + Int_t fac = 1; + UShort_t pat = 0xffff; + switch (mL.GetLineStyle()) { + case 2: pat = 0x3333; break; + case 3: pat = 0x5555; break; + case 4: pat = 0xf040; break; + case 5: pat = 0xf4f4; break; + case 6: pat = 0xf111; break; + case 7: pat = 0xf0f0; break; + case 8: pat = 0xff11; break; + case 9: pat = 0x3fff; break; + case 10: pat = 0x08ff; fac = 2; break; + } + glLineStipple(1, pat); + glEnable(GL_LINE_STIPPLE); + } + + TEveChunkManager::iterator li(mL.GetLinePlex()); + if(rnrCtx.SecSelection()) + { + GLuint name = 0; + glPushName(1); + glPushName(0); + while (li.next()) + { + TEveStraightLineSet::TEveLine& l = * (TEveStraightLineSet::TEveLine*) li(); + glLoadName(name); + { + glBegin(GL_LINES); + glVertex3f(l.fV1[0], l.fV1[1], l.fV1[2]); + glVertex3f(l.fV2[0], l.fV2[1], l.fV2[2]); + glEnd(); + } + name ++; + } + glPopName(); + glPopName(); + } + else + { + glBegin(GL_LINES); + while (li.next()) + { + TEveStraightLineSet::TEveLine& l = * (TEveStraightLineSet::TEveLine*) li(); + glVertex3f(l.fV1[0], l.fV1[1], l.fV1[2]); + glVertex3f(l.fV2[0], l.fV2[1], l.fV2[2]); + } + glEnd(); + } + } + glPopAttrib(); + + + // markers + if(mL.GetRnrMarkers() && mL.GetMarkerPlex().Size() > 0) + { + TEveChunkManager::iterator mi(mL.GetMarkerPlex()); + Float_t* pnts = new Float_t[mL.GetMarkerPlex().Size()*3]; + Float_t* pnt = pnts; + Int_t lidx = -1; + while (mi.next()) + { + TEveStraightLineSet::Marker& m = * (TEveStraightLineSet::Marker*) mi(); + lidx = m.fLineID; + TEveStraightLineSet::TEveLine& l = * (TEveStraightLineSet::TEveLine*) mL.GetLinePlex().Atom(lidx); + pnt[0] = l.fV1[0] + (l.fV2[0] - l.fV1[0])*m.fPos; + pnt[1] = l.fV1[1] + (l.fV2[1] - l.fV1[1])*m.fPos; + pnt[2] = l.fV1[2] + (l.fV2[2] - l.fV1[2])*m.fPos;; + pnt += 3; + } + if(rnrCtx.SecSelection()) glPushName(2); + TEveGLUtil::RenderPolyMarkers((TAttMarker&)mL, pnts, mL.GetMarkerPlex().Size(), + rnrCtx.Selection(), rnrCtx.SecSelection()); + if(rnrCtx.SecSelection()) glPopName(); + delete [] pnts; + } + +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveStraightLineSetGL::ProcessSelection(TGLRnrCtx & /*rnrCtx*/, + TGLSelectRecord & rec) +{ + if (rec.GetN() != 3) return; + if(rec.GetItem(1) == 1) + { + printf("selected line %d\n", rec.GetItem(2)); + } + else + { + TEveStraightLineSet::Marker& m = * (TEveStraightLineSet::Marker*) fM->GetMarkerPlex().Atom(rec.GetItem(2)); + printf("Selected point %d on line %d\n", rec.GetItem(2), m.fLineID); + } +} diff --git a/eve/src/TEveTrack.cxx b/eve/src/TEveTrack.cxx new file mode 100644 index 0000000000..824fa8f5a7 --- /dev/null +++ b/eve/src/TEveTrack.cxx @@ -0,0 +1,1301 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include + +#include +#include +#include +#include + +// Updates +#include +#include +#include +#include + +#include +#include +#include +#include + +//______________________________________________________________________________ +// TEveTrack +// +// Visual representation of a track. +// + +ClassImp(TEveTrack) + +//______________________________________________________________________________ +TEveTrack::TEveTrack() : + TEveLine(), + + fV(), + fP(), + fBeta(0), + fPdg(0), + fCharge(0), + fLabel(kMinInt), + fIndex(kMinInt), + fPathMarks(), + + fPropagator(0) +{ + // Default constructor. +} + +//______________________________________________________________________________ +TEveTrack::TEveTrack(TParticle* t, Int_t label, TEveTrackPropagator* rs): + TEveLine(), + + fV(t->Vx(), t->Vy(), t->Vz()), + fP(t->Px(), t->Py(), t->Pz()), + fBeta(t->P()/t->Energy()), + fPdg(0), + fCharge(0), + fLabel(label), + fIndex(kMinInt), + fPathMarks(), + + fPropagator(0) +{ + // Constructor from TParticle. + + SetPropagator(rs); + fMainColorPtr = &fLineColor; + + TParticlePDG* pdgp = t->GetPDG(); + if (pdgp) { + fPdg = pdgp->PdgCode(); + fCharge = (Int_t) TMath::Nint(pdgp->Charge()/3); + } + + SetName(t->GetName()); +} + +//______________________________________________________________________________ +TEveTrack::TEveTrack(TEveMCTrack* t, TEveTrackPropagator* rs): + TEveLine(), + + fV(t->Vx(), t->Vy(), t->Vz()), + fP(t->Px(), t->Py(), t->Pz()), + fBeta(t->P()/t->Energy()), + fPdg(0), + fCharge(0), + fLabel(t->label), + fIndex(t->index), + fPathMarks(), + + fPropagator(0) +{ + // Constructor from TEveUtil Monte Carlo track. + + SetPropagator(rs); + fMainColorPtr = &fLineColor; + + TParticlePDG* pdgp = t->GetPDG(); + if(pdgp == 0) { + t->ResetPdgCode(); pdgp = t->GetPDG(); + } + fCharge = (Int_t) TMath::Nint(pdgp->Charge()/3); + + SetName(t->GetName()); +} + +//______________________________________________________________________________ +TEveTrack::TEveTrack(TEveRecTrack* t, TEveTrackPropagator* rs) : + TEveLine(), + + fV(t->V), + fP(t->P), + fBeta(t->beta), + fPdg(0), + fCharge(t->sign), + fLabel(t->label), + fIndex(t->index), + fPathMarks(), + + fPropagator(0) +{ + // Constructor from TEveUtil reconstructed track. + + SetPropagator(rs); + fMainColorPtr = &fLineColor; + + SetName(t->GetName()); +} + +//______________________________________________________________________________ +TEveTrack::TEveTrack(const TEveTrack& t) : + TEveLine(), + TQObject(), + fV(t.fV), + fP(t.fP), + fBeta(t.fBeta), + fPdg(t.fPdg), + fCharge(t.fCharge), + fLabel(t.fLabel), + fIndex(t.fIndex), + fPathMarks(), + fPropagator(0) +{ + // Copy constructor. + + SetMainColor(t.GetMainColor()); + // TEveLine + fRnrLine = t.fRnrLine; + fRnrPoints = t.fRnrPoints; + // TLineAttrib + fLineColor = t.fLineColor; + fLineStyle = t.fLineStyle; + fLineWidth = t.fLineWidth; + SetPathMarks(t); + SetPropagator (t.fPropagator); +} + +//______________________________________________________________________________ +TEveTrack::~TEveTrack() +{ + // Destructor. + + SetPropagator(0); + for (vpPathMark_i i=fPathMarks.begin(); i!=fPathMarks.end(); ++i) + delete *i; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrack::SetStdTitle() +{ + // Set standard track title based on most data-member values. + + TString idx(fIndex == kMinInt ? "" : Form("%d", fIndex)); + TString lbl(fLabel == kMinInt ? "" : Form("%d", fLabel)); + SetTitle(Form("Index=%s, Label=%s\nChg=%d, Pdg=%d\n" + "pT=%.3f, pZ=%.3f\nV=(%.3f, %.3f, %.3f)", + idx.Data(), lbl.Data(), fCharge, fPdg, + fP.Perp(), fP.z, fV.x, fV.y, fV.z)); +} + +//______________________________________________________________________________ +void TEveTrack::SetTrackParams(const TEveTrack& t) +{ + // Copy track parameters from t. + // PathMarks are cleared. + + fV = t.fV; + fP = t.fP; + fBeta = t.fBeta; + fPdg = t.fPdg; + fCharge = t.fCharge; + fLabel = t.fLabel; + fIndex = t.fIndex; + + SetMainColor(t.GetMainColor()); + // TEveLine + fRnrLine = t.fRnrLine; + fRnrPoints = t.fRnrPoints; + // TLineAttrib + fLineColor = t.fLineColor; + fLineStyle = t.fLineStyle; + fLineWidth = t.fLineWidth; + fPathMarks.clear(); + SetPropagator(t.fPropagator); +} + +//______________________________________________________________________________ +void TEveTrack::SetPathMarks(const TEveTrack& t) +{ + // Copy path-marks from t. + + const std::vector& refs = t.GetPathMarksRef(); + for(std::vector::const_iterator i=refs.begin(); i!=refs.end(); ++i) + { + fPathMarks.push_back(new TEvePathMark(**i)); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrack::SetPropagator(TEveTrackPropagator* rs) +{ + // Set track's render style. + // Reference counts of old and new render-style are updated. + + if (fPropagator == rs) return; + if (fPropagator) fPropagator->DecRefCount(this); + fPropagator = rs; + if (fPropagator) rs->IncRefCount(this); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrack::SetAttLineAttMarker(TEveTrackList* tl) +{ + // Set line and marker attributes from TEveTrackList. + + SetLineColor(tl->GetLineColor()); + SetLineStyle(tl->GetLineStyle()); + SetLineWidth(tl->GetLineWidth()); + + SetMarkerColor(tl->GetMarkerColor()); + SetMarkerStyle(tl->GetMarkerStyle()); + SetMarkerSize(tl->GetMarkerSize()); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrack::MakeTrack(Bool_t recurse) +{ + // Calculate track representation based on track data and current + // settings of the render-style. + // If recurse is true, descend into children. + + Reset(0); + + TEveTrackPropagator& RS((fPropagator != 0) ? *fPropagator : TEveTrackPropagator::fgDefStyle); + if ((TMath::Abs(fV.z) < RS.fMaxZ) && + (fV.x*fV.x + fV.y*fV.y < RS.fMaxR*RS.fMaxR)) + { + TEveVector currP = fP; + Bool_t decay = kFALSE; + fPropagator->InitTrack(fV, fP, fBeta, fCharge); + for (std::vector::iterator i=fPathMarks.begin(); i!=fPathMarks.end(); ++i) + { + TEvePathMark* pm = *i; + if (RS.fFitReferences && pm->type == TEvePathMark::Reference) + { + if (TMath::Abs(pm->V.z) > RS.fMaxZ || + TMath::Sqrt(pm->V.x*pm->V.x + pm->V.y*pm->V.y) > RS.fMaxR) + goto bounds; + // printf("%s fit reference \n", fName.Data()); + if (fPropagator->GoToVertex(pm->V, currP)) { + currP.x = pm->P.x; currP.y = pm->P.y; currP.z = pm->P.z; + } + } + else if (RS.fFitDaughters && pm->type == TEvePathMark::Daughter) + { + if (TMath::Abs(pm->V.z) > RS.fMaxZ || + TMath::Sqrt(pm->V.x*pm->V.x + pm->V.y*pm->V.y) > RS.fMaxR) + goto bounds; + // printf("%s fit daughter \n", fName.Data()); + if (fPropagator->GoToVertex(pm->V, currP)) { + currP.x -= pm->P.x; currP.y -= pm->P.y; currP.z -= pm->P.z; + } + } + else if (RS.fFitDecay && pm->type == TEvePathMark::Decay) + { + if (TMath::Abs(pm->V.z) > RS.fMaxZ || + TMath::Sqrt(pm->V.x*pm->V.x + pm->V.y*pm->V.y) > RS.fMaxR) + goto bounds; + // printf("%s fit decay \n", fName.Data()); + fPropagator->GoToVertex(pm->V, currP); + decay = true; + break; + } + } // loop path-marks + + bounds: + if(!decay || RS.fFitDecay == kFALSE) + { + // printf("%s loop to bounds \n",fName.Data() ); + fPropagator->GoToBounds(currP); + } + // make_polyline: + fPropagator->FillPointSet(this); + fPropagator->ResetTrack(); + } + + if (recurse) + { + for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) + { + TEveTrack* t = dynamic_cast(*i); + if (t) t->MakeTrack(recurse); + } + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +TClass* TEveTrack::ProjectedClass() const +{ + // Virtual from TEveProjectable, return TEveTrackProjected class. + + return TEveTrackProjected::Class(); +} + +/******************************************************************************/ + +namespace { + +struct cmp_pathmark +{ + bool operator()(TEvePathMark* const & a, TEvePathMark* const & b) + { return a->time < b->time; } +}; + +} + +//______________________________________________________________________________ +void TEveTrack::SortPathMarksByTime() +{ + // Sort registerd pat-marks by time. + + std::sort(fPathMarks.begin(), fPathMarks.end(), cmp_pathmark()); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrack::ImportHits() +{ + // Import hits with same label as the track. + // Uses macro "hits_from_label.C". + + TEveUtil::LoadMacro("hits_from_label.C"); + gROOT->ProcessLine(Form("hits_from_label(%d, (TEveElement*)%p);", + fLabel, this)); +} + +//______________________________________________________________________________ +void TEveTrack::ImportClusters() +{ + // Import clusters with same label as the track. + // Uses macro "clusters_from_label.C". + + TEveUtil::LoadMacro("clusters_from_label.C"); + gROOT->ProcessLine(Form("clusters_from_label(%d, (TEveElement*)%p);", + fLabel, this)); +} + +//______________________________________________________________________________ +void TEveTrack::ImportClustersFromIndex() +{ + // Import clusters marked with same reconstructed track index as the track. + // Uses macro "clusters_from_index.C". + + static const TEveException eH("TEveTrack::ImportClustersFromIndex "); + + if (fIndex == kMinInt) + throw(eH + "index not set."); + + TEveUtil::LoadMacro("clusters_from_index.C"); + gROOT->ProcessLine(Form("clusters_from_index(%d, (TEveElement*)%p);", + fIndex, this)); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrack::ImportKine() +{ + // Import kinematics of the track's label recursively. + // Uses macro "kine_tracks.C". + + static const TEveException eH("TEveTrack::ImportKine "); + + if (fLabel == kMinInt) + throw(eH + "label not set."); + + Int_t label; + if (fLabel < 0) { + Warning(eH, "label negative, taking absolute value."); + label = -fLabel; + } else { + label = fLabel; + } + + TEveUtil::LoadMacro("kine_tracks.C"); + gROOT->ProcessLine(Form("kine_track(%d, kTRUE, kTRUE, kTRUE, kTRUE, (TEveElement*)%p);", + label, this)); + +} + +//______________________________________________________________________________ +void TEveTrack::ImportKineWithArgs(Bool_t importMother, Bool_t importDaugters, + Bool_t colorPdg, Bool_t recurse) +{ + // Import kinematics of the track's label. Arguments steer the + // import process: + // importMother import particle with track's label + // importDaugters import direct daughters of label + // colorPdg color kinematics by PDG code + // recurse recursive import of daughters' daughters + // Uses macro "kine_tracks.C". + + static const TEveException eH("TEveTrack::ImportKineWithArgs "); + + if (fLabel == kMinInt) + throw(eH + "label not set."); + + Int_t label; + if (fLabel < 0) { + Warning(eH, "label negative, taking absolute value."); + label = -fLabel; + } else { + label = fLabel; + } + + TEveUtil::LoadMacro("kine_tracks.C"); + gROOT->ProcessLine(Form("kine_track(%d, %d, %d, %d, %d, (TEveElement*)%p);", + label, importMother, importDaugters, colorPdg, recurse, this)); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrack::PrintKineStack() +{ + // Print kinematics pertaining to track's label. + // Uses macro "print_kine_from_label.C". + + static const TEveException eH("TEveTrack::PrintKineStack "); + + if (fLabel == kMinInt) + throw(eH + "label not set."); + + Int_t label; + if (fLabel < 0) { + Warning(eH, "label negative, taking absolute value."); + label = -fLabel; + } else { + label = fLabel; + } + + TEveUtil::LoadMacro("print_kine_from_label.C"); + gROOT->ProcessLine(Form("print_kine_from_label(%d);", label)); +} + +//______________________________________________________________________________ +void TEveTrack::PrintPathMarks() +{ + // Print registered path-marks. + + static const TEveException eH("TEveTrack::PrintPathMarks "); + + printf("TEveTrack '%s', number of path marks %ld, label %d\n", + GetName(), fPathMarks.size(), fLabel); + + TEvePathMark* pm; + for(vpPathMark_i i=fPathMarks.begin(); i!=fPathMarks.end(); i++) + { + pm = *i; + printf(" %-9s p: %8f %8f %8f Vertex: %8e %8e %8e %g \n", + pm->type_name(), + pm->P.x, pm->P.y, pm->P.z, + pm->V.x, pm->V.y, pm->V.z, + pm->time); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrack::CtrlClicked(TEveTrack* track) +{ + // Emits "CtrlClicked(TEveTrack*)" signal. + // Called from TEveTrackGL on secondary-selection. + + Emit("CtrlClicked(TEveTrack*)", (Long_t)track); +} + +//______________________________________________________________________________ +void TEveTrack::SetLineStyle(Style_t lstyle) +{ + // Set line-style of the track. + // The style is propagated to projected tracks. + + TAttLine::SetLineStyle(lstyle); + std::list::iterator pi = fProjectedList.begin(); + while (pi != fProjectedList.end()) + { + TEveTrack* pt = dynamic_cast(*pi); + if (pt) + { + pt->SetLineStyle(lstyle); + pt->ElementChanged(); + } + ++pi; + } +} + + +/******************************************************************************/ +/******************************************************************************/ +//______________________________________________________________________________ +// TEveTrackList +// +// A list of tracks supporting change of common attributes and +// selection based on track parameters. + +ClassImp(TEveTrackList) + +//______________________________________________________________________________ +TEveTrackList::TEveTrackList(TEveTrackPropagator* rs) : + TEveElementList(), + TAttMarker(1, 20, 1), + TAttLine(1,1,1), + + fRecurse(kTRUE), + fPropagator(0), + fRnrLine(kTRUE), + fRnrPoints(kFALSE), + + fMinPt (0), fMaxPt (0), fLimPt (0), + fMinP (0), fMaxP (0), fLimP (0) +{ + // Constructor. If TrackRenderStyle argument is 0, a new default + // render-style is created. + + fChildClass = TEveTrack::Class(); // override member from base TEveElementList + + fMainColorPtr = &fLineColor; + if (fPropagator== 0) rs = new TEveTrackPropagator; + SetPropagator(rs); +} + +//______________________________________________________________________________ +TEveTrackList::TEveTrackList(const Text_t* name, TEveTrackPropagator* rs) : + TEveElementList(name), + TAttMarker(1, 20, 1), + TAttLine(1,1,1), + + fRecurse(kTRUE), + fPropagator(0), + fRnrLine(kTRUE), + fRnrPoints(kFALSE), + + fMinPt (0), fMaxPt (0), fLimPt (0), + fMinP (0), fMaxP (0), fLimP (0) +{ + // Constructor. If TrackRenderStyle argument is 0, a new default + // render-style is created. + + fChildClass = TEveTrack::Class(); // override member from base TEveElementList + + fMainColorPtr = &fLineColor; + if (fPropagator== 0) rs = new TEveTrackPropagator; + SetPropagator(rs); +} + +//______________________________________________________________________________ +TEveTrackList::~TEveTrackList() +{ + // Destructor. + + SetPropagator(0); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackList::SetPropagator(TEveTrackPropagator* rs) +{ + // Set default render-style for tracks. + // This is not enforced onto the tracks themselves but this is the + // render-style that is show in the TEveTrackListEditor. + + if (fPropagator == rs) return; + if (fPropagator) fPropagator->DecRefCount(); + fPropagator = rs; + if (fPropagator) rs->IncRefCount(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackList::MakeTracks(Bool_t recurse) +{ + // Regenerate the visual representations of tracks. + // The momentum limits are rescanned during the same traversal. + + fLimPt = fLimP = 0; + + for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) + { + TEveTrack* track = (TEveTrack*)(*i); + track->MakeTrack(recurse); + + fLimPt = TMath::Max(fLimPt, track->fP.Perp()); + fLimP = TMath::Max(fLimP, track->fP.Mag()); + if (recurse) + FindMomentumLimits(*i, recurse); + } + + fLimPt = RoundMomentumLimit(fLimPt); + fLimP = RoundMomentumLimit(fLimP); + if (fMaxPt == 0) fMaxPt = fLimPt; + if (fMaxP == 0) fMaxP = fLimP; + + gEve->Redraw3D(); +} + +//______________________________________________________________________________ +void TEveTrackList::FindMomentumLimits(TEveElement* el, Bool_t recurse) +{ + // Loop over track elements of argument el and find highest pT and p. + // These are stored in members fLimPt and fLimP. + + for (List_i i=el->BeginChildren(); i!=el->EndChildren(); ++i) + { + TEveTrack* track = dynamic_cast(*i); + if (track) + { + fLimPt = TMath::Max(fLimPt, track->fP.Perp()); + fLimP = TMath::Max(fLimP, track->fP.Mag()); + if (recurse) + FindMomentumLimits(*i, recurse); + } + } +} + +//______________________________________________________________________________ +Float_t TEveTrackList::RoundMomentumLimit(Float_t x) +{ + // Round the momentum limit up to a nice value. + + using namespace TMath; + Double_t fac = Power(10, 1 - Floor(Log10(x))); + return Ceil(fac*x) / fac; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackList::SetRnrLine(Bool_t rnr) +{ + // Set rendering of track as line for the list and the elements. + + for (List_i i=BeginChildren(); i!=EndChildren(); ++i) + { + TEveTrack* track = (TEveTrack*)(*i); + if (track->GetRnrLine() == fRnrLine) + track->SetRnrLine(rnr); + if (fRecurse) + SetRnrLine(rnr, *i); + } + fRnrLine = rnr; +} + +//______________________________________________________________________________ +void TEveTrackList::SetRnrLine(Bool_t rnr, TEveElement* el) +{ + // Set rendering of track as line for children of el. + + TEveTrack* track; + for (List_i i=el->BeginChildren(); i!=el->EndChildren(); ++i) + { + track = dynamic_cast(*i); + if (track && (track->GetRnrLine() == fRnrLine)) + track->SetRnrLine(rnr); + if (fRecurse) + SetRnrLine(rnr, *i); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackList::SetRnrPoints(Bool_t rnr) +{ + // Set rendering of track as points for the list and the elements. + + for (List_i i=BeginChildren(); i!=EndChildren(); ++i) + { + TEveTrack* track = (TEveTrack*)(*i); + if (track->GetRnrPoints() == fRnrPoints) + track->SetRnrPoints(rnr); + if (fRecurse) + SetRnrPoints(rnr, *i); + } + fRnrPoints = rnr; +} + +//______________________________________________________________________________ +void TEveTrackList::SetRnrPoints(Bool_t rnr, TEveElement* el) +{ + // Set rendering of track as points for children of el. + + TEveTrack* track; + for (List_i i=el->BeginChildren(); i!=el->EndChildren(); ++i) + { + track = dynamic_cast(*i); + if (track) + if (track->GetRnrPoints() == fRnrPoints) + track->SetRnrPoints(rnr); + if (fRecurse) + SetRnrPoints(rnr, *i); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackList::SetMainColor(Color_t col) +{ + // Set main (line) color for the list and the elements. + + for (List_i i=BeginChildren(); i!=EndChildren(); ++i) + { + TEveTrack* track = (TEveTrack*)(*i); + if (track->GetLineColor() == fLineColor) + track->SetLineColor(col); + if (fRecurse) + SetLineColor(col, *i); + } + TEveElement::SetMainColor(col); +} + +//______________________________________________________________________________ +void TEveTrackList::SetLineColor(Color_t col, TEveElement* el) +{ + // Set line color for children of el. + + TEveTrack* track; + for (List_i i=el->BeginChildren(); i!=el->EndChildren(); ++i) + { + track = dynamic_cast(*i); + if (track && track->GetLineColor() == fLineColor) + track->SetLineColor(col); + if (fRecurse) + SetLineColor(col, *i); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackList::SetLineWidth(Width_t width) +{ + // Set line width for the list and the elements. + + for (List_i i=BeginChildren(); i!=EndChildren(); ++i) + { + TEveTrack* track = (TEveTrack*)(*i); + if (track->GetLineWidth() == fLineWidth) + track->SetLineWidth(width); + if (fRecurse) + SetLineWidth(width, *i); + } + fLineWidth=width; +} + +//______________________________________________________________________________ +void TEveTrackList::SetLineWidth(Width_t width, TEveElement* el) +{ + // Set line width for children of el. + + TEveTrack* track; + for (List_i i=el->BeginChildren(); i!=el->EndChildren(); ++i) + { + track = dynamic_cast(*i); + if (track && track->GetLineWidth() == fLineWidth) + track->SetLineWidth(width); + if (fRecurse) + SetLineWidth(width, *i); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackList::SetLineStyle(Style_t style) +{ + // Set line style for the list and the elements. + + for (List_i i=BeginChildren(); i!=EndChildren(); ++i) + { + TEveTrack* track = (TEveTrack*)(*i); + if (track->GetLineStyle() == fLineStyle) + track->SetLineStyle(style); + if (fRecurse) + SetLineStyle(style, *i); + } + fLineStyle=style; +} + +//______________________________________________________________________________ +void TEveTrackList::SetLineStyle(Style_t style, TEveElement* el) +{ + // Set line style for children of el. + + TEveTrack* track; + for (List_i i=el->BeginChildren(); i!=el->EndChildren(); ++i) + { + track = dynamic_cast(*i); + if (track && track->GetLineStyle() == fLineStyle) + track->SetLineStyle(style); + if (fRecurse) + SetLineStyle(style, *i); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackList::SetMarkerStyle(Style_t style) +{ + // Set marker style for the list and the elements. + + for (List_i i=BeginChildren(); i!=EndChildren(); ++i) + { + TEveTrack* track = (TEveTrack*)(*i); + if (track->GetMarkerStyle() == fMarkerStyle) + track->SetMarkerStyle(style); + if (fRecurse) + SetMarkerStyle(style, *i); + } + fMarkerStyle=style; +} + +//______________________________________________________________________________ +void TEveTrackList::SetMarkerStyle(Style_t style, TEveElement* el) +{ + // Set marker style for children of el. + + TEveTrack* track; + for (List_i i=el->BeginChildren(); i!=el->EndChildren(); ++i) + { + track = dynamic_cast(*i); + if (track && track->GetMarkerStyle() == fMarkerStyle) + track->SetMarkerStyle(style); + if(fRecurse) + SetMarkerStyle(style, *i); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackList::SetMarkerColor(Color_t col) +{ + // Set marker color for the list and the elements. + + for (List_i i=BeginChildren(); i!=EndChildren(); ++i) + { + TEveTrack* track = (TEveTrack*)(*i); + if (track->GetMarkerColor() == fMarkerColor) + track->SetMarkerColor(col); + if (fRecurse) + SetMarkerColor(col, *i); + } + fMarkerColor=col; +} + +//______________________________________________________________________________ +void TEveTrackList::SetMarkerColor(Color_t col, TEveElement* el) +{ + // Set marker color for children of el. + + TEveTrack* track; + for (List_i i=el->BeginChildren(); i!=el->EndChildren(); ++i) + { + track = dynamic_cast(*i); + if (track && track->GetMarkerColor() == fMarkerColor) + track->SetMarkerColor(col); + if (fRecurse) + SetMarkerColor(col, *i); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackList::SetMarkerSize(Size_t size) +{ + // Set marker size for the list and the elements. + + for (List_i i=BeginChildren(); i!=EndChildren(); ++i) + { + TEveTrack* track = (TEveTrack*)(*i); + if (track->GetMarkerSize() == fMarkerSize) + track->SetMarkerSize(size); + if (fRecurse) + SetMarkerSize(size, *i); + } + fMarkerSize=size; +} + +//______________________________________________________________________________ +void TEveTrackList::SetMarkerSize(Size_t size, TEveElement* el) +{ + // Set marker size for children of el. + + TEveTrack* track; + for (List_i i=el->BeginChildren(); i!=el->EndChildren(); ++i) + { + track = dynamic_cast(*i); + if (track && track->GetMarkerSize() == fMarkerSize) + track->SetMarkerSize(size); + if (fRecurse) + SetMarkerSize(size, *i); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackList::SelectByPt(Float_t min_pt, Float_t max_pt) +{ + // Select visibility of tracks by transverse momentum. + // If data-member fRecurse is set, the selection is applied + // recursively to all children. + + fMinPt = min_pt; + fMaxPt = max_pt; + + const Float_t minptsq = min_pt*min_pt; + const Float_t maxptsq = max_pt*max_pt; + + for (List_i i=BeginChildren(); i!=EndChildren(); ++i) + { + const Float_t ptsq = ((TEveTrack*)(*i))->fP.Perp2(); + Bool_t on = ptsq >= minptsq && ptsq <= maxptsq; + (*i)->SetRnrState(on); + if (on && fRecurse) + SelectByPt(min_pt, max_pt, *i); + } +} + +//______________________________________________________________________________ +void TEveTrackList::SelectByPt(Float_t min_pt, Float_t max_pt, TEveElement* el) +{ + // Select visibility of el's children tracks by transverse momentum. + + const Float_t minptsq = min_pt*min_pt; + const Float_t maxptsq = max_pt*max_pt; + + for (List_i i=el->BeginChildren(); i!=el->EndChildren(); ++i) + { + TEveTrack* track = dynamic_cast(*i); + if (track) + { + const Float_t ptsq = track->fP.Perp2(); + Bool_t on = ptsq >= minptsq && ptsq <= maxptsq; + track->SetRnrState(on); + if (on && fRecurse) + SelectByPt(min_pt, max_pt, *i); + } + } +} + +//______________________________________________________________________________ +void TEveTrackList::SelectByP(Float_t min_p, Float_t max_p) +{ + // Select visibility of tracks by momentum. + // If data-member fRecurse is set, the selection is applied + // recursively to all children. + + fMinP = min_p; + fMaxP = max_p; + + const Float_t minpsq = min_p*min_p; + const Float_t maxpsq = max_p*max_p; + + for (List_i i=BeginChildren(); i!=EndChildren(); ++i) + { + const Float_t psq = ((TEveTrack*)(*i))->fP.Mag2(); + Bool_t on = psq >= minpsq && psq <= maxpsq; + (*i)->SetRnrState(psq >= minpsq && psq <= maxpsq); + if (on && fRecurse) + SelectByP(min_p, max_p, *i); + } +} + +//______________________________________________________________________________ +void TEveTrackList::SelectByP(Float_t min_p, Float_t max_p, TEveElement* el) +{ + // Select visibility of el's children tracks by momentum. + + const Float_t minpsq = min_p*min_p; + const Float_t maxpsq = max_p*max_p; + + for (List_i i=el->BeginChildren(); i!=el->EndChildren(); ++i) + { + TEveTrack* track = dynamic_cast(*i); + if (track) + { + const Float_t psq = ((TEveTrack*)(*i))->fP.Mag2(); + Bool_t on = psq >= minpsq && psq <= maxpsq; + track->SetRnrState(on); + if (on && fRecurse) + SelectByP(min_p, max_p, *i); + } + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +TEveTrack* TEveTrackList::FindTrackByLabel(Int_t label) +{ + // Find track by label, select it and display it in the editor. + + for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) { + if (((TEveTrack*)(*i))->GetLabel() == label) { + TGListTree *lt = gEve->GetLTEFrame()->GetListTree(); + TGListTreeItem *mlti = lt->GetSelected(); + if (mlti->GetUserData() != this) + mlti = FindListTreeItem(lt); + TGListTreeItem *tlti = (*i)->FindListTreeItem(lt, mlti); + lt->HighlightItem(tlti); + lt->SetSelected(tlti); + gEve->EditElement(*i); + return (TEveTrack*) *i; + } + } + return 0; +} + +//______________________________________________________________________________ +TEveTrack* TEveTrackList::FindTrackByIndex(Int_t index) +{ + // Find track by index, select it and display it in the editor. + + for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) { + if (((TEveTrack*)(*i))->GetIndex() == index) { + TGListTree *lt = gEve->GetLTEFrame()->GetListTree(); + TGListTreeItem *mlti = lt->GetSelected(); + if (mlti->GetUserData() != this) + mlti = FindListTreeItem(lt); + TGListTreeItem *tlti = (*i)->FindListTreeItem(lt, mlti); + lt->HighlightItem(tlti); + lt->SetSelected(tlti); + gEve->EditElement(*i); + return (TEveTrack*) *i; + } + } + return 0; +} + +//______________________________________________________________________________ +void TEveTrackList::ImportHits() +{ + // Import hits for all track. + + for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) { + ((TEveTrack*)(*i))->ImportHits(); + } +} + +//______________________________________________________________________________ +void TEveTrackList::ImportClusters() +{ + // Import clusters for all track. + + for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) { + ((TEveTrack*)(*i))->ImportClusters(); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +TClass* TEveTrackList::ProjectedClass() const +{ + // Virtual from TEveProjectable, returns TEveTrackListProjected class. + + return TEveTrackListProjected::Class(); +} + + +/******************************************************************************/ +/******************************************************************************/ + +#include + +//______________________________________________________________________________ +// TEveTrackCounter +// +// Provides event-based method for tagging of good / bad (or primary / +// secondary) tracks. A report can be written into a text file. +// +// TEveTrack status is toggled by using secondary-selection / ctrl-click +// functionality of the GL viewer. +// +// Some of the functionality is implemented in TEveTrackCounterEditor +// class. + +ClassImp(TEveTrackCounter) + +//______________________________________________________________________________ +TEveTrackCounter* TEveTrackCounter::fgInstance = 0; + +//______________________________________________________________________________ +TEveTrackCounter::TEveTrackCounter(const Text_t* name, const Text_t* title) : + TEveElement(), + TNamed(name, title), + + fBadLineStyle (6), + fClickAction (CA_ToggleTrack), + fAllTracks (0), + fGoodTracks (0), + fTrackLists () +{ + // Constructor. + // Connects to global signal "TEveTrack", "CtrlClicked(TEveTrack*)". + + if (fgInstance == 0) fgInstance = this; + TQObject::Connect("TEveTrack", "CtrlClicked(TEveTrack*)", + "TEveTrackCounter", this, "DoTrackAction(TEveTrack*)"); +} + +//______________________________________________________________________________ +TEveTrackCounter::~TEveTrackCounter() +{ + // Destructor. + // Disconnect from the global track signals. + + TQObject::Disconnect("TEveTrack", "DoTrackAction(TEveTrack*)"); + if (fgInstance == this) fgInstance = 0; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackCounter::Reset() +{ + // Reset internal track-counters and track-list. + + printf("TEveTrackCounter::Reset()\n"); + fAllTracks = 0; + fGoodTracks = 0; + TIter next(&fTrackLists); + TEveTrackList* tlist; + while ((tlist = dynamic_cast(next()))) + tlist->DecDenyDestroy(); + fTrackLists.Clear("nodelete"); +} + +//______________________________________________________________________________ +void TEveTrackCounter::RegisterTracks(TEveTrackList* tlist, Bool_t goodTracks) +{ + // Register tracks from tlist and tlist itself. + // If goodTracks is true, they are considered as primary/good + // tracks. + + tlist->IncDenyDestroy(); + fTrackLists.Add(tlist); + + List_i i = tlist->BeginChildren(); + while (i != tlist->EndChildren()) + { + TEveTrack* t = dynamic_cast(*i); + if (t != 0) + { + if (goodTracks) + { + ++fGoodTracks; + } else { + t->SetLineStyle(fBadLineStyle); + } + ++fAllTracks; + } + ++i; + } +} + +//______________________________________________________________________________ +void TEveTrackCounter::DoTrackAction(TEveTrack* track) +{ + // Slot called when track is ctrl-clicked. + // + // No check is done if track actually belongs to one of the + // registered track-lists. + // + // Probably it would be safer to copy good/bad tracks into special + // sub-containers. + // In this case one should also override RemoveElementLocal. + + switch (fClickAction) + { + + case CA_PrintTrackInfo: + { + printf("TEveTrack '%s'\n", track->GetObject()->GetName()); + TEveVector &v = track->fV, &p = track->fP; + printf(" Vx=%f, Vy=%f, Vz=%f; Pt=%f, Pz=%f, phi=%f)\n", + v.x, v.y, v.z, p.Perp(), p.z, TMath::RadToDeg()*p.Phi()); + printf(" \n"); + break; + } + + case CA_ToggleTrack: + { + if (track->GetLineStyle() == 1) + { + track->SetLineStyle(fBadLineStyle); + --fGoodTracks; + } else { + track->SetLineStyle(1); + ++fGoodTracks; + } + track->ElementChanged(); + gEve->Redraw3D(); + + printf("TEveTrackCounter::CountTrack All=%d, Good=%d, Bad=%d\n", + fAllTracks, fGoodTracks, fAllTracks-fGoodTracks); + + if (gEve->GetEditor()->GetModel() == GetObject()) + gEve->EditElement(this); + + break; + } + + } // end switch fClickAction +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackCounter::OutputEventTracks(FILE* out) +{ + // Print good-track summary into a plain-text file by iteration + // through all registered track-lists. + // State of each track is determined by its line-style, it is + // considered a good track if it's line style is solid. + + if (out == 0) + { + out = stdout; + fprintf(out, "TEveTrackCounter::FinalizeEvent()\n"); + } + + fprintf(out, "Event = %d Ntracks = %d\n", fEventId, fGoodTracks); + + TIter tlists(&fTrackLists); + TEveTrackList* tlist; + Int_t cnt = 0; + while ((tlist = (TEveTrackList*) tlists()) != 0) + { + List_i i = tlist->BeginChildren(); + while (i != tlist->EndChildren()) + { + TEveTrack* t = dynamic_cast(*i); + if (t != 0 && t->GetLineStyle() == 1) + { + ++cnt; + fprintf(out, " %2d: chg=%+2d pt=%8.5f eta=%+8.5f\n", + cnt, t->fCharge, t->fP.Perp(), t->fP.Eta()); + } + ++i; + } + } +} diff --git a/eve/src/TEveTrackEditor.cxx b/eve/src/TEveTrackEditor.cxx new file mode 100644 index 0000000000..26ee8a2bd9 --- /dev/null +++ b/eve/src/TEveTrackEditor.cxx @@ -0,0 +1,511 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include // File input/output for track-count status. + +//______________________________________________________________________________ +// TEveTrackEditor +// +// Editor for TEveTrack class. + +ClassImp(TEveTrackEditor) + +//______________________________________________________________________________ +TEveTrackEditor::TEveTrackEditor(const TGWindow *p, Int_t width, Int_t height, + UInt_t options, Pixel_t back) : + TGedFrame(p, width, height, options | kVerticalFrame, back), + fM(0), + fRSEditor(0) +{ + MakeTitle("TEveTrack"); + + TGHorizontalFrame* f = new TGHorizontalFrame(this); + + fRSEditor = new TGTextButton(f, "Edit Propagator"); + fRSEditor->Connect("Clicked()", "TEveTrackEditor", this, "DoEditPropagator()"); + f->AddFrame(fRSEditor, new TGLayoutHints(kLHintsLeft, 2, 1, 4, 4)); + + AddFrame(f, new TGLayoutHints(kLHintsTop, 0,0,2,1)); +} + +//______________________________________________________________________________ +void TEveTrackEditor::SetModel(TObject* obj) +{ + fM = dynamic_cast(obj); +} + +//______________________________________________________________________________ +void TEveTrackEditor::DoEditPropagator() +{ + fGedEditor->SetModel(fGedEditor->GetPad(), fM->GetPropagator(), kButton1Down); +} + + +//______________________________________________________________________________ +// TEveTrackListEditor +// +// Editor for TEveTrackList class. + +ClassImp(TEveTrackListEditor) + +//______________________________________________________________________________ +TEveTrackListEditor::TEveTrackListEditor(const TGWindow *p, + Int_t width, Int_t height, + UInt_t options, Pixel_t back) : + TGedFrame(p, width, height, options | kVerticalFrame, back), + + fTC (0), + fPtRange (0), + fPRange (0), + fRSSubEditor(0) +{ + { + TGHorizontalFrame* f = new TGHorizontalFrame(this); + + fRnrPoints = new TGCheckButton(f, "Draw Marker"); + f->AddFrame(fRnrPoints, new TGLayoutHints(kLHintsLeft, 2,1,0,0)); + fRnrPoints->Connect("Toggled(Bool_t)"," TEveTrackListEditor", this, "DoRnrPoints()"); + + fRnrLine = new TGCheckButton(f, "Draw TEveLine"); + f->AddFrame(fRnrLine, new TGLayoutHints(kLHintsLeft, 1,2,0,0)); + fRnrLine->Connect("Toggled(Bool_t)", "TEveTrackListEditor", this, "DoRnrLine()"); + + AddFrame(f, new TGLayoutHints(kLHintsTop, 0,0,2,1)); + } + { // --- Selectors + Int_t labelW = 51; + Int_t dbW = 210; + + fPtRange = new TEveGDoubleValuator(this,"Pt rng:", 40, 0); + fPtRange->SetNELength(6); + fPtRange->SetLabelWidth(labelW); + fPtRange->Build(); + fPtRange->GetSlider()->SetWidth(dbW); + fPtRange->SetLimits(0, 10, TGNumberFormat::kNESRealTwo); + fPtRange->Connect("ValueSet()", + "TEveTrackListEditor", this, "DoPtRange()"); + AddFrame(fPtRange, new TGLayoutHints(kLHintsTop, 1, 1, 4, 1)); + + fPRange = new TEveGDoubleValuator(this,"P rng:", 40, 0); + fPRange->SetNELength(6); + fPRange->SetLabelWidth(labelW); + fPRange->Build(); + fPRange->GetSlider()->SetWidth(dbW); + fPRange->SetLimits(0, 100, TGNumberFormat::kNESRealTwo); + fPRange->Connect("ValueSet()", + "TEveTrackListEditor", this, "DoPRange()"); + AddFrame(fPRange, new TGLayoutHints(kLHintsTop, 1, 1, 4, 1)); + } + + MakeTitle("RenderStyle"); + fRSSubEditor = new TEveTrackPropagatorSubEditor(this); + fRSSubEditor->Connect("Changed()", "TEveTrackListEditor", this, "Update()"); + AddFrame(fRSSubEditor, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 2, 0,0,0)); + CreateRefsTab(); +} + +//______________________________________________________________________________ +TEveTrackListEditor::~TEveTrackListEditor() +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackListEditor::CreateRefsTab() +{ + fRefs = CreateEditorTabSubFrame("Refs"); + + TGCompositeFrame *title1 = new TGCompositeFrame(fRefs, 145, 10, + kHorizontalFrame | + kLHintsExpandX | + kFixedWidth | + kOwnBackground); + title1->AddFrame(new TGLabel(title1, "PathMarks"), + new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); + title1->AddFrame(new TGHorizontal3DLine(title1), + new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7)); + fRefs->AddFrame(title1, new TGLayoutHints(kLHintsTop, 0, 0, 2, 0)); + + // path marks + fRSSubEditor->CreateRefsContainer(fRefs); + fRSSubEditor->fPMAtt->SetGedEditor((TGedEditor*)gEve->GetEditor()); + fRSSubEditor->fFVAtt->SetGedEditor((TGedEditor*)gEve->GetEditor()); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackListEditor::SetModel(TObject* obj) +{ + fTC = dynamic_cast(obj); + fRnrLine ->SetState(fTC->GetRnrLine() ? kButtonDown : kButtonUp); + fRnrPoints->SetState(fTC->GetRnrPoints() ? kButtonDown : kButtonUp); + + Float_t llim; + fPtRange->SetValues(fTC->fMinPt, fTC->fMaxPt); + llim = TMath::Log10(fTC->fLimPt); + fPtRange->SetLimits(0, fTC->fLimPt, llim < 2 ? TGNumberFormat::kNESRealTwo : (llim < 3 ? TGNumberFormat::kNESRealOne : TGNumberFormat::kNESInteger)); + fPRange ->SetValues(fTC->fMinP, fTC->fMaxP); + llim = TMath::Log10(fTC->fLimP); + fPRange ->SetLimits(0, fTC->fLimP, llim < 2 ? TGNumberFormat::kNESRealTwo : (llim < 3 ? TGNumberFormat::kNESRealOne : TGNumberFormat::kNESInteger)); + + fRSSubEditor->SetModel(fTC->GetPropagator()); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackListEditor::DoRnrLine() +{ + fTC->SetRnrLine(fRnrLine->IsOn()); + Update(); +} + +//______________________________________________________________________________ +void TEveTrackListEditor::DoRnrPoints() +{ + fTC->SetRnrPoints(fRnrPoints->IsOn()); + Update(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackListEditor::DoPtRange() +{ + fTC->SelectByPt(fPtRange->GetMin(), fPtRange->GetMax()); + Update(); +} + +//______________________________________________________________________________ +void TEveTrackListEditor::DoPRange() +{ + fTC->SelectByP(fPRange->GetMin(), fPRange->GetMax()); + Update(); +} + + +/******************************************************************************/ +/******************************************************************************/ +/******************************************************************************/ + +#include +#include +#include + +//______________________________________________________________________________ +// TEveTrackCounterEditor +// +// Editor for TEveTrackCounter class. + +ClassImp(TEveTrackCounterEditor) + +//______________________________________________________________________________ +TEveTrackCounterEditor::TEveTrackCounterEditor(const TGWindow *p, Int_t width, Int_t height, + UInt_t options, Pixel_t back) : + TGedFrame(p, width, height, options | kVerticalFrame, back), + fM(0), + fClickAction (0), + fInfoLabel (0), + fEventId (0) +{ + MakeTitle("TEveTrackCounter"); + + Int_t labelW = 42; + + { // ClickAction + TGHorizontalFrame* f = new TGHorizontalFrame(this); + TGLabel* lab = new TGLabel(f, "Click:"); + f->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsBottom, 1, 10, 1, 2)); + fClickAction = new TGComboBox(f); + fClickAction->AddEntry("Print", 0); + fClickAction->AddEntry("Toggle", 1); + TGListBox* lb = fClickAction->GetListBox(); + lb->Resize(lb->GetWidth(), 2*16); + fClickAction->Resize(70, 20); + fClickAction->Connect("Selected(Int_t)", "TEveTrackCounterEditor", this, + "DoClickAction(Int_t)"); + f->AddFrame(fClickAction, new TGLayoutHints(kLHintsLeft, 1, 2, 1, 1)); + + AddFrame(f); + } + + { // Status + TGHorizontalFrame* f = new TGHorizontalFrame(this); + TGLabel* lab = new TGLabel(f, "Status:"); + f->AddFrame(lab, new TGLayoutHints(kLHintsLeft, 1, 5, 1, 2)); + + fInfoLabel = new TGLabel(f); + f->AddFrame(fInfoLabel, new TGLayoutHints(kLHintsLeft|kLHintsExpandX, 1, 9, 1, 2)); + + AddFrame(f); + } + + { + TGHorizontalFrame* f = new TGHorizontalFrame(this, 210, 20, kFixedWidth); + + TGHorizontalFrame* g = new TGHorizontalFrame(f, labelW, 0, kFixedWidth); + TGLabel* l = new TGLabel(g, "View:"); + g->AddFrame(l, new TGLayoutHints(kLHintsLeft, 0,0,4,0)); + f->AddFrame(g); + + TGTextButton* b; + + b = new TGTextButton(f, "Orto XY"); + f->AddFrame(b, new TGLayoutHints(kLHintsLeft|kLHintsExpandX, 1, 1, 0, 0)); + b->Connect("Clicked()", "TEveTrackCounterEditor", this, "DoOrtoXY()"); + + b = new TGTextButton(f, "Orto ZY"); + f->AddFrame(b, new TGLayoutHints(kLHintsLeft|kLHintsExpandX, 1, 1, 0, 0)); + b->Connect("Clicked()", "TEveTrackCounterEditor", this, "DoOrtoZY()"); + + b = new TGTextButton(f, "Persp"); + f->AddFrame(b, new TGLayoutHints(kLHintsLeft|kLHintsExpandX, 1, 1, 0, 0)); + b->Connect("Clicked()", "TEveTrackCounterEditor", this, "DoPersp()"); + + AddFrame(f); + } + + { + TGHorizontalFrame* f = new TGHorizontalFrame(this, 210, 20, kFixedWidth); + + TGHorizontalFrame* g = new TGHorizontalFrame(f, labelW, 0, kFixedWidth); + TGLabel* l = new TGLabel(g, "Event:"); + g->AddFrame(l, new TGLayoutHints(kLHintsLeft, 0,0,4,0)); + f->AddFrame(g); + + TGTextButton* b; + + b = new TGTextButton(f, "Prev"); + f->AddFrame(b, new TGLayoutHints(kLHintsLeft|kLHintsExpandX, 1, 1, 0, 0)); + b->Connect("Clicked()", "TEveTrackCounterEditor", this, "DoPrev()"); + + fEventId = new TGNumberEntry(f, 0, 3, -1,TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, + TGNumberFormat::kNELLimitMinMax, 0, 1000); + f->AddFrame(fEventId, new TGLayoutHints(kLHintsLeft|kLHintsExpandX, 1, 1, 0, 0)); + fEventId->Connect("ValueSet(Long_t)", "TEveTrackCounterEditor", this, "DoSetEvent()"); + + b = new TGTextButton(f, "Next"); + f->AddFrame(b, new TGLayoutHints(kLHintsLeft|kLHintsExpandX, 1, 1, 0, 0)); + b->Connect("Clicked()", "TEveTrackCounterEditor", this, "DoNext()"); + + AddFrame(f); + } + + { + TGHorizontalFrame* f = new TGHorizontalFrame(this, 210, 20, kFixedWidth); + + TGHorizontalFrame* g = new TGHorizontalFrame(f, labelW, 0, kFixedWidth); + TGLabel* l = new TGLabel(g, "Report:"); + g->AddFrame(l, new TGLayoutHints(kLHintsLeft, 0,0,4,0)); + f->AddFrame(g); + + TGTextButton* b; + + b = new TGTextButton(f, "Print"); + f->AddFrame(b, new TGLayoutHints(kLHintsLeft|kLHintsExpandX, 1, 1, 0, 0)); + b->Connect("Clicked()", "TEveTrackCounterEditor", this, "DoPrintReport()"); + + b = new TGTextButton(f, "File"); + f->AddFrame(b, new TGLayoutHints(kLHintsLeft|kLHintsExpandX, 1, 1, 0, 0)); + b->Connect("Clicked()", "TEveTrackCounterEditor", this, "DoFileReport()"); + + AddFrame(f, new TGLayoutHints(kLHintsLeft, 0, 0, 4, 0)); + } + { + TGHorizontalFrame* f = new TGHorizontalFrame(this, 210, 20, kFixedWidth); + + TGHorizontalFrame* g = new TGHorizontalFrame(f, labelW, 0, kFixedWidth); + TGLabel* l = new TGLabel(g, "Histos:"); + g->AddFrame(l, new TGLayoutHints(kLHintsLeft, 0,0,4,0)); + f->AddFrame(g); + + TGTextButton* b; + + b = new TGTextButton(f, "Show"); + f->AddFrame(b, new TGLayoutHints(kLHintsLeft|kLHintsExpandX, 1, 1, 0, 0)); + b->Connect("Clicked()", "TEveTrackCounterEditor", this, "DoShowHistos()"); + + AddFrame(f, new TGLayoutHints(kLHintsLeft, 0, 0, 0, 0)); + } + +} + +//______________________________________________________________________________ +TEveTrackCounterEditor::~TEveTrackCounterEditor() +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackCounterEditor::SetModel(TObject* obj) +{ + fM = dynamic_cast(obj); + + fClickAction->Select(fM->fClickAction, kFALSE); + fInfoLabel->SetText(Form("All: %3d; Primaries: %3d", fM->fAllTracks, fM->fGoodTracks)); + fEventId->SetNumber(fM->GetEventId()); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackCounterEditor::DoOrtoXY() +{ + gEve->GetGLViewer()->SetCurrentCamera(TGLViewer::kCameraOrthoXOY) ; +} + +//______________________________________________________________________________ +void TEveTrackCounterEditor::DoOrtoZY() +{ + gEve->GetGLViewer()->SetCurrentCamera(TGLViewer::kCameraOrthoZOY) ; +} + +//______________________________________________________________________________ +void TEveTrackCounterEditor::DoPersp() +{ + gEve->GetGLViewer()->SetCurrentCamera(TGLViewer::kCameraPerspXOZ) ; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackCounterEditor::DoPrev() +{ + TEveUtil::Macro("event_prev.C"); + gEve->EditElement(fM); +} + +//______________________________________________________________________________ +void TEveTrackCounterEditor::DoNext() +{ + TEveUtil::Macro("event_next.C"); + gEve->EditElement(fM); +} + +//______________________________________________________________________________ +void TEveTrackCounterEditor::DoSetEvent() +{ + TEveUtil::LoadMacro("event_goto.C"); + gROOT->ProcessLine(Form("event_goto(%d);", (Int_t) fEventId->GetNumber())); + gEve->EditElement(fM); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackCounterEditor::DoPrintReport() +{ + fM->OutputEventTracks(); +} + +//______________________________________________________________________________ +void TEveTrackCounterEditor::DoFileReport() +{ + TString file(Form("ev-report-%03d.txt", fM->GetEventId())); + if (gSystem->AccessPathName(file) == kFALSE) + { + Int_t ret; + new TGMsgBox(fClient->GetRoot(), GetMainFrame(), + "File Exist", + Form("Event record for event %d already exist.\n Replace?", fM->GetEventId()), + kMBIconQuestion, kMBYes | kMBNo, &ret); + if (ret == kMBNo) + return; + } + FILE* out = fopen(file, "w"); + fM->OutputEventTracks(out); + fclose(out); +} + +//______________________________________________________________________________ +void TEveTrackCounterEditor::DoShowHistos() +{ + TH1F* hcnt = new TH1F("cnt", "Primeries per event", 41, -0.5, 40.5); + TH1F* hchg = new TH1F("chg", "Primary charge", 3, -1.5, 1.5); + TH1F* hpt = new TH1F("pt", "pT distribution", 40, 0.0, 8.0); + TH1F* heta = new TH1F("eta", "eta distribution", 40, -1.0, 1.0); + + Int_t nn; // fscanf return value + + for (Int_t i=0; i<1000; ++i) + { + TString file(Form("ev-report-%03d.txt", i)); + if (gSystem->AccessPathName(file) == kFALSE) + { + Int_t ev, ntr; + FILE* f = fopen(file, "read"); + nn = fscanf(f, "Event = %d Ntracks = %d", &ev, &ntr); + if (nn != 2) { printf("SAFR1 %d\n", nn); fclose(f); return; } + hcnt->Fill(ntr); + for (Int_t t=0; tFill(chg); + hpt ->Fill(pt); + heta->Fill(eta); + } + fclose(f); + } + } + + TCanvas* c; + if (gPad == 0 || gPad->GetCanvas()->IsEditable() == kFALSE) { + c = new TCanvas("Scanwas", "Scanning Results", 800, 600); + } else { + c = gPad->GetCanvas(); + c->Clear(); + } + c->Divide(2, 2); + + c->cd(1); hcnt->Draw(); + c->cd(2); hchg->Draw(); + c->cd(3); hpt ->Draw(); + c->cd(4); heta->Draw(); + + c->Modified(); + c->Update(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackCounterEditor::DoClickAction(Int_t mode) +{ + fM->SetClickAction(mode); +} diff --git a/eve/src/TEveTrackGL.cxx b/eve/src/TEveTrackGL.cxx new file mode 100644 index 0000000000..3fe517e2e5 --- /dev/null +++ b/eve/src/TEveTrackGL.cxx @@ -0,0 +1,116 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include +#include + +#include + +#include + +//______________________________________________________________________________ +// TEveTrackGL +// +// GL-renderer for TEveTrack class. + +ClassImp(TEveTrackGL) + +//______________________________________________________________________________ +TEveTrackGL::TEveTrackGL() : TEveLineGL() +{ + // Default constructor. + + // fDLCache = false; // Disable display list. +} + +//______________________________________________________________________________ +TEveTrackGL::~TEveTrackGL() +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +Bool_t TEveTrackGL::SetModel(TObject* obj, const Option_t* /*opt*/) +{ + if(TEveLineGL::SetModel(obj) == kFALSE) return kFALSE; + if(SetModelCheckClass(obj, TEveTrack::Class())) { + fTrack = dynamic_cast(obj); + return kTRUE; + } + return kFALSE; +} +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackGL::ProcessSelection(TGLRnrCtx & /*rnrCtx*/, TGLSelectRecord & rec) +{ + // Processes secondary selection from TGLViewer. + // Calls TPointSet3D::PointSelected(Int_t) with index of selected + // point as an argument. + + printf("TEveTrackGL::ProcessSelection %d names on the stack (z1=%g, z2=%g).\n", + rec.GetN(), rec.GetMinZ(), rec.GetMaxZ()); + printf(" Names: "); + for (Int_t j=0; jCtrlClicked((TEveTrack*)fM); +} + +/******************************************************************************/ +void TEveTrackGL::DirectDraw(TGLRnrCtx & rnrCtx) const +{ + TEveLineGL::DirectDraw(rnrCtx); + + // path-marks + std::vector& pm = fTrack->fPathMarks; + TEveTrackPropagator& RS = *fTrack->GetPropagator(); + if(pm.size()) + { + Float_t* pnts = new Float_t[3*pm.size()]; // maximum + Int_t N = 0; + Bool_t accept; + for(std::vector::iterator i=pm.begin(); i!=pm.end(); ++i) + { + accept = kFALSE; + switch((*i)->type) + { + case(TEvePathMark::Daughter): + if(RS.fRnrDaughters) accept = kTRUE; + break; + case(TEvePathMark::Reference): + if(RS.fRnrReferences) accept = kTRUE; + break; + case(TEvePathMark::Decay): + if(RS.fRnrDecay) accept = kTRUE; + break; + } + if(accept) + { + if((TMath::Abs((*i)->V.z) < RS.fMaxZ) && ((*i)->V.Perp() < RS.fMaxR)) + { + pnts[3*N ] =(*i)->V.x; + pnts[3*N+1] =(*i)->V.y; + pnts[3*N+2] =(*i)->V.z; + N++; + } + } + } + TEveGLUtil::RenderPolyMarkers(RS.fPMAtt, pnts, N); + delete [] pnts; + } + + // fist vertex + if(RS.fRnrFV && fTrack->GetLastPoint()) + TEveGLUtil::RenderPolyMarkers(RS.fFVAtt, fTrack->GetP(), 1); +} diff --git a/eve/src/TEveTrackProjected.cxx b/eve/src/TEveTrackProjected.cxx new file mode 100644 index 0000000000..bc34157e2e --- /dev/null +++ b/eve/src/TEveTrackProjected.cxx @@ -0,0 +1,246 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include +#include + +//______________________________________________________________________________ +// TEveTrackProjected +// +// Projected copy of a TEveTrack. + +ClassImp(TEveTrackProjected) + +//______________________________________________________________________________ +TEveTrackProjected::TEveTrackProjected() : + TEveTrack (), + fOrigPnts(0), + fProjection(0) +{ + // Default constructor. +} + +//______________________________________________________________________________ +TEveTrackProjected::~TEveTrackProjected() +{ + // Destructor. Noop. +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackProjected::SetProjection(TEveProjectionManager* proj, TEveProjectable* model) +{ + TEveProjected::SetProjection(proj, model); + TEveTrack* origTrack = dynamic_cast(fProjectable); + + SetTrackParams(*origTrack); + SetPathMarks (*origTrack); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackProjected::UpdateProjection() +{ + fProjection = fProjector->GetProjection(); + MakeTrack(kFALSE); // TEveProjectionManager makes recursive calls +} + +//______________________________________________________________________________ +void TEveTrackProjected::GetBreakPoint(Int_t idx, Bool_t back, + Float_t& x, Float_t& y, Float_t& z) +{ + TEveVector vL = fOrigPnts[idx]; + TEveVector vR = fOrigPnts[idx+1]; + TEveVector vM, vLP, vMP; + while((vL-vR).Mag() > 0.01) + { + vM.Mult(vL+vR, 0.5f); + vLP.Set(vL); fProjection->ProjectPoint(vLP.x, vLP.y, vLP.z); + vMP.Set(vM); fProjection->ProjectPoint(vMP.x, vMP.y, vMP.z); + if(fProjection->AcceptSegment(vLP, vMP, 0.0f)) + { + vL.Set(vM); + } + else + { + vR.Set(vM); + } + //printf("new interval Mag %f (%f, %f, %f)(%f, %f, %f) \n",(vL-vR).Mag(), vL.x, vL.y, vL.z, vR.x, vR.y, vR.z); + } + + if(back) + { + x = vL.x; y = vL.y; z = vL.z; + } + else + { + x = vR.x; y = vR.y; z = vR.z; + } + fProjection->ProjectPoint(x, y, z); + // printf("TEveTrackProjected::GetBreakPoint %d (%f, %f, %f) \n", idx, x, y, z); +} + +//______________________________________________________________________________ +Int_t TEveTrackProjected::GetBreakPointIdx(Int_t start) +{ + // Findex index of the last point that lies within the same + // segment of projected space. + // For example, rho-z projection separates upper and lower hemisphere + // and tracks break into two lines when crossing the y=0 plane. + + Int_t val = fLastPoint; + + TEveVector v1, v2; + if (Size() > 1) + { + Int_t i = start; + while(i < fLastPoint) + { + GetPoint(i, v1.x, v1.y, v1.z); + GetPoint(i+1, v2.x, v2.y, v2.z); + if(fProjection->AcceptSegment(v1, v2, fPropagator->fDelta) == kFALSE) + { + val = i; + break; + } + i++; + } + } + // printf("BreakPoint IDX start:%d, BREAK %d, total:%d \n", start, val, Size()); + return val; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackProjected::MakeTrack(Bool_t recurse) +{ + // Calculate the points of the track for drawing. + // Call base-class, project, find break-points and insert points + // required for full representation. + + TEveTrack::MakeTrack(recurse); + + fBreakPoints.clear(); + if(Size() == 0) return; // All points can be outside of MaxR / MaxZ limits. + + // Project points, store originals (needed for break-points). + Float_t *p = GetP(); + fOrigPnts = new TEveVector[Size()]; + for(Int_t i = 0; i < Size(); ++i, p+=3) + { + fOrigPnts[i].Set(p); + fProjection->ProjectPoint(p[0], p[1], p[2]); + p[2] = fDepth; + } + + Float_t x, y, z; + std::vector vvec; + Int_t bL = 0, bR = GetBreakPointIdx(0); + while (1) + { + for(Int_t i=bL; i<=bR; i++) + { + GetPoint(i, x, y, z); + vvec.push_back(TEveVector(x, y, z)); + } + if (bR == fLastPoint) + break; + + GetBreakPoint(bR, kTRUE, x, y, z); vvec.push_back(TEveVector(x, y, z)); + fBreakPoints.push_back(vvec.size()); + GetBreakPoint(bR, kFALSE, x, y, z); vvec.push_back(TEveVector(x, y, z)); + + bL = bR + 1; + bR = GetBreakPointIdx(bL); + } + fBreakPoints.push_back(vvec.size()); // Mark the track-end for drawing. + + Reset(vvec.size()); + for (std::vector::iterator i=vvec.begin(); i!=vvec.end(); ++i) + SetNextPoint((*i).x, (*i).y, (*i).z); + delete [] fOrigPnts; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackProjected::PrintLineSegments() +{ + printf("%s LineSegments:\n", GetName()); + Int_t start = 0; + Int_t segment = 0; + TEveVector S; + TEveVector E; + for (std::vector::iterator bpi = fBreakPoints.begin(); + bpi != fBreakPoints.end(); ++bpi) + { + Int_t size = *bpi - start; + + GetPoint(start, S.x, S.y, S.z); + GetPoint((*bpi)-1, E.x, E.y, E.z); + printf("seg %d size %d start %d ::(%f, %f, %f) (%f, %f, %f)\n", + segment, size, start, S.x, S.y, S.z, E.x, E.y, E.z); + start += size; + segment ++; + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackProjected::CtrlClicked(TEveTrack* /*track*/) +{ + TEveTrack* t = dynamic_cast(fProjectable); + if (t) + t->CtrlClicked(t); +} + + +//______________________________________________________________________________ +// TEveTrackListProjected +// +// Specialization of TEveTrackList for holding TEveTrackProjected objects. + +//______________________________________________________________________________ +ClassImp(TEveTrackListProjected) + +//______________________________________________________________________________ +TEveTrackListProjected::TEveTrackListProjected() : + TEveTrackList (), + TEveProjected () +{ + // Default constructor. +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackListProjected::SetProjection(TEveProjectionManager* proj, TEveProjectable* model) +{ + TEveProjected::SetProjection(proj, model); + + TEveTrackList& tl = * dynamic_cast(model); + SetLineColor(tl.GetLineColor()); + SetLineStyle(tl.GetLineStyle()); + SetLineWidth(tl.GetLineWidth()); + SetMarkerColor(tl.GetMarkerColor()); + SetMarkerStyle(tl.GetMarkerStyle()); + SetMarkerSize(tl.GetMarkerSize()); + SetRnrLine(tl.GetRnrLine()); + SetRnrPoints(tl.GetRnrPoints()); + + SetPropagator(tl.GetPropagator()); +} diff --git a/eve/src/TEveTrackProjectedGL.cxx b/eve/src/TEveTrackProjectedGL.cxx new file mode 100644 index 0000000000..86adb485a0 --- /dev/null +++ b/eve/src/TEveTrackProjectedGL.cxx @@ -0,0 +1,117 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include +#include +#include + +#include +#include + +//______________________________________________________________________________ +// TEveTrackProjectedGL +// +// GL-renderer for TEveTrackProjected class. + +ClassImp(TEveTrackProjectedGL) + +//______________________________________________________________________________ +TEveTrackProjectedGL::TEveTrackProjectedGL() : TEveTrackGL(), fM(0) +{ + // Constructor. + + // fDLCache = kFALSE; // Disable display list. +} + +//______________________________________________________________________________ +TEveTrackProjectedGL::~TEveTrackProjectedGL() +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +Bool_t TEveTrackProjectedGL::SetModel(TObject* obj, const Option_t* /*opt*/) +{ + if(TEveTrackGL::SetModel(obj) == kFALSE) return kFALSE; + if(SetModelCheckClass(obj, TEveTrackProjected::Class())) { + fM = dynamic_cast(obj); + return kTRUE; + } + return kFALSE; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackProjectedGL::DirectDraw(TGLRnrCtx & rnrCtx) const +{ + // printf("TEveTrackProjectedGL::DirectDraw Style %d, LOD %d\n", flags.Style(), flags.LOD()); + if (rnrCtx.DrawPass() == TGLRnrCtx::kPassOutlineLine || fM->Size() == 0) + return; + + // lines + Int_t start = 0; + Float_t* p = fM->GetP(); + for (std::vector::iterator bpi = fM->fBreakPoints.begin(); + bpi != fM->fBreakPoints.end(); ++bpi) + { + Int_t size = *bpi - start; + if (fM->fRnrLine) TEveGLUtil::RenderLine(*fM, p, size); + if (fM->fRnrPoints) TEveGLUtil::RenderPolyMarkers(*fM, p, size); + p += 3*size; + start += size; + } + + // path-marks + std::vector& pm = fM->fPathMarks; + TEveTrackPropagator& RS = *fM->GetPropagator(); + if(pm.size()) + { + Float_t* pnts = new Float_t[3*pm.size()]; // maximum + Int_t N = 0; + Bool_t accept; + for(std::vector::iterator i=pm.begin(); i!=pm.end(); ++i) + { + accept = kFALSE; + switch((*i)->type) + { + case(TEvePathMark::Daughter): + if(RS.fRnrDaughters) accept = kTRUE; + break; + case(TEvePathMark::Reference): + if(RS.fRnrReferences) accept = kTRUE; + break; + case(TEvePathMark::Decay): + if(RS.fRnrDecay) accept = kTRUE; + break; + } + if(accept) + { + if((TMath::Abs((*i)->V.z) < RS.fMaxZ) && ((*i)->V.Perp() < RS.fMaxR)) + { + pnts[3*N ] =(*i)->V.x; + pnts[3*N+1] =(*i)->V.y; + pnts[3*N+2] =(*i)->V.z; + fM->fProjection->ProjectPoint(pnts[3*N ], pnts[3*N+1], pnts[3*N+2]); + N++; + } + } + } + TEveGLUtil::RenderPolyMarkers(RS.fPMAtt, pnts, N); + delete [] pnts; + } + + // fist vertex + if(RS.fRnrFV && fTrack->GetLastPoint()) + TEveGLUtil::RenderPolyMarkers(RS.fFVAtt, fTrack->GetP(), 1); +} diff --git a/eve/src/TEveTrackPropagator.cxx b/eve/src/TEveTrackPropagator.cxx new file mode 100644 index 0000000000..06fc5d0f89 --- /dev/null +++ b/eve/src/TEveTrackPropagator.cxx @@ -0,0 +1,444 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include + +#include + +#include + +//______________________________________________________________________________ +void TEveTrackPropagator::Helix::Step(Vertex4D& v, TEveVector& p) +{ + v.x += (p.x*fSin - p.y*(1 - fCos))/fA + fXoff; + v.y += (p.y*fSin + p.x*(1 - fCos))/fA + fYoff; + v.z += fLam*TMath::Abs(fR*fPhiStep); + v.t += fTimeStep; + + Float_t pxt = p.x*fCos - p.y*fSin; + Float_t pyt = p.y*fCos + p.x*fSin; + p.x = pxt; + p.y = pyt; +} + +//______________________________________________________________________________ +void TEveTrackPropagator::Helix::StepVertex(Vertex4D& v, TEveVector& p, Vertex4D& forw) +{ + forw.x = v.x + (p.x*fSin - p.y*(1 - fCos))/fA + fXoff; + forw.y = v.y + (p.y*fSin + p.x*(1 - fCos))/fA + fYoff; + forw.z = v.z + fLam*TMath::Abs(fR*fPhiStep); + forw.t = v.t + fTimeStep; +} + +//______________________________________________________________________________ +// TEveTrackPropagator +// +//______________________________________________________________________________ +// TEveTrackPropagator +// +// Holding structure for a number of track rendering parameters. +// Calculates path taking into account the parameters. +// +// This is decoupled from TEveTrack/TEveTrackList to allow sharing of the +// Propagator among several instances. Back references are kept so the +// tracks can be recreated when the parameters change. +// +// TEveTrackList has Get/Set methods for RnrStlye. TEveTrackEditor and +// TEveTrackListEditor provide editor access. + +ClassImp(TEveTrackPropagator) + +Float_t TEveTrackPropagator::fgDefMagField = 5; +const Float_t TEveTrackPropagator::fgkB2C = 0.299792458e-3; +TEveTrackPropagator TEveTrackPropagator::fgDefStyle; + +//______________________________________________________________________________ +TEveTrackPropagator::TEveTrackPropagator() : + TObject(), + TEveRefBackPtr(), + + fMagField(fgDefMagField), + + fMaxR (350), + fMaxZ (450), + + fMaxOrbs (0.5), + fMinAng (45), + fDelta (0.1), + + fEditPathMarks(kFALSE), + fPMAtt(), + + fFitDaughters (kTRUE), + fFitReferences (kTRUE), + fFitDecay (kTRUE), + + fRnrDaughters (kTRUE), + fRnrReferences (kTRUE), + fRnrDecay (kTRUE), + + fRnrFV(kFALSE), + fFVAtt(), + + fCharge (0), + fVelocity (0.0f), + fV (), + fN (0), + fNLast (0), + fNMax (4096) +{ +} + +//______________________________________________________________________________ +void TEveTrackPropagator::InitTrack(TEveVector &v, TEveVector &p, Float_t beta, Int_t charge) +{ + fV.x = v.x; + fV.y = v.y; + fV.z = v.z; + fV.t = 0; + fPoints.push_back(fV); + + fVelocity = TMath::C()*beta; + fCharge = charge; + if (fCharge) + { + // initialise helix + using namespace TMath; + Float_t pT = p.Perp(); + fH.fA = fgkB2C *fMagField * charge; + fH.fLam = p.z/pT; + fH.fR = pT/fH.fA; + + fH.fPhiStep = fMinAng * DegToRad(); + if (fDelta < Abs(fH.fR)) + { + Float_t ang = 2*ACos(1 - fDelta/Abs(fH.fR)); + if (ang < fH.fPhiStep) fH.fPhiStep = ang; + } + if (fH.fA < 0) fH.fPhiStep *= -1; + //printf("PHI STEP %f \n", fH.fPhiStep); + + fH.fTimeStep = 0.01* Abs(fH.fR*fH.fPhiStep)*Sqrt(1+(fH.fLam*fH.fLam))/fVelocity;//cm->m + fH.fSin = Sin(fH.fPhiStep); + fH.fCos = Cos(fH.fPhiStep); + } +} + +//______________________________________________________________________________ +void TEveTrackPropagator::ResetTrack() +{ + fPoints.clear(); + fN = 0; + fNLast = 0; +} + +//______________________________________________________________________________ +Bool_t TEveTrackPropagator::GoToVertex(TEveVector& v, TEveVector& p) +{ + Bool_t hit; + if (fCharge != 0 && TMath::Abs(fMagField) > 1e-5 && p.Perp2() > 1e-12) + hit = HelixToVertex(v, p); + else + hit = LineToVertex(v); + return hit; +} + +//______________________________________________________________________________ +void TEveTrackPropagator::GoToBounds(TEveVector& p) +{ + if(fCharge != 0 && TMath::Abs(fMagField) > 1e-5 && p.Perp2() > 1e-12) + HelixToBounds(p); + else + LineToBounds(p); +} + +//______________________________________________________________________________ +void TEveTrackPropagator::SetNumOfSteps() +{ + using namespace TMath; + // max orbits + fNLast = Int_t(fMaxOrbs*TwoPi()/Abs(fH.fPhiStep)); + // Z boundaries + Float_t nz; + if (fH.fLam > 0) { + nz = ( fMaxZ - fV.z)/( fH.fLam*Abs(fH.fR*fH.fPhiStep) ); + } else { + nz = (-fMaxZ - fV.z)/( fH.fLam*Abs(fH.fR*fH.fPhiStep) ); + } + if (nz < fNLast) fNLast = Int_t(nz + 1); + // printf("end steps in helix line %d \n", fNLast); +} + + +//______________________________________________________________________________ +void TEveTrackPropagator::HelixToBounds(TEveVector& p) +{ + // printf("HelixToBounds\n"); + SetNumOfSteps(); + if (fNLast > 0) + { + Bool_t crosR = kFALSE; + if (fV.Perp() < fMaxR + TMath::Abs(fH.fR)) + crosR = true; + + Float_t maxR2 = fMaxR * fMaxR; + Vertex4D forw; + while (fN < fNLast) + { + fH.StepVertex(fV, p, forw); + if (crosR && forw.Perp2() > maxR2) + { + Float_t t = (fMaxR - fV.R()) / (forw.R() - fV.R()); + assert(t >= 0 && t <= 1); + fPoints.push_back(fV + (forw-fV)*t);fN++; + return; + } + if (TMath::Abs(forw.z) > fMaxZ) + { + Float_t t = (fMaxZ - TMath::Abs(fV.z)) / TMath::Abs((forw.z - fV.z)); + assert(t >= 0 && t <= 1); + fPoints.push_back(fV + (forw-fV)*t);fN++; + return; + } + fH.Step(fV, p); fPoints.push_back(fV); fN++; + } + return; + } +} + +//______________________________________________________________________________ +Bool_t TEveTrackPropagator::HelixToVertex(TEveVector& v, TEveVector& p) +{ + Float_t p0x = p.x, p0y = p.y; + Float_t zs = fH.fLam*TMath::Abs(fH.fR*fH.fPhiStep); + Float_t maxrsq = fMaxR * fMaxR; + Float_t fnsteps = (v.z - fV.z)/zs; + Int_t nsteps = Int_t((v.z - fV.z)/zs); + Float_t sinf = TMath::Sin(fnsteps*fH.fPhiStep); // final sin + Float_t cosf = TMath::Cos(fnsteps*fH.fPhiStep); // final cos + + // check max orbits + nsteps = TMath::Min(nsteps, fNLast -fN); + { + if (nsteps > 0) + { + // check offset and distribute it over all steps + Float_t xf = fV.x + (p.x*sinf - p.y*(1 - cosf))/fH.fA; + Float_t yf = fV.y + (p.y*sinf + p.x*(1 - cosf))/fH.fA; + fH.fXoff = (v.x - xf)/fnsteps; + fH.fYoff = (v.y - yf)/fnsteps; + Vertex4D forw; + for (Int_t l=0; l maxrsq || TMath::Abs(fV.z) > fMaxZ) + return kFALSE; + fH.Step(fV, p); fPoints.push_back(fV); fN++; + } + } + // set time to the end point + fV.t += TMath::Sqrt((fV.x-v.x)*(fV.x-v.x)+(fV.y-v.y)*(fV.y-v.y) +(fV.z-v.z)*(fV.z-v.z))/fVelocity; + fV.x = v.x; fV.y = v.y; fV.z = v.z; + fPoints.push_back(fV); fN++; + } + { // rotate momentum for residuum + Float_t cosr = TMath::Cos((fnsteps-nsteps)*fH.fPhiStep); + Float_t sinr = TMath::Sin((fnsteps-nsteps)*fH.fPhiStep); + Float_t pxt = p.x*cosr - p.y*sinr; + Float_t pyt = p.y*cosr + p.x*sinr; + p.x = pxt; + p.y = pyt; + } + { // calculate size of faked p.x,py + Float_t pxf = (p0x*cosf - p0y*sinf)/TMath::Abs(fH.fA) + fH.fXoff/fH.fPhiStep; + Float_t pyf = (p0y*cosf + p0x*sinf)/TMath::Abs(fH.fA) + fH.fYoff/fH.fPhiStep; + Float_t fac = TMath::Sqrt((p0x*p0x + p0y*p0y) / (pxf*pxf + pyf*pyf)); + p.x = fac*pxf; + p.y = fac*pyf; + } + return kTRUE; +} + +//______________________________________________________________________________ +Bool_t TEveTrackPropagator::LineToVertex(TEveVector& v) +{ + fV.t += TMath::Sqrt((fV.x-v.x)*(fV.x-v.x)+(fV.y-v.y)*(fV.y-v.y)+(fV.z-v.z)*(fV.z-v.z))/fVelocity; + fV.x = v.x; + fV.y = v.y; + fV.z = v.z; + fPoints.push_back(fV); + + return kTRUE; +} + +//______________________________________________________________________________ +void TEveTrackPropagator::LineToBounds(TEveVector& p) +{ + Float_t tZ = 0, Tb = 0; + // time where particle intersect +/- fMaxZ + if (p.z > 0) { + tZ = (fMaxZ - fV.z)/p.z; + } + else if (p.z < 0 ) { + tZ = (-1)*(fMaxZ + fV.z)/p.z; + } + // time where particle intersects cylinder + Float_t tR = 0; + Double_t a = p.x*p.x + p.y*p.y; + Double_t b = 2*(fV.x*p.x + fV.y*p.y); + Double_t c = fV.x*fV.x + fV.y*fV.y - fMaxR*fMaxR; + Double_t D = b*b - 4*a*c; + if (D >= 0) { + Double_t D_sqrt=TMath::Sqrt(D); + tR = ( -b - D_sqrt )/(2*a); + if (tR < 0) { + tR = ( -b + D_sqrt )/(2*a); + } + Tb = tR < tZ ? tR : tZ; // compare the two times + } else { + Tb = tZ; + } + TEveVector nv(fV.x + p.x*Tb, fV.y + p.y*Tb, fV.z+ p.z*Tb); + LineToVertex(nv); +} + +//______________________________________________________________________________ +void TEveTrackPropagator::FillPointSet(TEvePointSet* ps) const +{ + Int_t size = TMath::Min(fNMax, (Int_t) fPoints.size()); + ps->Reset(size); + for (Int_t i=0; iSetNextPoint(v.x, v.y, v.z); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackPropagator::RebuildTracks() +{ + // Rebuild all tracks using this render-style. + + TEveTrack* track; + std::list::iterator i = fBackRefs.begin(); + while (i != fBackRefs.end()) + { + track = dynamic_cast(*i); + track->MakeTrack(); + track->ElementChanged(); + ++i; + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackPropagator::SetMaxR(Float_t x) +{ + // Set maximum radius and rebuild tracks. + + fMaxR = x; + RebuildTracks(); +} + +//______________________________________________________________________________ +void TEveTrackPropagator::SetMaxZ(Float_t x) +{ + // Set maximum z and rebuild tracks. + + fMaxZ = x; + RebuildTracks(); +} + +//______________________________________________________________________________ +void TEveTrackPropagator::SetMaxOrbs(Float_t x) +{ + // Set maximum number of orbits and rebuild tracks. + + fMaxOrbs = x; + RebuildTracks(); +} + +//______________________________________________________________________________ +void TEveTrackPropagator::SetMinAng(Float_t x) +{ + // Set minimum step angle and rebuild tracks. + + fMinAng = x; + RebuildTracks(); +} + +//______________________________________________________________________________ +void TEveTrackPropagator::SetDelta(Float_t x) +{ + // Set maximum error and rebuild tracks. + + fDelta = x; + RebuildTracks(); +} + +//______________________________________________________________________________ +void TEveTrackPropagator::SetFitDaughters(Bool_t x) +{ + // Set daughter creation point fitting and rebuild tracks. + + fFitDaughters = x; + RebuildTracks(); +} + +//______________________________________________________________________________ +void TEveTrackPropagator::SetFitReferences(Bool_t x) +{ + // Set track-reference fitting and rebuild tracks. + + fFitReferences = x; + RebuildTracks(); +} + +//______________________________________________________________________________ +void TEveTrackPropagator::SetFitDecay(Bool_t x) +{ + // Set decay fitting and rebuild tracks. + + fFitDecay = x; + RebuildTracks(); +} + +//______________________________________________________________________________ +void TEveTrackPropagator::SetRnrDecay(Bool_t rnr) +{ + // Set decay rendering and rebuild tracks. + + fRnrDecay = rnr; + RebuildTracks(); +} + +//______________________________________________________________________________ +void TEveTrackPropagator::SetRnrDaughters(Bool_t rnr) +{ + // Set daughter rendering and rebuild tracks. + + fRnrDaughters = rnr; + RebuildTracks(); +} + +//______________________________________________________________________________ +void TEveTrackPropagator::SetRnrReferences(Bool_t rnr) +{ + // Set track-reference rendering and rebuild tracks. + + fRnrReferences = rnr; + RebuildTracks(); +} + diff --git a/eve/src/TEveTrackPropagatorEditor.cxx b/eve/src/TEveTrackPropagatorEditor.cxx new file mode 100644 index 0000000000..9a279ceff8 --- /dev/null +++ b/eve/src/TEveTrackPropagatorEditor.cxx @@ -0,0 +1,398 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +// #include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +//______________________________________________________________________________ +// TEveTrackPropagatorSubEditor +// +// Sub-editor for TEveTrackPropagator class. + +ClassImp(TEveTrackPropagatorSubEditor) + +//______________________________________________________________________________ +TEveTrackPropagatorSubEditor::TEveTrackPropagatorSubEditor(const TGWindow *p): + TGVerticalFrame(p), + fM (0), + + fMaxR(0), + fMaxZ(0), + fMaxOrbits(0), + fMinAng(0), + fDelta(0), + + fRnrFV(0), + + fPMFrame(0), + fFitDaughters(0), + fFitReferences(0), + fFitDecay(0), + fRnrDaughters(0), + fRnrReferences(0), + fRnrDecay(0), + + fRefsCont(0), + fPMAtt(0), + fFVAtt(0) +{ + Int_t labelW = 51; + + // --- Limits + fMaxR = new TEveGValuator(this, "Max R:", 90, 0); + fMaxR->SetLabelWidth(labelW); + fMaxR->SetNELength(6); + fMaxR->Build(); + fMaxR->SetLimits(0.1, 1000, 101, TGNumberFormat::kNESRealOne); + fMaxR->SetToolTip("Maximum radius to which the tracks will be drawn."); + fMaxR->Connect("ValueSet(Double_t)", "TEveTrackPropagatorSubEditor", this, "DoMaxR()"); + AddFrame(fMaxR, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1)); + + fMaxZ = new TEveGValuator(this, "Max Z:", 90, 0); + fMaxZ->SetLabelWidth(labelW); + fMaxZ->SetNELength(6); + fMaxZ->Build(); + fMaxZ->SetLimits(0.1, 2000, 101, TGNumberFormat::kNESRealOne); + fMaxZ->SetToolTip("Maximum z-coordinate to which the tracks will be drawn."); + fMaxZ->Connect("ValueSet(Double_t)", "TEveTrackPropagatorSubEditor", this, "DoMaxZ()"); + AddFrame(fMaxZ, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1)); + + fMaxOrbits = new TEveGValuator(this, "Orbits:", 90, 0); + fMaxOrbits->SetLabelWidth(labelW); + fMaxOrbits->SetNELength(6); + fMaxOrbits->Build(); + fMaxOrbits->SetLimits(0.1, 10, 101, TGNumberFormat::kNESRealOne); + fMaxOrbits->SetToolTip("Maximal angular path of tracks' orbits (1 ~ 2Pi)."); + fMaxOrbits->Connect("ValueSet(Double_t)", "TEveTrackPropagatorSubEditor", this, "DoMaxOrbits()"); + AddFrame(fMaxOrbits, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1)); + + fMinAng = new TEveGValuator(this, "Angle:", 90, 0); + fMinAng->SetLabelWidth(labelW); + fMinAng->SetNELength(6); + fMinAng->Build(); + fMinAng->SetLimits(1, 160, 81, TGNumberFormat::kNESRealOne); + fMinAng->SetToolTip("Minimal angular step between two helix points."); + fMinAng->Connect("ValueSet(Double_t)", "TEveTrackPropagatorSubEditor", this, "DoMinAng()"); + AddFrame(fMinAng, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1)); + + fDelta = new TEveGValuator(this, "Delta:", 90, 0); + fDelta->SetLabelWidth(labelW); + fDelta->SetNELength(6); + fDelta->Build(); + fDelta->SetLimits(0.001, 10, 101, TGNumberFormat::kNESRealThree); + fDelta->SetToolTip("Maximal error at the mid-point of the line connecting to helix points."); + fDelta->Connect("ValueSet(Double_t)", "TEveTrackPropagatorSubEditor", this, "DoDelta()"); + AddFrame(fDelta, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1)); +} + +//______________________________________________________________________________ +void TEveTrackPropagatorSubEditor::CreateRefsContainer(TGVerticalFrame* p) +{ + // Create a frame containing track-reference controls under parent + // frame p. + + fRefsCont = new TGCompositeFrame(p, 80, 20, kVerticalFrame); + fPMFrame = new TGVerticalFrame(fRefsCont); + // Rendering control. + { + TGGroupFrame* fitPM = new TGGroupFrame(fPMFrame, "PathMarks:", kLHintsTop | kLHintsCenterX); + fitPM->SetTitlePos(TGGroupFrame::kLeft); + fPMFrame->AddFrame( fitPM, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 3, 3, 3, 3)); + + TGMatrixLayout *ml = new TGMatrixLayout(fitPM, 0,1,6); + fitPM->SetLayoutManager(ml); + + fFitDaughters = new TGCheckButton(fitPM, "Fit Daughters", TEvePathMark::Daughter); + fFitReferences = new TGCheckButton(fitPM, "Fit Refs", TEvePathMark::Reference); + fFitDecay = new TGCheckButton(fitPM, "Fit Decay", TEvePathMark::Decay); + + fitPM->AddFrame(fFitDaughters); + fitPM->AddFrame(fFitReferences); + fitPM->AddFrame(fFitDecay); + + fFitDecay->Connect("Clicked()","TEveTrackPropagatorSubEditor", this, "DoFitPM()"); + fFitReferences->Connect("Clicked()","TEveTrackPropagatorSubEditor", this, "DoFitPM()"); + fFitDaughters->Connect("Clicked()","TEveTrackPropagatorSubEditor", this, "DoFitPM()"); + } + // Kinematics fitting. + { + TGGroupFrame* rnrPM = new TGGroupFrame(fPMFrame, "PathMarks:", kLHintsTop | kLHintsCenterX); + rnrPM->SetTitlePos(TGGroupFrame::kLeft); + fPMFrame->AddFrame( rnrPM, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 3, 3, 3, 3)); + + TGMatrixLayout *ml = new TGMatrixLayout(rnrPM, 0,1,6); + rnrPM->SetLayoutManager(ml); + + fRnrDaughters = new TGCheckButton(rnrPM, "Rnr Daughters", TEvePathMark::Daughter); + fRnrReferences = new TGCheckButton(rnrPM, "Rnr Refs", TEvePathMark::Reference); + fRnrDecay = new TGCheckButton(rnrPM, "Rnr Decay", TEvePathMark::Decay); + + rnrPM->AddFrame(fRnrDaughters); + rnrPM->AddFrame(fRnrReferences); + rnrPM->AddFrame(fRnrDecay); + + fRnrDecay->Connect("Clicked()","TEveTrackPropagatorSubEditor", this, "DoRnrPM()"); + fRnrReferences->Connect("Clicked()","TEveTrackPropagatorSubEditor", this, "DoRnrPM()"); + fRnrDaughters->Connect("Clicked()","TEveTrackPropagatorSubEditor", this, "DoRnrPM()"); + + fRefsCont->AddFrame(fPMFrame, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1)); + } + // Marker attributes. + { + fPMAtt = new TAttMarkerEditor(fRefsCont); + TGFrameElement *el = (TGFrameElement*) fPMAtt->GetList()->First(); + TGFrame *f = el->fFrame; fPMAtt->RemoveFrame(f); + f->DestroyWindow(); delete f; + fRefsCont->AddFrame(fPMAtt, new TGLayoutHints(kLHintsTop, 1, 1, 3, 1)); + } + + // First vertex. + TGCompositeFrame *title1 = new TGCompositeFrame(fRefsCont, 145, 10, + kHorizontalFrame | + kLHintsExpandX | + kFixedWidth | + kOwnBackground); + title1->AddFrame(new TGLabel(title1, "FirstVertex"), + new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); + title1->AddFrame(new TGHorizontal3DLine(title1), + new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 5)); + fRefsCont->AddFrame(title1, new TGLayoutHints(kLHintsTop, 0, 0, 2, 0)); + + fRnrFV = new TGCheckButton(fRefsCont, "Rnr"); + fRnrFV->Connect("Clicked()","TEveTrackPropagatorSubEditor", this, "DoRnrFV()"); + fRefsCont->AddFrame(fRnrFV, new TGLayoutHints(kLHintsTop, 5, 1, 2, 0)); + { + fFVAtt = new TAttMarkerEditor(fRefsCont); + TGFrameElement *el = (TGFrameElement*) fFVAtt->GetList()->First(); + TGFrame *f = el->fFrame; fFVAtt->RemoveFrame(f); + f->DestroyWindow(); delete f; + fRefsCont->AddFrame(fFVAtt, new TGLayoutHints(kLHintsTop, 1, 1, 3, 1)); + } + p->AddFrame(fRefsCont,new TGLayoutHints(kLHintsTop| kLHintsExpandX)); +} + +//______________________________________________________________________________ +void TEveTrackPropagatorSubEditor::SetModel(TEveTrackPropagator* m) +{ + // Set model object. + + fM = m; + + fMaxR->SetValue(fM->fMaxR); + fMaxZ->SetValue(fM->fMaxZ); + fMaxOrbits->SetValue(fM->fMaxOrbs); + fMinAng->SetValue(fM->fMinAng); + fDelta->SetValue(fM->fDelta); + + if(fM->fEditPathMarks) + { + ShowFrame(fPMFrame); + fRnrDaughters->SetState(fM->fRnrDaughters ? kButtonDown : kButtonUp); + fRnrReferences->SetState(fM->fRnrReferences ? kButtonDown : kButtonUp); + fRnrDecay->SetState(fM->fRnrDecay ? kButtonDown : kButtonUp); + + fFitDaughters->SetState(fM->fFitDaughters ? kButtonDown : kButtonUp); + fFitReferences->SetState(fM->fFitReferences ? kButtonDown : kButtonUp); + fFitDecay->SetState(fM->fFitDecay ? kButtonDown : kButtonUp); + + fPMAtt->SetModel(&fM->fPMAtt); + } + else + { + fRefsCont->HideFrame(fPMFrame); + } + + fRnrFV->SetState(fM->fRnrFV ? kButtonDown : kButtonUp); + fFVAtt->SetModel(&fM->fFVAtt); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackPropagatorSubEditor::Changed() +{ + // Update registered tracks and emit "Changed()" signal. + + fM->UpdateBackPtrItems(); + Emit("Changed()"); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackPropagatorSubEditor::DoMaxR() +{ + fM->SetMaxR(fMaxR->GetValue()); + Changed(); +} + +//______________________________________________________________________________ +void TEveTrackPropagatorSubEditor::DoMaxZ() +{ + fM->SetMaxZ(fMaxZ->GetValue()); + Changed(); +} + +//______________________________________________________________________________ +void TEveTrackPropagatorSubEditor::DoMaxOrbits() +{ + fM->SetMaxOrbs(fMaxOrbits->GetValue()); + Changed(); +} + +//______________________________________________________________________________ +void TEveTrackPropagatorSubEditor::DoMinAng() +{ + fM->SetMinAng(fMinAng->GetValue()); + Changed(); +} + +//______________________________________________________________________________ +void TEveTrackPropagatorSubEditor::DoDelta() +{ + fM->SetDelta(fDelta->GetValue()); + Changed(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackPropagatorSubEditor::DoFitPM() +{ + TGButton* b = (TGButton *) gTQSender; + TEvePathMark::Type_e type = TEvePathMark::Type_e(b->WidgetId()); + Bool_t on = b->IsOn(); + + switch(type) + { + case TEvePathMark::Daughter: + fM->SetFitDaughters(on); + break; + case TEvePathMark::Reference: + fM->SetFitReferences(on); + break; + case TEvePathMark::Decay: + fM->SetFitDecay(on); + break; + default: + break; + } + Changed(); +} + +//______________________________________________________________________________ +void TEveTrackPropagatorSubEditor::DoRnrPM() +{ + TGButton * b = (TGButton *) gTQSender; + TEvePathMark::Type_e type = TEvePathMark::Type_e(b->WidgetId()); + Bool_t on = b->IsOn(); + switch(type){ + case TEvePathMark::Daughter: + fM->SetRnrDaughters(on); + break; + case TEvePathMark::Reference: + fM->SetRnrReferences(on); + break; + case TEvePathMark::Decay: + fM->SetRnrDecay(on); + break; + + default: + break; + } + Changed(); +} + +//______________________________________________________________________________ +void TEveTrackPropagatorSubEditor::DoRnrFV() +{ + fM->SetRnrFV(fRnrFV->IsOn()); + Changed(); +} + + +//______________________________________________________________________________ +// TEveTrackPropagatorEditor +// +// GUI editor for TEveTrackPropagator. +// It's only a wrapper around a TEveTrackPropagatorSubEditor that holds actual +// widgets. + +ClassImp(TEveTrackPropagatorEditor) + +//______________________________________________________________________________ +TEveTrackPropagatorEditor::TEveTrackPropagatorEditor(const TGWindow *p, + Int_t width, Int_t height, + UInt_t options, Pixel_t back) : + TGedFrame(p, width, height, options | kVerticalFrame, back), + fM(0), + fRSSubEditor(0) +{ + // Constructor. + + MakeTitle("RenderStyle"); + + fRSSubEditor = new TEveTrackPropagatorSubEditor(this); + fRSSubEditor->Connect("Changed()", "TEveTrackPropagatorEditor", this, "Update()"); + AddFrame(fRSSubEditor, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 2, 0,0,0)); + + TGVerticalFrame* refsFrame = CreateEditorTabSubFrame("Refs"); + TGCompositeFrame *title1 = new TGCompositeFrame(refsFrame, 145, 10, + kHorizontalFrame | + kLHintsExpandX | + kFixedWidth | + kOwnBackground); + title1->AddFrame(new TGLabel(title1, "PathMarks"), + new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0)); + title1->AddFrame(new TGHorizontal3DLine(title1), + new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7)); + refsFrame->AddFrame(title1, new TGLayoutHints(kLHintsTop, 0, 0, 2, 0)); + + // path marks + fRSSubEditor->CreateRefsContainer(refsFrame); + fRSSubEditor->fPMAtt->SetGedEditor((TGedEditor*)gEve->GetEditor()); + fRSSubEditor->fFVAtt->SetGedEditor((TGedEditor*)gEve->GetEditor()); + + fRSSubEditor->Connect("Changed()", "TEveTrackPropagatorEditor", this, "Update()"); +} + +//______________________________________________________________________________ +TEveTrackPropagatorEditor::~TEveTrackPropagatorEditor() +{ + // Destructor. Noop. +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrackPropagatorEditor::SetModel(TObject* obj) +{ + // Set model object. + + fM = dynamic_cast(obj); + fRSSubEditor->SetModel(fM); +} diff --git a/eve/src/TEveTrans.cxx b/eve/src/TEveTrans.cxx new file mode 100644 index 0000000000..848d84d221 --- /dev/null +++ b/eve/src/TEveTrans.cxx @@ -0,0 +1,830 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +//______________________________________________________________________________ +// TEveTrans +// +// TEveTrans is a 4x4 transformation matrix for homogeneous coordinates +// stored internaly in a column-major order to allow direct usage by +// GL. The element type is Double32_t as statically the floats would +// be precise enough but continuous operations on the matrix must +// retain precision of column vectors. +// +// Cartan angles in mA[1-3] (+z, -y, +x) are stored for backward +// compatibility and will probably be removed soon. +// +// Direct element access (first two should be used with care): +// operator[i] direct access to elements, i:0->15 +// CM(i,j) element 4*j + i; i,j:0->3 { CM ~ c-matrix } +// operator(i,j) element 4*(j-1) + i - 1 i,j:1->4 +// +// Column-vector access: +// USet Get/SetBaseVec(), Get/SetPos() and Arr[XYZT]() methods. +// +// For all methods taking the matrix indices: +// 1->X, 2->Y, 3->Z; 4->Position (if applicable). 0 reserved for time. +// +// Shorthands in method-names: +// LF ~ LocalFrame; PF ~ ParentFrame; IP ~ InPlace + +#include +#include +#include +#include + +#include + +#define F00 0 +#define F01 4 +#define F02 8 +#define F03 12 + +#define F10 1 +#define F11 5 +#define F12 9 +#define F13 13 + +#define F20 2 +#define F21 6 +#define F22 10 +#define F23 14 + +#define F30 3 +#define F31 7 +#define F32 11 +#define F33 15 + +ClassImp(TEveTrans) + +//______________________________________________________________________________ +TEveTrans::TEveTrans() : + TObject(), + mA1(0), mA2(0), mA3(0), bAsOK(kFALSE), + fUseTrans (kTRUE), + fEditTrans(kFALSE) +{ + UnitTrans(); +} + +//______________________________________________________________________________ +TEveTrans::TEveTrans(const TEveTrans& t) : + TObject(), + mA1(t.mA1), mA2(t.mA2), mA3(t.mA3), bAsOK(t.bAsOK), + fUseTrans (t.fUseTrans), + fEditTrans(t.fEditTrans) +{ + SetTrans(t, kFALSE); +} + +//______________________________________________________________________________ +TEveTrans::TEveTrans(const Double_t arr[16]) : + TObject(), + mA1(0), mA2(0), mA3(0), bAsOK(kFALSE), + fUseTrans (kTRUE), + fEditTrans(kFALSE) +{ + SetFromArray(arr); +} + +//______________________________________________________________________________ +TEveTrans::TEveTrans(const Float_t arr[16]) : + TObject(), + mA1(0), mA2(0), mA3(0), bAsOK(kFALSE), + fUseTrans (kTRUE), + fEditTrans(kFALSE) +{ + SetFromArray(arr); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrans::UnitTrans() +{ + // Reset matrix to unity. + + memset(M, 0, 16*sizeof(Double_t)); + M[F00] = M[F11] = M[F22] = M[F33] = 1; + mA1 = mA2 = mA3 = 0; + bAsOK = kTRUE; +} + +//______________________________________________________________________________ +void TEveTrans::UnitRot() +{ + // Reset rotation part of the matrix to unity. + + memset(M, 0, 12*sizeof(Double_t)); + M[F00] = M[F11] = M[F22] = 1; + mA1 = mA2 = mA3 = 0; + bAsOK = kTRUE; +} + +//______________________________________________________________________________ +void TEveTrans::SetTrans(const TEveTrans& t, Bool_t copyAngles) +{ + memcpy(M, t.M, sizeof(M)); + if (copyAngles && t.bAsOK) { + bAsOK = kTRUE; + mA1 = t.mA1; mA2 = t.mA2; mA3 = t.mA3; + } else { + bAsOK = kFALSE; + } +} + +//______________________________________________________________________________ +void TEveTrans::SetFromArray(const Double_t arr[16]) +{ + for(Int_t i=0; i<16; ++i) M[i] = arr[i]; + bAsOK = false; +} + +//______________________________________________________________________________ +void TEveTrans::SetFromArray(const Float_t arr[16]) +{ + for(Int_t i=0; i<16; ++i) M[i] = arr[i]; + bAsOK = false; +} + +//______________________________________________________________________________ +void TEveTrans::SetupRotation(Int_t i, Int_t j, Double_t f) +{ + // Setup the matrix as an elementary rotation. + // Optimized versions of left/right multiplication with an elementary + // rotation matrix are implemented in RotatePF/RotateLF. + // Expects identity matrix. + + if(i == j) return; + TEveTrans& M = *this; + M(i,i) = M(j,j) = TMath::Cos(f); + Double_t s = TMath::Sin(f); + M(i,j) = -s; M(j,i) = s; + bAsOK = kFALSE; +} + +/******************************************************************************/ + +// OrtoNorm3 and Invert are near the bottom. + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrans::MultLeft(const TEveTrans& t) +{ + Double_t B[4]; + Double_t* C = M; + for(int c=0; c<4; ++c, C+=4) { + const Double_t* T = t.M; + for(int r=0; r<4; ++r, ++T) + B[r] = T[0]*C[0] + T[4]*C[1] + T[8]*C[2] + T[12]*C[3]; + C[0] = B[0]; C[1] = B[1]; C[2] = B[2]; C[3] = B[3]; + } + bAsOK = kFALSE; +} + +//______________________________________________________________________________ +void TEveTrans::MultRight(const TEveTrans& t) +{ + Double_t B[4]; + Double_t* C = M; + for(int r=0; r<4; ++r, ++C) { + const Double_t* T = t.M; + for(int c=0; c<4; ++c, T+=4) + B[c] = C[0]*T[0] + C[4]*T[1] + C[8]*T[2] + C[12]*T[3]; + C[0] = B[0]; C[4] = B[1]; C[8] = B[2]; C[12] = B[3]; + } + bAsOK = kFALSE; +} + +//______________________________________________________________________________ +TEveTrans TEveTrans::operator*(const TEveTrans& t) +{ + TEveTrans b(*this); + b.MultRight(t); + return b; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrans::TransposeRotationPart() +{ + Double_t x; + x = M[F01]; M[F01] = M[F10]; M[F10] = x; + x = M[F02]; M[F02] = M[F20]; M[F20] = x; + x = M[F12]; M[F12] = M[F21]; M[F21] = x; + bAsOK = false; +} + +/******************************************************************************/ +// Move & Rotate +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrans::MoveLF(Int_t ai, Double_t amount) +{ + const Double_t *C = M + 4*--ai; + M[F03] += amount*C[0]; M[F13] += amount*C[1]; M[F23] += amount*C[2]; +} + +//______________________________________________________________________________ +void TEveTrans::Move3LF(Double_t x, Double_t y, Double_t z) +{ + M[F03] += x*M[0] + y*M[4] + z*M[8]; + M[F13] += x*M[1] + y*M[5] + z*M[9]; + M[F23] += x*M[2] + y*M[6] + z*M[10]; +} + +//______________________________________________________________________________ +void TEveTrans::RotateLF(Int_t i1, Int_t i2, Double_t amount) +{ + // Rotate in local frame. Does optimised version of MultRight. + + if(i1 == i2) return; + // Algorithm: TEveTrans a; a.SetupRotation(i1, i2, amount); MultRight(a); + // Optimized version: + const Double_t cos = TMath::Cos(amount), sin = TMath::Sin(amount); + Double_t b1, b2; + Double_t* C = M; + --i1 <<= 2; --i2 <<= 2; // column major + for(int r=0; r<4; ++r, ++C) { + b1 = cos*C[i1] + sin*C[i2]; + b2 = cos*C[i2] - sin*C[i1]; + C[i1] = b1; C[i2] = b2; + } + bAsOK = kFALSE; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrans::MovePF(Int_t ai, Double_t amount) +{ + M[F03 + --ai] += amount; +} + +//______________________________________________________________________________ +void TEveTrans::Move3PF(Double_t x, Double_t y, Double_t z) +{ + M[F03] += x; + M[F13] += y; + M[F23] += z; +} + +//______________________________________________________________________________ +void TEveTrans::RotatePF(Int_t i1, Int_t i2, Double_t amount) +{ + // Rotate in parent frame. Does optimised version of MultLeft. + + if(i1 == i2) return; + // Algorithm: TEveTrans a; a.SetupRotation(i1, i2, amount); MultLeft(a); + + // Optimized version: + const Double_t cos = TMath::Cos(amount), sin = TMath::Sin(amount); + Double_t b1, b2; + Double_t* C = M; + --i1; --i2; + for(int c=0; c<4; ++c, C+=4) { + b1 = cos*C[i1] - sin*C[i2]; + b2 = cos*C[i2] + sin*C[i1]; + C[i1] = b1; C[i2] = b2; + } + bAsOK = kFALSE; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrans::Move(const TEveTrans& a, Int_t ai, Double_t amount) +{ + const Double_t* A = a.M + 4*--ai; + M[F03] += amount*A[0]; + M[F13] += amount*A[1]; + M[F23] += amount*A[2]; +} + +//______________________________________________________________________________ +void TEveTrans::Move3(const TEveTrans& a, Double_t x, Double_t y, Double_t z) +{ + const Double_t* A = a.M; + M[F03] += x*A[F00] + y*A[F01] + z*A[F02]; + M[F13] += x*A[F10] + y*A[F11] + z*A[F12]; + M[F23] += x*A[F20] + y*A[F21] + z*A[F22]; +} + +//______________________________________________________________________________ +void TEveTrans::Rotate(const TEveTrans& a, Int_t i1, Int_t i2, Double_t amount) +{ + if(i1 == i2) return; + TEveTrans X(a); + X.Invert(); + MultLeft(X); + RotatePF(i1, i2, amount); + MultLeft(a); + bAsOK = kFALSE; +} + +/******************************************************************************/ +// Base-vector interface +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrans::SetBaseVec(Int_t b, Double_t x, Double_t y, Double_t z) +{ + Double_t* C = M + 4*--b; + C[0] = x; C[1] = y; C[2] = z; + bAsOK = kFALSE; +} + +//______________________________________________________________________________ +void TEveTrans::SetBaseVec(Int_t b, const TVector3& v) +{ + Double_t* C = M + 4*--b; + v.GetXYZ(C); + bAsOK = kFALSE; +} + +//______________________________________________________________________________ +TVector3 TEveTrans::GetBaseVec(Int_t b) const +{ return TVector3(&M[4*--b]); } + +void TEveTrans::GetBaseVec(Int_t b, TVector3& v) const +{ + const Double_t* C = M + 4*--b; + v.SetXYZ(C[0], C[1], C[2]); +} + +/******************************************************************************/ +// Position interface +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrans::SetPos(Double_t x, Double_t y, Double_t z) +{ M[F03] = x; M[F13] = y; M[F23] = z; } + +void TEveTrans::SetPos(Double_t* x) +{ M[F03] = x[0]; M[F13] = x[1]; M[F23] = x[2]; } + +void TEveTrans::SetPos(Float_t* x) +{ M[F03] = x[0]; M[F13] = x[1]; M[F23] = x[2]; } + +void TEveTrans::SetPos(const TEveTrans& t) +{ + const Double_t* T = t.M; + M[F03] = T[F03]; M[F13] = T[F13]; M[F23] = T[F23]; +} + +//______________________________________________________________________________ +void TEveTrans::GetPos(Double_t& x, Double_t& y, Double_t& z) const +{ x = M[F03]; y = M[F13]; z = M[F23]; } + +void TEveTrans::GetPos(Double_t* x) const +{ x[0] = M[F03]; x[1] = M[F13]; x[2] = M[F23]; } + +void TEveTrans::GetPos(Float_t* x) const +{ x[0] = M[F03]; x[1] = M[F13]; x[2] = M[F23]; } + +void TEveTrans::GetPos(TVector3& v) const +{ v.SetXYZ(M[F03], M[F13], M[F23]); } + +TVector3 TEveTrans::GetPos() const +{ return TVector3(M[F03], M[F13], M[F23]); } + +/******************************************************************************/ +// Cardan angle interface +/******************************************************************************/ + +namespace { +inline void clamp_angle(Float_t& a) { + while(a < -TMath::TwoPi()) a += TMath::TwoPi(); + while(a > TMath::TwoPi()) a -= TMath::TwoPi(); +} +} + +void TEveTrans::SetRotByAngles(Float_t a1, Float_t a2, Float_t a3) +{ + // Sets Rotation part as given by angles: + // a1 around z, -a2 around y, a3 around x + clamp_angle(a1); clamp_angle(a2); clamp_angle(a3); + + Double_t A, B, C, D, E, F; + A = TMath::Cos(a3); B = TMath::Sin(a3); + C = TMath::Cos(a2); D = TMath::Sin(a2); // should be -sin(a2) for positive direction + E = TMath::Cos(a1); F = TMath::Sin(a1); + Double_t AD = A*D, BD = B*D; + + M[F00] = C*E; M[F01] = -BD*E - A*F; M[F02] = -AD*E + B*F; + M[F10] = C*F; M[F11] = -BD*F + A*E; M[F12] = -AD*F - B*E; + M[F20] = D; M[F21] = B*C; M[F22] = A*C; + + mA1 = a1; mA2 = a2; mA3 = a3; + bAsOK = true; +} + +//______________________________________________________________________________ +void TEveTrans::SetRotByAnyAngles(Float_t a1, Float_t a2, Float_t a3, + const Text_t* pat) +{ + // Sets Rotation part as given by angles a1, a1, a3 and pattern pat. + // Pattern consists of "XxYyZz" characters. + // eg: x means rotate about x axis, X means rotate in negative direction + // xYz -> R_x(a3) * R_y(-a2) * R_z(a1); (standard Gled representation) + // Note that angles and pattern elements have inversed order! + // + // Implements Eulerian/Cardanian angles in a uniform way. + + int n = strspn(pat, "XxYyZz"); if(n > 3) n = 3; + // Build Trans ... assign ... + Float_t a[] = { a3, a2, a1 }; + UnitRot(); + for(int i=0; i1) d=1; else if(d<-1) d=-1; // Fix numerical errors + mA2 = TMath::ASin(d); + Double_t C = TMath::Cos(mA2); + if(TMath::Abs(C) > 8.7e-6) { + mA1 = TMath::ATan2(M[F10], M[F00]); + mA3 = TMath::ATan2(M[F21]/sy, M[F22]/sz); + } else { + mA1 = TMath::ATan2(M[F10]/sx, M[F11]/sy); + mA3 = 0; + } + bAsOK = true; + } + x[0] = mA1; x[1] = mA2; x[2] = mA3; +} + +/******************************************************************************/ +// Scaling +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrans::Scale(Double_t sx, Double_t sy, Double_t sz) +{ + M[F00] *= sx; M[F10] *= sx; M[F20] *= sx; + M[F01] *= sy; M[F11] *= sy; M[F21] *= sy; + M[F02] *= sz; M[F12] *= sz; M[F22] *= sz; +} + +//______________________________________________________________________________ +void TEveTrans::GetScale(Double_t& sx, Double_t& sy, Double_t& sz) const +{ + sx = TMath::Sqrt( M[F00]*M[F00] + M[F10]*M[F10] + M[F20]*M[F20] ); + sy = TMath::Sqrt( M[F01]*M[F01] + M[F11]*M[F11] + M[F21]*M[F21] ); + sz = TMath::Sqrt( M[F02]*M[F02] + M[F12]*M[F12] + M[F22]*M[F22] ); +} + +//______________________________________________________________________________ +void TEveTrans::Unscale(Double_t& sx, Double_t& sy, Double_t& sz) +{ + GetScale(sx, sy, sz); + M[F00] /= sx; M[F10] /= sx; M[F20] /= sx; + M[F01] /= sy; M[F11] /= sy; M[F21] /= sy; + M[F02] /= sz; M[F12] /= sz; M[F22] /= sz; +} + +//______________________________________________________________________________ +Double_t TEveTrans::Unscale() +{ + Double_t sx, sy, sz; + Unscale(sx, sy, sz); + return (sx + sy + sz)/3; +} + +/******************************************************************************/ +// Operations on vectors +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrans::MultiplyIP(TVector3& v, Double_t w) const +{ + v.SetXYZ(M[F00]*v.x() + M[F01]*v.y() + M[F02]*v.z() + M[F03]*w, + M[F10]*v.x() + M[F11]*v.y() + M[F12]*v.z() + M[F13]*w, + M[F20]*v.x() + M[F21]*v.y() + M[F22]*v.z() + M[F23]*w); +} + +//______________________________________________________________________________ +void TEveTrans::MultiplyIP(Double_t* v, Double_t w) const +{ + Double_t r[3] = { v[0], v[1], v[2] }; + v[0] = M[F00]*r[0] + M[F01]*r[1] + M[F02]*r[2] + M[F03]*w; + v[1] = M[F10]*r[0] + M[F11]*r[1] + M[F12]*r[2] + M[F13]*w; + v[2] = M[F20]*r[0] + M[F21]*r[1] + M[F22]*r[2] + M[F23]*w; +} + +//______________________________________________________________________________ +void TEveTrans::MultiplyIP(Float_t* v, Double_t w) const +{ + Double_t r[3] = { v[0], v[1], v[2] }; + v[0] = M[F00]*r[0] + M[F01]*r[1] + M[F02]*r[2] + M[F03]*w; + v[1] = M[F10]*r[0] + M[F11]*r[1] + M[F12]*r[2] + M[F13]*w; + v[2] = M[F20]*r[0] + M[F21]*r[1] + M[F22]*r[2] + M[F23]*w; +} + +//______________________________________________________________________________ +TVector3 TEveTrans::Multiply(const TVector3& v, Double_t w) const +{ + return TVector3(M[F00]*v.x() + M[F01]*v.y() + M[F02]*v.z() + M[F03]*w, + M[F10]*v.x() + M[F11]*v.y() + M[F12]*v.z() + M[F13]*w, + M[F20]*v.x() + M[F21]*v.y() + M[F22]*v.z() + M[F23]*w); +} + +//______________________________________________________________________________ +void TEveTrans::Multiply(const Double_t *vin, Double_t* vout, Double_t w) const +{ + vout[0] = M[F00]*vin[0] + M[F01]*vin[1] + M[F02]*vin[2] + M[F03]*w; + vout[1] = M[F10]*vin[0] + M[F11]*vin[1] + M[F12]*vin[1] + M[F13]*w; + vout[2] = M[F20]*vin[0] + M[F21]*vin[1] + M[F22]*vin[1] + M[F23]*w; +} + +//______________________________________________________________________________ +void TEveTrans::RotateIP(TVector3& v) const +{ + v.SetXYZ(M[F00]*v.x() + M[F01]*v.y() + M[F02]*v.z(), + M[F10]*v.x() + M[F11]*v.y() + M[F12]*v.z(), + M[F20]*v.x() + M[F21]*v.y() + M[F22]*v.z()); +} + +//______________________________________________________________________________ +TVector3 TEveTrans::Rotate(const TVector3& v) const +{ + return TVector3(M[F00]*v.x() + M[F01]*v.y() + M[F02]*v.z(), + M[F10]*v.x() + M[F11]*v.y() + M[F12]*v.z(), + M[F20]*v.x() + M[F21]*v.y() + M[F22]*v.z()); +} + +/******************************************************************************/ +// Normalization, ortogonalization +/******************************************************************************/ + +//______________________________________________________________________________ +Double_t TEveTrans::norm3_column(Int_t col) +{ + Double_t* C = M + 4*--col; + const Double_t l = TMath::Sqrt(C[0]*C[0] + C[1]*C[1] + C[2]*C[2]); + C[0] /= l; C[1] /= l; C[2] /= l; + return l; +} + +//______________________________________________________________________________ +Double_t TEveTrans::orto3_column(Int_t col, Int_t ref) +{ + Double_t* C = M + 4*--col; + Double_t* R = M + 4*--ref; + const Double_t dp = C[0]*R[0] + C[1]*R[1] + C[2]*R[2]; + C[0] -= R[0]*dp; C[1] -= R[1]*dp; C[2] -= R[2]*dp; + return dp; +} + +//______________________________________________________________________________ +void TEveTrans::OrtoNorm3() +{ + norm3_column(1); + orto3_column(2,1); norm3_column(2); + M[F02] = M[F10]*M[F21] - M[F11]*M[F20]; + M[F12] = M[F20]*M[F01] - M[F21]*M[F00]; + M[F22] = M[F00]*M[F11] - M[F01]*M[F10]; + // cross-product faster. + // orto3_column(3,1); orto3_column(3,2); norm3_column(3); +} + +/******************************************************************************/ +// Inversion +/******************************************************************************/ + +//______________________________________________________________________________ +Double_t TEveTrans::Invert() +{ + // Copied from ROOT's TMatrixFCramerInv. + + static const TEveException _eh("TEveTrans::Invert "); + + // Find all NECESSARY 2x2 dets: (18 of them) + const Double_t det2_12_01 = M[F10]*M[F21] - M[F11]*M[F20]; + const Double_t det2_12_02 = M[F10]*M[F22] - M[F12]*M[F20]; + const Double_t det2_12_03 = M[F10]*M[F23] - M[F13]*M[F20]; + const Double_t det2_12_13 = M[F11]*M[F23] - M[F13]*M[F21]; + const Double_t det2_12_23 = M[F12]*M[F23] - M[F13]*M[F22]; + const Double_t det2_12_12 = M[F11]*M[F22] - M[F12]*M[F21]; + const Double_t det2_13_01 = M[F10]*M[F31] - M[F11]*M[F30]; + const Double_t det2_13_02 = M[F10]*M[F32] - M[F12]*M[F30]; + const Double_t det2_13_03 = M[F10]*M[F33] - M[F13]*M[F30]; + const Double_t det2_13_12 = M[F11]*M[F32] - M[F12]*M[F31]; + const Double_t det2_13_13 = M[F11]*M[F33] - M[F13]*M[F31]; + const Double_t det2_13_23 = M[F12]*M[F33] - M[F13]*M[F32]; + const Double_t det2_23_01 = M[F20]*M[F31] - M[F21]*M[F30]; + const Double_t det2_23_02 = M[F20]*M[F32] - M[F22]*M[F30]; + const Double_t det2_23_03 = M[F20]*M[F33] - M[F23]*M[F30]; + const Double_t det2_23_12 = M[F21]*M[F32] - M[F22]*M[F31]; + const Double_t det2_23_13 = M[F21]*M[F33] - M[F23]*M[F31]; + const Double_t det2_23_23 = M[F22]*M[F33] - M[F23]*M[F32]; + + // Find all NECESSARY 3x3 dets: (16 of them) + const Double_t det3_012_012 = M[F00]*det2_12_12 - M[F01]*det2_12_02 + M[F02]*det2_12_01; + const Double_t det3_012_013 = M[F00]*det2_12_13 - M[F01]*det2_12_03 + M[F03]*det2_12_01; + const Double_t det3_012_023 = M[F00]*det2_12_23 - M[F02]*det2_12_03 + M[F03]*det2_12_02; + const Double_t det3_012_123 = M[F01]*det2_12_23 - M[F02]*det2_12_13 + M[F03]*det2_12_12; + const Double_t det3_013_012 = M[F00]*det2_13_12 - M[F01]*det2_13_02 + M[F02]*det2_13_01; + const Double_t det3_013_013 = M[F00]*det2_13_13 - M[F01]*det2_13_03 + M[F03]*det2_13_01; + const Double_t det3_013_023 = M[F00]*det2_13_23 - M[F02]*det2_13_03 + M[F03]*det2_13_02; + const Double_t det3_013_123 = M[F01]*det2_13_23 - M[F02]*det2_13_13 + M[F03]*det2_13_12; + const Double_t det3_023_012 = M[F00]*det2_23_12 - M[F01]*det2_23_02 + M[F02]*det2_23_01; + const Double_t det3_023_013 = M[F00]*det2_23_13 - M[F01]*det2_23_03 + M[F03]*det2_23_01; + const Double_t det3_023_023 = M[F00]*det2_23_23 - M[F02]*det2_23_03 + M[F03]*det2_23_02; + const Double_t det3_023_123 = M[F01]*det2_23_23 - M[F02]*det2_23_13 + M[F03]*det2_23_12; + const Double_t det3_123_012 = M[F10]*det2_23_12 - M[F11]*det2_23_02 + M[F12]*det2_23_01; + const Double_t det3_123_013 = M[F10]*det2_23_13 - M[F11]*det2_23_03 + M[F13]*det2_23_01; + const Double_t det3_123_023 = M[F10]*det2_23_23 - M[F12]*det2_23_03 + M[F13]*det2_23_02; + const Double_t det3_123_123 = M[F11]*det2_23_23 - M[F12]*det2_23_13 + M[F13]*det2_23_12; + + // Find the 4x4 det: + const Double_t det = M[F00]*det3_123_123 - M[F01]*det3_123_023 + + M[F02]*det3_123_013 - M[F03]*det3_123_012; + + if(det == 0) { + throw(_eh + "matrix is singular."); + } + + const Double_t oneOverDet = 1.0/det; + const Double_t mn1OverDet = - oneOverDet; + + M[F00] = det3_123_123 * oneOverDet; + M[F01] = det3_023_123 * mn1OverDet; + M[F02] = det3_013_123 * oneOverDet; + M[F03] = det3_012_123 * mn1OverDet; + + M[F10] = det3_123_023 * mn1OverDet; + M[F11] = det3_023_023 * oneOverDet; + M[F12] = det3_013_023 * mn1OverDet; + M[F13] = det3_012_023 * oneOverDet; + + M[F20] = det3_123_013 * oneOverDet; + M[F21] = det3_023_013 * mn1OverDet; + M[F22] = det3_013_013 * oneOverDet; + M[F23] = det3_012_013 * mn1OverDet; + + M[F30] = det3_123_012 * mn1OverDet; + M[F31] = det3_023_012 * oneOverDet; + M[F32] = det3_013_012 * mn1OverDet; + M[F33] = det3_012_012 * oneOverDet; + + bAsOK = kFALSE; + return det; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrans::Streamer(TBuffer &R__b) +{ + // Stream an object of class TEveTrans. + + if (R__b.IsReading()) { + TEveTrans::Class()->ReadBuffer(R__b, this); + bAsOK = kFALSE; + } else { + TEveTrans::Class()->WriteBuffer(R__b, this); + } +} + +/******************************************************************************/ +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTrans::Print(Option_t* /*option*/) const +{ + const Double_t* C = M; + for(Int_t i=0; i<4; ++i, ++C) + printf("%8.3f %8.3f %8.3f | %8.3f\n", C[0], C[4], C[8], C[12]); +} + +#include + +//______________________________________________________________________________ +ostream& operator<<(ostream& s, const TEveTrans& t) { + s.setf(std::ios::fixed, std::ios::floatfield); + s.precision(3); + for(Int_t i=1; i<=4; i++) + for(Int_t j=1; j<=4; j++) + s << t(i,j) << ((j==4) ? "\n" : "\t"); + return s; +} + +/******************************************************************************/ +// TEveUtil stuff +/******************************************************************************/ + +#include +#include + +void TEveTrans::SetFrom(Double_t* carr) +{ + fUseTrans = kTRUE; + memcpy(M, carr, 16*sizeof(Double_t)); + bAsOK = kFALSE; +} + +//______________________________________________________________________________ +void TEveTrans::SetFrom(const TGeoMatrix& mat) +{ + fUseTrans = kTRUE; + const Double_t *r = mat.GetRotationMatrix(); + const Double_t *t = mat.GetTranslation(); + const Double_t *s = mat.GetScale(); + Double_t *m = M; + m[0] = r[0]*s[0]; m[1] = r[3]*s[0]; m[2] = r[6]*s[0]; m[3] = 0; m += 4; + m[0] = r[1]*s[1]; m[1] = r[4]*s[1]; m[2] = r[7]*s[1]; m[3] = 0; m += 4; + m[0] = r[2]*s[2]; m[1] = r[5]*s[2]; m[2] = r[8]*s[2]; m[3] = 0; m += 4; + m[0] = t[0]; m[1] = t[1]; m[2] = t[2]; m[3] = 1; + bAsOK = kFALSE; +} + +//______________________________________________________________________________ +void TEveTrans::SetGeoHMatrix(TGeoHMatrix& mat) +{ + Double_t *r = mat.GetRotationMatrix(); + Double_t *t = mat.GetTranslation(); + Double_t *s = mat.GetScale(); + if (fUseTrans) + { + mat.SetBit(TGeoMatrix::kGeoGenTrans); + Double_t *m = M; + GetScale(s[0], s[1], s[2]); + r[0] = m[0]/s[0]; r[3] = m[1]/s[0]; r[6] = m[2]/s[0]; m += 4; + r[1] = m[0]/s[1]; r[4] = m[1]/s[1]; r[7] = m[2]/s[1]; m += 4; + r[2] = m[0]/s[2]; r[5] = m[1]/s[2]; r[8] = m[2]/s[2]; m += 4; + t[0] = m[0]; t[1] = m[1]; t[2] = m[2]; + } else { + mat.ResetBit(TGeoMatrix::kGeoGenTrans); + r[0] = 1; r[3] = 0; r[6] = 0; + r[1] = 0; r[4] = 1; r[7] = 0; + r[2] = 0; r[5] = 0; r[8] = 1; + s[0] = s[1] = s[2] = 1; + t[0] = t[1] = t[2] = 0; + } +} + +//______________________________________________________________________________ +void TEveTrans::SetBuffer3D(TBuffer3D& buff) +{ + buff.fLocalFrame = fUseTrans; + if (fUseTrans) { + // In phys-shape ctor the rotation part is transposed, due to + // TGeo's convention for rotation matrix. So we have to transpose + // it here, also. + Double_t *B = buff.fLocalMaster; + B[0] = M[0]; B[1] = M[4]; B[2] = M[8]; B[3] = M[3]; + B[4] = M[1]; B[5] = M[5]; B[6] = M[9]; B[7] = M[7]; + B[8] = M[2]; B[9] = M[6]; B[10] = M[10]; B[11] = M[11]; + B[12] = M[12]; B[13] = M[13]; B[14] = M[14]; B[15] = M[15]; + // Otherwise this would do: + // memcpy(buff.fLocalMaster, M, 16*sizeof(Double_t)); + } +} + +//______________________________________________________________________________ +Bool_t TEveTrans::IsScale(Double_t low, Double_t high) const +{ + // Test if the transformation is a scale. + // To be used by ROOT TGLObject descendants that potentially need to + // use GL_NORMALIZE. + // The low/high limits are expected to be squares of acutal limits. + // + // Ideally this should be done by the TGLViewer [but is not]. + + if (!fUseTrans) return kFALSE; + Double_t s; + s = M[F00]*M[F00] + M[F10]*M[F10] + M[F20]*M[F20]; + if (s < low || s > high) return kTRUE; + s = M[F01]*M[F01] + M[F11]*M[F11] + M[F21]*M[F21]; + if (s < low || s > high) return kTRUE; + s = M[F02]*M[F02] + M[F12]*M[F12] + M[F22]*M[F22]; + if (s < low || s > high) return kTRUE; + return kFALSE; +} diff --git a/eve/src/TEveTransEditor.cxx b/eve/src/TEveTransEditor.cxx new file mode 100644 index 0000000000..d76d9790ce --- /dev/null +++ b/eve/src/TEveTransEditor.cxx @@ -0,0 +1,232 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include + +#include +#include + +#include + +//______________________________________________________________________________ +// TEveTransSubEditor +// +// Sub-editor for TEveTrans class. + +ClassImp(TEveTransSubEditor) + +//______________________________________________________________________________ +TEveTransSubEditor::TEveTransSubEditor(TGWindow* p) : + TGVerticalFrame(p), + fTrans (0), + + fTopHorFrame(0), + + fUseTrans(0), + fEditTrans(0), + + fEditTransFrame(0), + + fPos(0), + fRot(0), + fScale(0), + + fAutoUpdate(0), + fUpdate(0) +{ + // --- Top controls + + fTopHorFrame = new TGHorizontalFrame(this); + + fUseTrans = new TGCheckButton(fTopHorFrame, "UseTrans"); + fTopHorFrame->AddFrame(fUseTrans, new TGLayoutHints(kLHintsLeft, 1,2,0,0)); + fUseTrans->Connect("Toggled(Bool_t)", "TEveTransSubEditor", this, "DoUseTrans()"); + fEditTrans = new TGCheckButton(fTopHorFrame, "EditTrans"); + fTopHorFrame->AddFrame(fEditTrans, new TGLayoutHints(kLHintsLeft, 2,1,0,0)); + fEditTrans->Connect("Toggled(Bool_t)"," TEveTransSubEditor", this, "DoEditTrans()"); + + AddFrame(fTopHorFrame, new TGLayoutHints(kLHintsTop, 0,0,2,1)); + + + // --- Trans edit part + + fEditTransFrame = new TGVerticalFrame(this); + + fPos = new TEveGTriVecValuator(fEditTransFrame, "Pos", 160, 20); + fPos->SetLabelWidth(17); + fPos->SetNELength(6); + fPos->Build(kFALSE, "x", "y", "z"); + fPos->SetLimits(-1e5, 1e5, TGNumberFormat::kNESRealThree); + fEditTransFrame->AddFrame(fPos, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0,0,0,0)); + + fRot = new TEveGTriVecValuator(fEditTransFrame, "Rot", 160, 20); + fRot->SetLabelWidth(17); + fRot->SetNELength(6); + fRot->Build(kFALSE, "Rz", "RY", "Rx"); + fRot->SetLimits(-360, 360, TGNumberFormat::kNESRealOne); + fEditTransFrame->AddFrame(fRot, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0,0,0,0)); + + fScale = new TEveGTriVecValuator(fEditTransFrame, "Scale", 160, 20); + fScale->SetLabelWidth(17); + fScale->SetNELength(6); + fScale->Build(kFALSE, "Sx", "Sy", "Sz"); + fScale->SetLimits(1e-2, 1e2, TGNumberFormat::kNESRealTwo); + fEditTransFrame->AddFrame(fScale, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0,0,0,0)); + + fPos ->Connect("ValueSet()", "TEveTransSubEditor", this, "DoTransChanged()"); + fRot ->Connect("ValueSet()", "TEveTransSubEditor", this, "DoTransChanged()"); + fScale->Connect("ValueSet()", "TEveTransSubEditor", this, "DoTransChanged()"); + + { + TGHorizontalFrame* hframe = new TGHorizontalFrame(fEditTransFrame); + + fAutoUpdate = new TGCheckButton(hframe, "AutoUpdate"); + hframe->AddFrame(fAutoUpdate, new TGLayoutHints(kLHintsLeft, 1,10,1,1)); + fUpdate = new TGTextButton(hframe, "Update"); + hframe->AddFrame(fUpdate, new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 5,5,1,1)); + fUpdate->Connect("Clicked()", "TEveTransSubEditor", this, "TransChanged()"); + + fEditTransFrame->AddFrame(hframe, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0,0,4,0)); + } + + AddFrame(fEditTransFrame, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0,0,1,2)); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTransSubEditor::SetDataFromTrans(TEveTrans* t) +{ + fTrans = t; + + fUseTrans ->SetState(fTrans->fUseTrans ? kButtonDown : kButtonUp); + fEditTrans->SetState(fTrans->fEditTrans ? kButtonDown : kButtonUp); + if (fTrans->fEditTrans) + fEditTransFrame->MapWindow(); + else + fEditTransFrame->UnmapWindow(); + ((TGMainFrame*)fEditTransFrame->GetMainFrame())->Layout(); + + fPos->SetValues(fTrans->ArrT()); + Float_t a[3]; + fTrans->GetRotAngles(a); + a[0] *= TMath::RadToDeg(); + a[1] *= TMath::RadToDeg(); + a[2] *= TMath::RadToDeg(); + fRot->SetValues(a); + Double_t x, y, z; + fTrans->GetScale(x, y, z); + fScale->SetValues(x, y, z); +} + +//______________________________________________________________________________ +void TEveTransSubEditor::SetTransFromData() +{ + Double_t v[3]; + fTrans->UnitTrans(); + fRot->GetValues(v); + fTrans->SetRotByAngles(v[0]*TMath::DegToRad(), v[1]*TMath::DegToRad(), v[2]*TMath::DegToRad()); + fPos->GetValues(v); + fTrans->SetPos(v); + fScale->GetValues(v); + fTrans->Scale(v[0], v[1], v[2]); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTransSubEditor::UseTrans() +{ + Emit("UseTrans()"); +} + +//______________________________________________________________________________ +void TEveTransSubEditor::TransChanged() +{ + SetTransFromData(); + Emit("TransChanged()"); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTransSubEditor::DoUseTrans() +{ + fTrans->SetUseTrans(fUseTrans->IsOn()); + UseTrans(); +} + +//______________________________________________________________________________ +void TEveTransSubEditor::DoEditTrans() +{ + fTrans->SetEditTrans(fEditTrans->IsOn()); + if (fEditTrans->IsOn()) + fEditTransFrame->MapWindow(); + else + fEditTransFrame->UnmapWindow(); + ((TGMainFrame*)fEditTransFrame->GetMainFrame())->Layout(); +} + +//______________________________________________________________________________ +void TEveTransSubEditor::DoTransChanged() +{ + if (fAutoUpdate->IsOn()) + TransChanged(); +} + + +//______________________________________________________________________________ +// TEveTransEditor +// +// Editor for TEveTrans class. + +ClassImp(TEveTransEditor) + +//______________________________________________________________________________ +TEveTransEditor::TEveTransEditor(const TGWindow *p, Int_t width, Int_t height, + UInt_t options, Pixel_t back) : + TGedFrame(p, width, height, options | kVerticalFrame, back), + fM(0) + // Initialize widget pointers to 0 +{ + MakeTitle("TEveTrans"); + + // Create widgets + // fXYZZ = new TGSomeWidget(this, ...); + // AddFrame(fXYZZ, new TGLayoutHints(...)); + // fXYZZ->Connect("SignalName()", "TEveTransEditor", this, "DoXYZZ()"); +} + +TEveTransEditor::~TEveTransEditor() +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTransEditor::SetModel(TObject* obj) +{ + fM = dynamic_cast(obj); + + // Set values of widgets + // fXYZZ->SetValue(fM->GetXYZZ()); +} + +/******************************************************************************/ + +// Implements callback/slot methods + +// void TEveTransEditor::DoXYZZ() +// { +// fM->SetXYZZ(fXYZZ->GetValue()); +// Update(); +// } diff --git a/eve/src/TEveTreeTools.cxx b/eve/src/TEveTreeTools.cxx new file mode 100644 index 0000000000..404cbd572f --- /dev/null +++ b/eve/src/TEveTreeTools.cxx @@ -0,0 +1,125 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +//______________________________________________________________________________ +// TTreeTools +// +// Collection of classes for TTree interaction. + +#include +#include +#include + +/******************************************************************************/ +/******************************************************************************/ + +//______________________________________________________________________________ +// TEveSelectorToEventList +// +// TSelector that stores entry numbers of matching TTree entries into +// an event-list. + + +ClassImp(TEveSelectorToEventList) + +//______________________________________________________________________________ +TEveSelectorToEventList::TEveSelectorToEventList(TEventList* evl, const Text_t* sel) : + TSelectorDraw(), fEvList(evl) +{ + fInput.Add(new TNamed("varexp", "")); + fInput.Add(new TNamed("selection", sel)); + SetInputList(&fInput); +} + +//______________________________________________________________________________ +Bool_t TEveSelectorToEventList::Process(Long64_t entry) +{ + if(GetSelect()->EvalInstance(0) != 0) + fEvList->Enter(entry); + return kTRUE; +} + + +//______________________________________________________________________________ +// TEvePointSelector, TEvePointSelectorConsumer +// +// TEvePointSelector is a sub-class of TSelectorDraw for direct +// extraction of point-like data from a Tree. +// +// TEvePointSelectorConsumer is a virtual base for classes that can be +// filled from TTree data via the TEvePointSelector class. + +ClassImp(TEvePointSelector) +ClassImp(TEvePointSelectorConsumer) + +//______________________________________________________________________________ +TEvePointSelector::TEvePointSelector(TTree* t, + TEvePointSelectorConsumer* c, + const Text_t* vexp, const Text_t* sel) : + TSelectorDraw(), + + fTree (t), + fConsumer (c), + fVarexp (vexp), + fSelection (sel), + fSubIdExp (), + fSubIdNum (0) +{ + SetInputList(&fInput); +} + +//______________________________________________________________________________ +Long64_t TEvePointSelector::Select(const Text_t* selection) +{ + TString var(fVarexp); + if (fSubIdExp.IsNull()) { + fSubIdNum = 0; + } else { + fSubIdNum = fSubIdExp.CountChar(':') + 1; + var += ":" + fSubIdExp; + } + + TString sel; + if (selection != 0) + sel = selection; + else + sel = fSelection; + + fInput.Delete(); + fInput.Add(new TNamed("varexp", var.Data())); + fInput.Add(new TNamed("selection", sel.Data())); + + if (fConsumer) + fConsumer->InitFill(fSubIdNum); + + // 'para' option -> hack allowing arbitrary dimensions. + if(fTree) + fTree->Process(this, "goff para"); + + return fSelectedRows; +} + +//______________________________________________________________________________ +Long64_t TEvePointSelector::Select(TTree* t, const Text_t* selection) +{ + fTree = t; + return Select(selection); +} + +//______________________________________________________________________________ +void TEvePointSelector::TakeAction() +{ + fSelectedRows += fNfill; + // printf("TEvePointSelector::TakeAction nfill=%d, nall=%lld\n", fNfill, fSelectedRows); + if (fConsumer) { + fConsumer->TakeAction(this); + } +} diff --git a/eve/src/TEveTriangleSet.cxx b/eve/src/TEveTriangleSet.cxx new file mode 100644 index 0000000000..794d3ff7a3 --- /dev/null +++ b/eve/src/TEveTriangleSet.cxx @@ -0,0 +1,198 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +//______________________________________________________________________________ +// TEveTriangleSet +// +// Made from a list of vertices and a list of triangles (triplets of +// vertex indices). +// +// If input is composed from triangles with direct vertex coordinates +// one should consider finding all occurences of the same vertex +// and specifying it only once. +// + +ClassImp(TEveTriangleSet) + +//______________________________________________________________________________ +TEveTriangleSet::TEveTriangleSet(Int_t nv, Int_t nt, Bool_t norms, Bool_t cols) : + TEveElement(fColor), + TNamed("TEveTriangleSet", 0), + fNVerts (nv), fVerts(0), + fNTrings (nt), fTrings(0), fTringNorms(0), fTringCols(0), + fColor (2), fTransp(0), + fHMTrans () +{ + // Constructor. + + fVerts = new Float_t[3*fNVerts]; + fTrings = new Int_t [3*fNTrings]; + fTringNorms = (norms) ? new Float_t[3*fNTrings] : 0; + fTringCols = (cols) ? new UChar_t[3*fNTrings] : 0; +} + +//______________________________________________________________________________ +TEveTriangleSet::~TEveTriangleSet() +{ + // Destructor. + + delete [] fVerts; + delete [] fTrings; + delete [] fTringNorms; + delete [] fTringCols; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTriangleSet::GenerateTriangleNormals() +{ + // Generate triangle normals via cross product of triangle edges. + + if (fTringNorms == 0) fTringNorms = new Float_t[3*fNTrings]; + + TVector3 e1, e2, n; + Float_t *N = fTringNorms; + Int_t *T = fTrings; + for(Int_t t=0; tRedraw3D(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTriangleSet::ComputeBBox() +{ + if (fNVerts <= 0) { + BBoxZero(); + return; + } + + BBoxInit(); + Float_t* v = fVerts; + for (Int_t i=0; iGetViewer3D()->AddObject(buffer); + if (reqSections == TBuffer3D::kNone) { + return; + } + + Error("TEveTriangleSet::Paint", "only direct OpenGL rendering supported."); +} + +/******************************************************************************/ + +#include + +//______________________________________________________________________________ +TEveTriangleSet* TEveTriangleSet::ReadTrivialFile(const char* file) +{ + FILE* f = fopen(file, "r"); + if (f == 0) { + ::Error("TEveTriangleSet::ReadTrivialFile", Form("file '%s' not found.", file)); + return 0; + } + + Int_t nv, nt; + fscanf(f, "%d %d", &nv, &nt); + + TEveTriangleSet* ts = new TEveTriangleSet(nv, nt); + + Float_t *V = ts->Vertex(0); + for (Int_t i=0; iTriangle(0); + for (Int_t i=0; i +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +//______________________________________________________________________________ +// TEveTriangleSetEditor +// +// Editor for TEveTriangleSet class. + +ClassImp(TEveTriangleSetEditor) + +//______________________________________________________________________________ +TEveTriangleSetEditor::TEveTriangleSetEditor(const TGWindow *p, Int_t width, Int_t height, + UInt_t options, Pixel_t back) : + TGedFrame(p, width, height, options | kVerticalFrame, back), + fM(0), + fHMTrans(0) +{ + MakeTitle("TEveTriangleSet"); + + fHMTrans = new TEveTransSubEditor(this); + fHMTrans->Connect("UseTrans()", "TEveTriangleSetEditor", this, "Update()"); + fHMTrans->Connect("TransChanged()", "TEveTriangleSetEditor", this, "Update()"); + AddFrame(fHMTrans, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 2, 0, 0, 0)); +} + +//______________________________________________________________________________ +TEveTriangleSetEditor::~TEveTriangleSetEditor() +{ + delete fHMTrans; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTriangleSetEditor::SetModel(TObject* obj) +{ + fM = dynamic_cast(obj); + + fHMTrans->SetDataFromTrans(&fM->fHMTrans); +} diff --git a/eve/src/TEveTriangleSetGL.cxx b/eve/src/TEveTriangleSetGL.cxx new file mode 100644 index 0000000000..af733c8615 --- /dev/null +++ b/eve/src/TEveTriangleSetGL.cxx @@ -0,0 +1,123 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include + +#include + +//______________________________________________________________________________ +// TEveTriangleSetGL +// +// GL-renderer for TEveTriangleSet class. +// +// See also: TGLObject, TGLLogicalShape. + +ClassImp(TEveTriangleSetGL) + +//______________________________________________________________________________ +TEveTriangleSetGL::TEveTriangleSetGL() : TGLObject(), fM(0) +{ + // Constructor. + + // fDLCache = false; // Disable display list. +} + +//______________________________________________________________________________ +TEveTriangleSetGL::~TEveTriangleSetGL() +{ + // Destructor. +} + +/******************************************************************************/ + +//______________________________________________________________________________ +Bool_t TEveTriangleSetGL::SetModel(TObject* obj, const Option_t* /*opt*/) +{ + // Set model object. + + if(SetModelCheckClass(obj, TEveTriangleSet::Class())) { + fM = dynamic_cast(obj); + return kTRUE; + } + return kFALSE; +} + +//______________________________________________________________________________ +void TEveTriangleSetGL::SetBBox() +{ + // Set bounding-box from the model. + + // !! This ok if master sub-classed from TAttBBox + SetAxisAlignedBBox(((TEveTriangleSet*)fExternalObj)->AssertBBox()); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveTriangleSetGL::DirectDraw(TGLRnrCtx & /*rnrCtx*/) const +{ + // Low-level GL rendering. + + TEveTriangleSet& TS = *fM; + Bool_t isScaled = TS.fHMTrans.IsScale(); + + GLint ex_shade_model; + glGetIntegerv(GL_SHADE_MODEL, &ex_shade_model); + glShadeModel(GL_FLAT); + + glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT); + + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + glPolygonMode(GL_FRONT, GL_FILL); + glPolygonMode(GL_BACK, GL_LINE); + glDisable(GL_CULL_FACE); + if (isScaled) glEnable(GL_NORMALIZE); + glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); + glVertexPointer(3, GL_FLOAT, 0, TS.fVerts); + glEnableClientState(GL_VERTEX_ARRAY); + + Int_t* T = TS.fTrings; + Float_t* N = TS.fTringNorms; + UChar_t* C = TS.fTringCols; + + TVector3 e1, e2, n; + + glBegin(GL_TRIANGLES); + for(Int_t t=0; t +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +//______________________________________________________________________________ +// TEveUtil +// +// Standard utility functions for Reve. + +ClassImp(TEveUtil) + +//______________________________________________________________________________ +void TEveUtil::SetupEnvironment() +{ + // Setup Include and Macro paths. + // Since inclusion into ROOT this does nothing but could + // potentially be reactivated if some common macros are established + // and shipped with binary ROOT (in macros/eve). For example, these + // might be used to spawn specific GUI / GL configurations. + + static const TEveException eH("TEveUtil::SetupEnvironment"); + static Bool_t setupDone = kFALSE; + + if (setupDone) { + Info(eH.Data(), "has already been run."); + return; + } + + // Old initialization for ALICE. + // Left as an example. + /* + // Check if REVESYS exists, try fallback to $ALICE_ROOT/EVE. + if(gSystem->Getenv("REVESYS") == 0) { + if(gSystem->Getenv("ALICE_ROOT") != 0) { + Info(eH.Data(), "setting REVESYS from ALICE_ROOT."); + gSystem->Setenv("REVESYS", Form("%s/EVE", gSystem->Getenv("ALICE_ROOT"))); + } else { + Error(eH.Data(), "REVESYS not defined, neither is ALICE_ROOT."); + gSystem->Exit(1); + } + } + if(gSystem->AccessPathName(gSystem->Getenv("REVESYS")) == kTRUE) { + Error(eH.Data(), "REVESYS '%s' does not exist.", gSystem->Getenv("REVESYS")); + gSystem->Exit(1); + } + + TString macPath(gROOT->GetMacroPath()); + macPath += Form(":%s/macros", gSystem->Getenv("REVESYS")); + gInterpreter->AddIncludePath(gSystem->Getenv("REVESYS")); + if(gSystem->Getenv("ALICE_ROOT") != 0) { + macPath += Form(":%s/alice-macros", gSystem->Getenv("REVESYS")); + gInterpreter->AddIncludePath(Form("%s/include", gSystem->Getenv("ALICE_ROOT"))); + gInterpreter->AddIncludePath(gSystem->Getenv("ALICE_ROOT")); + } + gROOT->SetMacroPath(macPath); + */ +} + +//______________________________________________________________________________ +void TEveUtil::SetupGUI() +{ + // Setup icon pictures and mime-types. + + TString fld( Form("%s/icons/", gSystem->Getenv("ROOTSYS")) ); + + TEveElement::fgRnrIcons[0] = gClient->GetPicture(fld + "eve_rnr00_t.xpm"); + TEveElement::fgRnrIcons[1] = gClient->GetPicture(fld + "eve_rnr01_t.xpm"); + TEveElement::fgRnrIcons[2] = gClient->GetPicture(fld + "eve_rnr10_t.xpm"); + TEveElement::fgRnrIcons[3] = gClient->GetPicture(fld + "eve_rnr11_t.xpm"); + + TEveElement::fgListTreeIcons[0] = gClient->GetPicture("folder_t.xpm"); + TEveElement::fgListTreeIcons[1] = gClient->GetPicture(fld + "eve_viewer.xpm"); + TEveElement::fgListTreeIcons[2] = gClient->GetPicture(fld + "eve_scene.xpm"); + TEveElement::fgListTreeIcons[3] = gClient->GetPicture(fld + "eve_pointset.xpm"); + TEveElement::fgListTreeIcons[4] = gClient->GetPicture(fld + "eve_track.xpm"); + + gClient->GetMimeTypeList()->AddType("root/tmacro", "TEveMacro", + "tmacro_s.xpm", "tmacro_t.xpm", ""); +} + +/******************************************************************************/ + +namespace +{ +//______________________________________________________________________________ +void ChompTail(TString& s, char c='.') +{ + Ssiz_t p = s.Last(c); + if(p != kNPOS) + s.Remove(p); +} +} + +//______________________________________________________________________________ +Bool_t TEveUtil::CheckMacro(const Text_t* mac) +{ + // Checks if macro 'mac' is loaded. + + // Axel's advice; now sth seems slow, using old method below for test. + // return gROOT->GetInterpreter()->IsLoaded(mac); + + // Previous version expected function with same name and used ROOT's + // list of global functions. + + TString foo(mac); ChompTail(foo); + /* + if(recreate) { + TCollection* logf = gROOT->GetListOfGlobalFunctions(kFALSE); + logf->SetOwner(); + logf->Clear(); + } + */ + if (gROOT->GetGlobalFunction(foo.Data(), 0, kFALSE) != 0) + return kTRUE; + else + return (gROOT->GetGlobalFunction(foo.Data(), 0, kTRUE) != 0); +} + +//______________________________________________________________________________ +void TEveUtil::AssertMacro(const Text_t* mac) +{ + // Load and execute macro 'mac' if it has not been loaded yet. + + if(CheckMacro(mac) == kFALSE) { + gROOT->Macro(mac); + } +} + +//______________________________________________________________________________ +void TEveUtil::Macro(const Text_t* mac) +{ + // Execute macro 'mac'. Do not reload the macro. + + if(CheckMacro(mac) == kFALSE) { + gROOT->LoadMacro(mac); + } + TString foo(mac); ChompTail(foo); foo += "()"; + gROOT->ProcessLine(foo.Data()); +} + +//______________________________________________________________________________ +void TEveUtil::LoadMacro(const Text_t* mac) +{ + // Makes sure that macro 'mac' is loaded, but do not reload it. + + if(CheckMacro(mac) == kFALSE) { + gROOT->LoadMacro(mac); + } +} + +/******************************************************************************/ +// Color management +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveUtil::ColorFromIdx(Color_t ci, UChar_t col[4], Bool_t alpha) +{ + // Fill col with RGBA values corresponding to index ci. If alpha + // is true, set alpha component of col to 255. + // ROOT's indexed color palette does not support transparency. + + if (ci < 0) { + col[0] = col[1] = col[2] = col[3] = 0; + return; + } + TColor* c = gROOT->GetColor(ci); + if (c) { + col[0] = (UChar_t)(255*c->GetRed()); + col[1] = (UChar_t)(255*c->GetGreen()); + col[2] = (UChar_t)(255*c->GetBlue()); + if (alpha) col[3] = 255; + } +} + +//______________________________________________________________________________ +void TEveUtil::ColorFromIdx(Float_t f1, Color_t c1, Float_t f2, Color_t c2, + UChar_t col[4], Bool_t alpha) +{ + // Fill col with weighted RGBA values corresponding to + // color-indices c1 and c2. If alpha is true, set alpha component + // of col to 255. + + TColor* t1 = gROOT->GetColor(c1); + TColor* t2 = gROOT->GetColor(c2); + if(t1 && t2) { + col[0] = (UChar_t)(255*(f1*t1->GetRed() + f2*t2->GetRed())); + col[1] = (UChar_t)(255*(f1*t1->GetGreen() + f2*t2->GetGreen())); + col[2] = (UChar_t)(255*(f1*t1->GetBlue() + f2*t2->GetBlue())); + if (alpha) col[3] = 255; + } +} + +//______________________________________________________________________________ +Color_t* TEveUtil::FindColorVar(TObject* obj, const Text_t* varname) +{ + // Find address of Color_t data-member with name varname in object + // obj. + // + // This is used to access color information for TGListTreeItem + // coloration from visualization macros that wrap TObjects into + // TEveElementObjectPtr instances. + + static const TEveException eH("TEveUtil::FindColorVar"); + + Int_t off = obj->IsA()->GetDataMemberOffset(varname); + if(off == 0) + throw(eH + "could not find member '" + varname + "' in class " + obj->IsA()->GetName() + "."); + return (Color_t*) (((char*)obj) + off); +} + + +/******************************************************************************/ +// TEveException +/******************************************************************************/ + +// TString .vs. string + +//______________________________________________________________________________ +bool operator==(const TString& t, const std::string& s) +{ return (s == t.Data()); } + +bool operator==(const std::string& s, const TString& t) +{ return (s == t.Data()); } + +// Exc + +TEveException::TEveException(const std::string& s) : TString(s.c_str()) {} + +// Exc + ops + +TEveException operator+(const TEveException &s1, const std::string &s2) +{ TEveException r(s1); r += s2; return r; } + +TEveException operator+(const TEveException &s1, const TString &s2) +{ TEveException r(s1); r += s2; return r; } + +TEveException operator+(const TEveException &s1, const char *s2) +{ TEveException r(s1); r += s2; return r; } + + +/******************************************************************************/ +// TEvePadHolder +/******************************************************************************/ + +TEvePadHolder::TEvePadHolder(Bool_t modify_update_p, TVirtualPad* new_pad, Int_t subpad) : + fOldPad (gPad), + fModifyUpdateP (modify_update_p) +{ + if (new_pad != 0) + new_pad->cd(subpad); + else + gPad = 0; +} + +//______________________________________________________________________________ +TEvePadHolder::~TEvePadHolder() +{ + if(fModifyUpdateP && gPad != 0) { + gPad->Modified(); + gPad->Update(); + } + gPad = fOldPad; +} + +/******************************************************************************/ +// TEveGeoManagerHolder +/******************************************************************************/ + +//______________________________________________________________________________ +TEveGeoManagerHolder::TEveGeoManagerHolder(TGeoManager* new_gmgr) : + fManager(gGeoManager) +{ + gGeoManager = new_gmgr; +} + +//______________________________________________________________________________ +TEveGeoManagerHolder::~TEveGeoManagerHolder() +{ + gGeoManager = fManager; +} + + +//______________________________________________________________________________ +// TEveRefBackPtr +// +// Base-class for reference-counted objects with reverse references to +// TEveElement objects. + +ClassImp(TEveRefBackPtr) + +//______________________________________________________________________________ +TEveRefBackPtr::TEveRefBackPtr() : + TEveRefCnt(), + fBackRefs() +{ + // Default constructor. +} + +//______________________________________________________________________________ +TEveRefBackPtr::~TEveRefBackPtr() +{ + // Destructor. Noop, should complain if back-ref list is not empty. + + // !!!! Complain if list not empty. +} + +//______________________________________________________________________________ +TEveRefBackPtr::TEveRefBackPtr(const TEveRefBackPtr&) : + TEveRefCnt(), + fBackRefs() +{ + // Copy constructor. New copy starts with zero reference count and + // empty back-reference list. +} + +//______________________________________________________________________________ +TEveRefBackPtr& TEveRefBackPtr::operator=(const TEveRefBackPtr&) +{ + // Assignment operator. Reference count and back-reference + // information is not assigned as these object hold pointers to a + // specific object. + + return *this; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveRefBackPtr::IncRefCount(TEveElement* re) +{ + // Increase reference cound and add re to the list of back-references. + + TEveRefCnt::IncRefCount(); + fBackRefs.push_back(re); +} + +//______________________________________________________________________________ +void TEveRefBackPtr::DecRefCount(TEveElement* re) +{ + // Decrease reference cound and remove re from the list of back-references. + + static const TEveException eH("TEveRefBackPtr::DecRefCount "); + + std::list::iterator i = + std::find(fBackRefs.begin(), fBackRefs.end(), re); + if (i != fBackRefs.end()) { + fBackRefs.erase(i); + TEveRefCnt::DecRefCount(); + } else { + Warning(eH, Form("render element '%s' not found in back-refs.", + re->GetObject()->GetName())); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveRefBackPtr::UpdateBackPtrItems() +{ + std::list::iterator i = fBackRefs.begin(); + while (i != fBackRefs.end()) + { + (*i)->UpdateItems(); + ++i; + } +} diff --git a/eve/src/TEveVSD.cxx b/eve/src/TEveVSD.cxx new file mode 100644 index 0000000000..a992e994bb --- /dev/null +++ b/eve/src/TEveVSD.cxx @@ -0,0 +1,240 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include + +//______________________________________________________________________________ +// TEveVSD +// +// Visualization Summary Data - a collection of trees holding standard event data in experiment independant format. + +ClassImp(TEveVSD) + +//______________________________________________________________________________ +TEveVSD::TEveVSD(const Text_t* , const Text_t* ) : + TObject(), + + fBuffSize (128*1024), + + mFile (0), + mDirectory (0), + + mTreeK (0), + //mTreeTR (0), + mTreeH (0), + mTreeC (0), + mTreeR (0), + mTreeKK (0), + mTreeV0 (0), + mTreeGI (0), + + mK(), mpK (&mK), + mH(), mpH (&mH), + mC(), mpC (&mC), + mR(), mpR (&mR), + mKK(), mpKK(&mKK), + mV0(), mpV0(&mV0), + mGI(), mpGI(&mGI) +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveVSD::SetDirectory(TDirectory* dir) +{ + mDirectory = dir; +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveVSD::CreateTrees() +{ + mDirectory->cd(); + // TR missing ... + mTreeK = new TTree("Kinematics", "Simulated tracks."); + mTreeH = new TTree("Hits", "Combined detector hits."); + mTreeC = new TTree("Clusters", "Reconstructed clusters."); + mTreeR = new TTree("RecTracks", "Reconstructed tracks."); + mTreeKK = new TTree("RecKinks", "Reconstructed kinks."); + mTreeV0 = new TTree("RecV0s", "Reconstructed V0s."); + mTreeGI = new TTree("TEveMCRecCrossRef", "Objects prepared for cross query."); +} + +//______________________________________________________________________________ +void TEveVSD::DeleteTrees() +{ + delete mTreeK; mTreeK = 0; + // delete mTreeTR; mTreeTR = 0; + delete mTreeH; mTreeH = 0; + delete mTreeC; mTreeC = 0; + delete mTreeR; mTreeR = 0; + delete mTreeV0; mTreeV0 = 0; + delete mTreeKK; mTreeKK = 0; + delete mTreeGI; mTreeGI = 0; +} + +//______________________________________________________________________________ +void TEveVSD::CreateBranches() +{ + // TR missing ... + if(mTreeK) + mTreeK ->Branch("K", "TEveMCTrack", &mpK, fBuffSize); + if(mTreeH) + mTreeH ->Branch("H", "TEveHit", &mpH, fBuffSize); + if(mTreeC) + mTreeC ->Branch("C", "TEveCluster", &mpC, fBuffSize); + if(mTreeR) + mTreeR ->Branch("R", "TEveRecTrack", &mpR, fBuffSize); + if(mTreeKK) + mTreeKK->Branch("KK", "TEveRecKink", &mpKK, fBuffSize); + if(mTreeV0) + mTreeV0->Branch("V0", "TEveRecV0", &mpV0, fBuffSize); + + if(mTreeGI) { + mTreeGI->Branch("GI", "TEveMCRecCrossRef", &mpGI, fBuffSize); + mTreeGI->Branch("K.", "TEveMCTrack", &mpK); + mTreeGI->Branch("R.", "TEveRecTrack", &mpR); + } +} + +//______________________________________________________________________________ +void TEveVSD::SetBranchAddresses() +{ + // TR missing ... + if(mTreeK) + mTreeK ->SetBranchAddress("K", &mpK); + if(mTreeH) + mTreeH ->SetBranchAddress("H", &mpH); + if(mTreeC) + mTreeC ->SetBranchAddress("C", &mpC); + if(mTreeR) + mTreeR ->SetBranchAddress("R", &mpR); + if(mTreeKK) + mTreeKK->SetBranchAddress("KK", &mpKK); + if(mTreeV0) + mTreeV0->SetBranchAddress("V0", &mpV0); + + if(mTreeGI) { + mTreeGI->SetBranchAddress("GI", &mpGI); + mTreeGI->SetBranchAddress("K.", &mpK); + mTreeGI->SetBranchAddress("R.", &mpR); + } +} + +//______________________________________________________________________________ +void TEveVSD::WriteTrees() +{ + // Does nothing here ... +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveVSD::LoadTrees() +{ + static const TEveException eH("TEveVSD::LoadTrees "); + + if(mDirectory == 0) + throw(eH + "directory not set."); + + printf("Reading kinematics.\n"); + mTreeK = (TTree*) mDirectory->Get("Kinematics"); + if(mTreeK == 0) { + printf("%s Kinematics not available in mDirectory %s.\n", + eH.Data(), mDirectory->GetName()); + } + + printf("Reading hits.\n"); + mTreeH = (TTree*) mDirectory->Get("Hits"); + if(mTreeH == 0) { + printf("%s Hits not available in mDirectory %s.\n", + eH.Data(), mDirectory->GetName()); + } + + printf("Reading clusters.\n"); + mTreeC = (TTree*) mDirectory->Get("Clusters"); + if(mTreeC == 0) { + printf("%s Clusters not available in mDirectory %s.\n", + eH.Data(), mDirectory->GetName()); + } + + printf("Reading reconstructed tracks.\n"); + mTreeR = (TTree*) mDirectory->Get("RecTracks"); + if(mTreeR == 0) { + printf("%s RecTracks not available in mDirectory %s.\n", + eH.Data(), mDirectory->GetName()); + } + + printf("Reading reconstructed kinks. \n"); + mTreeKK = (TTree*) mDirectory->Get("RecKinks"); + if(mTreeKK == 0) { + printf("%s Kinks not available in mDirectory %s.\n", + eH.Data(), mDirectory->GetName()); + } + + printf("Reading Reconstructed V0s.\n"); + mTreeV0 = (TTree*) mDirectory->Get("RecV0s"); + if(mTreeV0 == 0) { + printf("%s V0 not available in mDirectory %s.\n", + eH.Data(), mDirectory->GetName()); + } + + printf("Reading TEveMCRecCrossRef.\n"); + mTreeGI = (TTree*)mDirectory->Get("TEveMCRecCrossRef"); + if(mTreeGI == 0) { + printf("%s TEveMCRecCrossRef not available in mDirectory %s.\n", + eH.Data(), mDirectory->GetName()); + } + +} + +//______________________________________________________________________________ +void TEveVSD::LoadVSD(const Text_t* vsd_file_name, const Text_t* dir_name) +{ + static const TEveException eH("TEveVSD::LoadVSD "); + + mFile = TFile::Open(vsd_file_name); + if(mFile == 0) + throw(eH + "can not open TEveVSD file '" + vsd_file_name + "'."); + + mDirectory = (TDirectory*) mFile->Get(dir_name); + if(mDirectory == 0) + throw(eH + "directory '" + dir_name + "' not found in TEveVSD file '" + vsd_file_name + "'."); + printf("%p\n", (void*)mDirectory); + LoadTrees(); + SetBranchAddresses(); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveVSD::DisableTObjectStreamersForVSDStruct() +{ + // Disble TObject streamers for those VSD structs that inherit from + // TObject directly. + + // TEveVector is not TObject + + // TEveMCTrack derives from TParticle + TParticle::Class()->IgnoreTObjectStreamer(true); + + TEveHit::Class()->IgnoreTObjectStreamer(true); + TEveCluster::Class()->IgnoreTObjectStreamer(true); + + TEveRecTrack::Class()->IgnoreTObjectStreamer(true); + // TEveRecKink derives from TEveRecTrack + + TEveRecV0::Class()->IgnoreTObjectStreamer(true); + + TEveMCRecCrossRef::Class()->IgnoreTObjectStreamer(true); +} diff --git a/eve/src/TEveVSDStructs.cxx b/eve/src/TEveVSDStructs.cxx new file mode 100644 index 0000000000..9dcb37942b --- /dev/null +++ b/eve/src/TEveVSDStructs.cxx @@ -0,0 +1,82 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 + +//______________________________________________________________________________ +// TEveVector +// +// Float three-vector; a inimal Float_t copy of TVector3 used to +// represent points and momenta (also used in VSD). + +ClassImp(TEveVector) + +//______________________________________________________________________________ +Float_t TEveVector::Eta() const +{ + Float_t cosTheta = CosTheta(); + if (cosTheta*cosTheta < 1) return -0.5* TMath::Log( (1.0-cosTheta)/(1.0+cosTheta) ); + Warning("Eta","transverse momentum = 0! return +/- 10e10"); + return (z >= 0) ? 10e10 : -10e10; +} + +//______________________________________________________________________________ +TEveVector TEveVector::operator + (const TEveVector & b) +{ + return TEveVector(x + b.x, y + b.y, z + b.z); +} + +//______________________________________________________________________________ +TEveVector TEveVector::operator - (const TEveVector & b) +{ + return TEveVector(x - b.x, y - b.y, z - b.z); +} + +//______________________________________________________________________________ +TEveVector TEveVector::operator * (Float_t a) +{ + return TEveVector(a*x, a*y, a*z); +} + + +//______________________________________________________________________________ +// TEvePathMark +// +// Special-point on track: position/momentum reference, daughter +// creation or decay (also used in VSD). + +ClassImp(TEvePathMark) + +//______________________________________________________________________________ +const char* TEvePathMark::type_name() +{ + switch (type) + { + case Daughter: return "Daughter"; + case Reference: return "Reference"; + case Decay: return "Decay"; + default: return "Unknown"; + } +} + + +//______________________________________________________________________________ +// +// Not documented. +// + +ClassImp(TEveMCTrack) +ClassImp(TEveHit) +ClassImp(TEveCluster) +ClassImp(TEveRecTrack) +ClassImp(TEveRecKink) +ClassImp(TEveRecV0) +ClassImp(TEveMCRecCrossRef) diff --git a/eve/src/TEveViewer.cxx b/eve/src/TEveViewer.cxx new file mode 100644 index 0000000000..3dcfe3a700 --- /dev/null +++ b/eve/src/TEveViewer.cxx @@ -0,0 +1,200 @@ +// @(#)root/eve:$Id$ +// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 + +/************************************************************************* + * Copyright (C) 1995-2007, 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 +#include +#include + +#include + +#include +#include + +#include // For fixing defaults in root 5.17.4 + +//______________________________________________________________________________ +// TEveViewer +// +// Reve representation of TGLViewer. + +ClassImp(TEveViewer) + +//______________________________________________________________________________ +TEveViewer::TEveViewer(const Text_t* n, const Text_t* t) : + TEveElementList(n, t), + fGLViewer (0) +{ + SetChildClass(TEveSceneInfo::Class()); +} + +//______________________________________________________________________________ +TEveViewer::~TEveViewer() +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveViewer::SetGLViewer(TGLViewer* s) +{ + delete fGLViewer; + fGLViewer = s; + + fGLViewer->SetSmartRefresh(kTRUE); + // fGLViewer->SetResetCamerasOnUpdate(kFALSE); + fGLViewer->SetResetCameraOnDoubleClick(kFALSE); + + // Temporary fix for wrong defaults in root 5.17.04 + fGLViewer->SetCurrentCamera(TGLViewer::kCameraOrthoXOY); + ((TGLOrthoCamera&)(fGLViewer->CurrentCamera())).SetEnableRotate(kTRUE); + fGLViewer->SetCurrentCamera(TGLViewer::kCameraOrthoXOZ); + ((TGLOrthoCamera&)(fGLViewer->CurrentCamera())).SetEnableRotate(kTRUE); + fGLViewer->SetCurrentCamera(TGLViewer::kCameraOrthoZOY); + ((TGLOrthoCamera&)(fGLViewer->CurrentCamera())).SetEnableRotate(kTRUE); + fGLViewer->SetCurrentCamera(TGLViewer::kCameraPerspXOZ); +} + +//______________________________________________________________________________ +void TEveViewer::SpawnGLViewer(const TGWindow* parent, TGedEditor* ged) +{ + TGLSAViewer* v = new TGLSAViewer(parent, 0, ged); + v->ToggleEditObject(); + SetGLViewer(v); +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveViewer::AddScene(TEveScene* scene) +{ + static const TEveException eH("TEveViewer::AddScene "); + + TGLSceneInfo* glsi = fGLViewer->AddScene(scene->GetGLScene()); + if (glsi != 0) { + TEveSceneInfo* si = new TEveSceneInfo(this, scene, glsi); + gEve->AddElement(si, this); + } else { + throw(eH + "scene already in the viewer."); + } +} + +//______________________________________________________________________________ +void TEveViewer::RemoveElementLocal(TEveElement* el) +{ + fGLViewer->RemoveScene(((TEveSceneInfo*)el)->GetGLScene()); +} + +//______________________________________________________________________________ +void TEveViewer::RemoveElementsLocal() +{ + fGLViewer->RemoveAllScenes(); +} + +//______________________________________________________________________________ +TObject* TEveViewer::GetEditorObject() const +{ + return fGLViewer; +} + +//______________________________________________________________________________ +Bool_t TEveViewer::HandleElementPaste(TEveElement* el) +{ + static const TEveException eH("TEveViewer::HandleElementPaste "); + + TEveScene* scene = dynamic_cast(el); + if (scene != 0) { + AddScene(scene); + return kTRUE; + } else { + Warning(eH.Data(), "class TEveViewer only accepts TEveScene paste argument."); + return kFALSE; + } +} + +/******************************************************************************/ +/******************************************************************************/ +/******************************************************************************/ + +//______________________________________________________________________________ +// TEveViewerList +// +// List of Viewers providing common operations on TEveViewer collections. + +ClassImp(TEveViewerList) + +//______________________________________________________________________________ +TEveViewerList::TEveViewerList(const Text_t* n, const Text_t* t) : + TEveElementList(n, t) +{ + SetChildClass(TEveViewer::Class()); +} + +//______________________________________________________________________________ +TEveViewerList::~TEveViewerList() +{} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveViewerList::RepaintChangedViewers(Bool_t resetCameras, Bool_t dropLogicals) +{ + for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) + { + TGLViewer* glv = ((TEveViewer*)*i)->GetGLViewer(); + if (glv->IsChanged()) + { + // printf(" TEveViewer '%s' changed ... reqesting draw.\n", (*i)->GetObject()->GetName()); + + if (resetCameras) glv->PostSceneBuildSetup(kTRUE); + if (dropLogicals) glv->SetSmartRefresh(kFALSE); + + glv->RequestDraw(TGLRnrCtx::kLODHigh); + + if (dropLogicals) glv->SetSmartRefresh(kTRUE); + } + } +} + +//______________________________________________________________________________ +void TEveViewerList::RepaintAllViewers(Bool_t resetCameras, Bool_t dropLogicals) +{ + for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) + { + TGLViewer* glv = ((TEveViewer*)*i)->GetGLViewer(); + + // printf(" TEveViewer '%s' sending redraw reqest.\n", (*i)->GetObject()->GetName()); + + if (resetCameras) glv->PostSceneBuildSetup(kTRUE); + if (dropLogicals) glv->SetSmartRefresh(kFALSE); + + glv->RequestDraw(TGLRnrCtx::kLODHigh); + + if (dropLogicals) glv->SetSmartRefresh(kTRUE); + } +} + +/******************************************************************************/ + +//______________________________________________________________________________ +void TEveViewerList::SceneDestructing(TEveScene* scene) +{ + for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) + { + TEveViewer* viewer = (TEveViewer*) *i; + List_i j = viewer->BeginChildren(); + while (j != viewer->EndChildren()) + { + TEveSceneInfo* sinfo = (TEveSceneInfo*) *j; + ++j; + if (sinfo->GetScene() == scene) + gEve->RemoveElement(sinfo, viewer); + } + } +} diff --git a/fonts/eve_fontdefault.txf b/fonts/eve_fontdefault.txf new file mode 100644 index 0000000000000000000000000000000000000000..c333664759acad232f9de747c2cfcdbda716f3bd GIT binary patch literal 3220 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 c #454545", +", c #626262", +"' c #B2B2B2", +") c #545454", +"! c #3D3D3D", +"~ c #888888", +"{ c #E4E4E4", +"] c #F7F7F7", +"^ c #121212", +"/ c #616161", +"( c #858585", +"_ c #DCDCDC", +": c #000000", +"< c #5A5A5A", +"[ c #FDFDFD", +"} c #393939", +"| c #0C0C0C", +"1 c #F4F4F4", +"2 c #585858", +"3 c #737373", +"4 c #2D2D2D", +"5 c #F9F9F9", +"6 c #EDEDED", +"7 c #D9D9D9", +"8 c #FCFCFC", +"9 c #6B6B6B", +"0 c #606060", +"a c #B8B8B8", +"b c #A0A0A0", +"c c #D4D4D4", +"................", +"..............+@", +"............#$%&", +"..........#*=-;.", +"..........>,'...", +".......).!~{]...", +".......^/(_.....", +".....>:::<;.....", +".....[}|$1].....", +".....2345.......", +"...6!78-........", +"...97...........", +"..0.............", +".=a.............", +"=b..............", +"c1.............."}; diff --git a/icons/eve_viewer.xpm b/icons/eve_viewer.xpm new file mode 100644 index 0000000000..e4b4b71c36 --- /dev/null +++ b/icons/eve_viewer.xpm @@ -0,0 +1,108 @@ +/* XPM */ +static char * tes_xpm[] = { +"16 16 89 1", +" c #FFFFFF", +". c #FCFCFC", +"+ c #CCCCCC", +"@ c #A0A0A0", +"# c #8D8D8D", +"$ c #939393", +"% c #B4B4B4", +"& c #EEEEEE", +"* c #E4E4E4", +"= c #737373", +"- c #161616", +"; c #000000", +"> c #0D0D0D", +", c #2F2F2F", +"' c #202020", +") c #515151", +"! c #FEFEFE", +"~ c #949494", +"{ c #0B0B0B", +"] c #060606", +"^ c #5A5A5A", +"/ c #BBBBBB", +"( c #F9F9F9", +"_ c #D3D3D3", +": c #A2A2A2", +"< c #606060", +"[ c #070707", +"} c #6D6D6D", +"| c #E2E2E2", +"1 c #8A8A8A", +"2 c #222222", +"3 c #F1F1F1", +"4 c #636363", +"5 c #555555", +"6 c #DFDFDF", +"7 c #4C4C4C", +"8 c #363636", +"9 c #A4A4A4", +"0 c #1D1D1D", +"a c #B7B7B7", +"b c #D8D8D8", +"c c #3D3D3D", +"d c #0F0F0F", +"e c #4F4F4F", +"f c #E9E9E9", +"g c #F6F6F6", +"h c #F7F7F7", +"i c #1A1A1A", +"j c #414141", +"k c #ECECEC", +"l c #EDEDED", +"m c #2B2B2B", +"n c #282828", +"o c #808080", +"p c #646464", +"q c #C5C5C5", +"r c #0A0A0A", +"s c #565656", +"t c #333333", +"u c #525252", +"v c #EFEFEF", +"w c #959595", +"x c #4E4E4E", +"y c #DDDDDD", +"z c #464646", +"A c #CBCBCB", +"B c #585858", +"C c #BABABA", +"D c #111111", +"E c #2E2E2E", +"F c #5E5E5E", +"G c #050505", +"H c #818181", +"I c #3A3A3A", +"J c #DCDCDC", +"K c #505050", +"L c #F5F5F5", +"M c #1C1C1C", +"N c #ACACAC", +"O c #5F5F5F", +"P c #626262", +"Q c #DBDBDB", +"R c #B3B3B3", +"S c #FDFDFD", +"T c #E6E6E6", +"U c #F4F4F4", +"V c #6F6F6F", +"W c #747474", +"X c #E0E0E0", +" ", +" ", +" .+@#$%& ", +" *=-;;;>,')+", +" !~{;;]^/( _:", +" .<;;[}| 123 ", +" 4;;56 78 ", +" 9;0a bcdefg. ", +"hijk9lmno{pqrs. ", +"9tg uv;w x8yzA! ", +"BC !D&EiFGH.! ", +"I. !d=JK,oLM^! ", +"N O;PAQRS4^T ", +" UVmtWX ", +" ", +" "}; diff --git a/tutorials/eve/broken_torus.tring b/tutorials/eve/broken_torus.tring new file mode 100644 index 0000000000..1f566fd62a --- /dev/null +++ b/tutorials/eve/broken_torus.tring @@ -0,0 +1,1003 @@ +334 668 +-0.150000 0.800000 -0.198925 +-0.150000 0.700000 -0.176981 +0.050000 0.800000 -0.199935 +0.500000 -0.500000 0.171236 +0.389558 -0.496174 0.103750 +0.496174 -0.389558 0.103750 +-0.300000 0.578076 0.122188 +-0.400000 0.600000 0.179255 +-0.350000 0.700000 0.197475 +0.250000 0.800000 0.194057 +0.050000 0.700000 0.168951 +0.050000 0.800000 0.199935 +0.350000 -0.700000 0.197475 +0.150000 -0.700000 0.176981 +0.300000 -0.578076 0.122188 +-0.400000 -0.600000 0.179255 +-0.500000 -0.650000 0.193353 +-0.389558 -0.496174 0.103750 +0.600000 -0.800000 -0.000000 +0.693572 -0.693572 0.054899 +0.642832 -0.707882 -0.112606 +-0.300000 0.578076 -0.122188 +-0.389558 0.496174 -0.103750 +-0.316354 0.511607 -0.000000 +0.524276 0.807341 0.107864 +0.345670 0.903201 0.096121 +0.500000 0.860483 -0.000000 +0.300000 -0.578076 -0.122188 +0.350000 -0.700000 -0.197475 +0.400000 -0.600000 -0.179255 +0.500000 -0.700000 0.187907 +0.550000 -0.600000 0.195475 +0.050000 -0.800000 -0.199935 +-0.150000 -0.926578 -0.128324 +0.050000 -0.931936 -0.132385 +-0.700000 -0.200000 0.182725 +-0.800000 -0.250000 0.194057 +-0.700000 -0.050000 0.168951 +-0.389558 0.496174 0.103750 +-0.425343 0.425343 -0.000000 +-0.496174 0.389558 0.103750 +-0.800000 0.600000 -0.000000 +-0.693572 0.693572 0.054899 +-0.730101 0.600000 0.125212 +0.300000 -0.800000 0.190135 +0.150000 -0.800000 0.198925 +-0.300000 0.947786 -0.000000 +-0.403525 0.901347 -0.039543 +-0.300000 0.910540 -0.113155 +0.642832 0.707882 -0.112606 +0.500000 0.650000 -0.193353 +0.600000 0.550000 -0.195475 +0.578076 -0.300000 -0.122188 +0.496174 -0.389558 -0.103750 +0.600000 -0.400000 -0.179255 +0.600000 -0.400000 0.179255 +-0.524276 0.807341 -0.107864 +-0.350000 0.750000 -0.188841 +-0.316354 -0.511607 -0.000000 +-0.300000 -0.578076 0.122188 +-0.000000 -0.633333 0.100000 +-0.050000 -0.700000 0.168951 +-0.144449 -0.611414 0.100804 +-0.903201 -0.345670 0.096121 +-0.922618 -0.200000 0.125212 +0.916579 0.250000 -0.119184 +0.931936 0.050000 -0.132385 +0.975139 0.200000 -0.000000 +0.926578 -0.150000 -0.128324 +0.800000 -0.250000 -0.194057 +0.910540 -0.300000 -0.113155 +0.050000 -0.931936 0.132385 +-0.050000 -0.800000 0.199935 +-0.800000 0.150000 0.198925 +-0.931936 -0.050000 0.132385 +-0.926578 0.150000 0.128324 +0.050000 0.996730 -0.000000 +-0.150000 0.926578 -0.128324 +0.050000 0.931936 -0.132385 +-0.800000 -0.600000 -0.000000 +-0.860483 -0.500000 -0.000000 +-0.807341 -0.524276 0.107864 +0.860483 -0.500000 -0.000000 +0.807341 -0.524276 0.107864 +0.800000 -0.600000 -0.000000 +0.400000 0.800000 0.170278 +0.700000 -0.050000 -0.168951 +0.611414 -0.144449 -0.100804 +0.633333 -0.000000 -0.100000 +0.903201 -0.345670 0.096121 +0.800000 -0.400000 0.170278 +0.345670 -0.903201 0.096121 +0.200000 -0.922618 0.125212 +0.693572 0.693572 0.054899 +0.600000 0.800000 -0.000000 +-0.860483 0.500000 -0.000000 +-0.903201 0.345670 0.096121 +-0.901347 0.403525 -0.039543 +0.389558 -0.496174 -0.103750 +-0.000000 0.633333 0.100000 +-0.150000 0.700000 0.176981 +0.700000 -0.200000 -0.182725 +0.200000 0.975139 -0.000000 +0.250000 0.916579 -0.119184 +0.300000 0.947786 -0.000000 +-0.600000 -0.550000 0.195475 +-0.700000 -0.500000 0.187907 +-0.600000 -0.400000 0.179255 +0.700000 0.350000 0.197475 +0.578076 0.300000 0.122188 +0.600000 0.400000 0.179255 +-0.800000 -0.400000 0.170278 +0.650000 -0.500000 0.193353 +-0.144449 0.611414 0.100804 +-0.100000 0.598290 0.008105 +-0.200000 0.570402 -0.000000 +0.350000 0.700000 -0.197475 +0.300000 0.578076 -0.122188 +0.400000 0.600000 -0.179255 +0.144449 -0.611414 0.100804 +0.700000 0.200000 0.182725 +0.611414 0.144449 0.100804 +-0.693572 -0.693572 0.054899 +-0.730101 -0.600000 0.125212 +-0.600000 -0.730101 0.125212 +0.600000 0.400000 -0.179255 +0.578076 0.300000 -0.122188 +0.700000 0.350000 -0.197475 +0.511607 -0.316354 -0.000000 +0.578076 -0.300000 0.122188 +-0.500000 0.500000 0.171236 +0.903201 0.345670 0.096121 +0.800000 0.300000 0.190135 +0.800000 0.400000 0.170278 +0.901347 -0.403525 -0.039543 +-0.975139 -0.200000 -0.000000 +0.350000 0.700000 0.197475 +0.200000 0.700000 0.182725 +-0.700000 -0.350000 0.197475 +-0.707882 0.642832 -0.112606 +-0.511607 0.316354 -0.000000 +-0.578076 0.300000 0.122188 +-0.700000 0.050000 -0.168951 +-0.800000 -0.050000 -0.199935 +-0.700000 -0.150000 -0.176981 +-0.611414 -0.144449 -0.100804 +-0.599573 -0.081250 0.008105 +-0.633333 -0.000000 -0.100000 +0.500000 -0.700000 -0.187907 +0.524276 -0.807341 -0.107864 +-0.650000 0.500000 0.193353 +-0.800000 0.400000 0.170278 +-0.807341 0.524276 0.107864 +0.800000 0.600000 -0.000000 +0.860483 0.500000 -0.000000 +0.807341 0.524276 0.107864 +0.700000 0.050000 0.168951 +-0.496174 0.389558 -0.103750 +-0.578076 0.300000 -0.122188 +0.496174 0.389558 -0.103750 +0.050000 -0.700000 -0.168951 +0.200000 -0.700000 -0.182725 +-0.570402 0.200000 -0.000000 +-0.578076 -0.300000 0.122188 +-0.611414 -0.144449 0.100804 +0.500000 -0.500000 -0.171236 +0.550000 -0.600000 -0.195475 +-0.611414 0.144449 -0.100804 +-0.550000 0.600000 -0.195475 +-0.400000 0.600000 -0.179255 +-0.150000 0.984299 -0.000000 +-0.800000 -0.050000 0.199935 +-0.700000 0.150000 0.176981 +0.500000 -0.860483 -0.000000 +0.700000 -0.350000 0.197475 +0.800000 -0.250000 0.194057 +0.400000 0.600000 0.179255 +0.300000 0.578076 0.122188 +-0.600000 0.730101 -0.125212 +-0.600000 0.800000 -0.000000 +0.650000 -0.500000 -0.193353 +0.524276 0.807341 -0.107864 +0.496174 0.389558 0.103750 +0.730101 0.600000 -0.125212 +-0.524276 -0.807341 -0.107864 +-0.400000 -0.800000 -0.170278 +-0.403525 -0.901347 -0.039543 +0.400000 -0.600000 0.179255 +0.250000 -0.800000 -0.194057 +0.400000 -0.800000 -0.170278 +0.250000 -0.916579 -0.119184 +0.403525 -0.901347 -0.039543 +-0.807341 -0.524276 -0.107864 +-0.650000 -0.500000 -0.193353 +-0.730101 -0.600000 -0.125212 +-0.345670 -0.903201 0.096121 +-0.524276 -0.807341 0.107864 +-0.400000 -0.800000 0.170278 +-0.800000 0.300000 0.190135 +-0.600000 0.400000 0.179255 +-0.700000 0.350000 0.197475 +0.700000 0.500000 -0.187907 +0.570402 -0.200000 -0.000000 +0.599573 -0.081250 0.008105 +0.611414 -0.144449 0.100804 +0.389558 0.496174 0.103750 +0.316354 0.511607 -0.000000 +0.400000 0.800000 -0.170278 +-0.578076 -0.300000 -0.122188 +-0.600000 -0.400000 -0.179255 +-0.496174 -0.389558 -0.103750 +0.700000 0.500000 0.187907 +-0.150000 0.800000 0.198925 +-0.000000 0.633333 -0.100000 +0.081250 0.599573 0.008105 +0.144449 0.611414 -0.100804 +0.730101 -0.600000 -0.125212 +-0.500000 -0.500000 -0.171236 +-0.389558 -0.496174 -0.103750 +-0.600000 -0.800000 -0.000000 +-0.642832 -0.707882 -0.112606 +-0.633333 -0.000000 0.100000 +-0.611414 0.144449 0.100804 +-0.550000 -0.600000 -0.195475 +0.700000 -0.150000 0.176981 +0.800000 -0.050000 0.199935 +0.700000 -0.350000 -0.197475 +0.200000 0.570402 -0.000000 +-0.500000 0.500000 -0.171236 +0.500000 0.500000 -0.171236 +-0.144449 -0.611414 -0.100804 +-0.150000 -0.700000 -0.176981 +-0.000000 -0.633333 -0.100000 +-0.500000 0.700000 -0.187907 +0.807341 -0.524276 -0.107864 +0.807341 0.524276 -0.107864 +0.144449 -0.611414 -0.100804 +-0.400000 0.800000 0.170278 +-0.500000 0.700000 0.187907 +-0.524276 0.807341 0.107864 +0.730101 0.600000 0.125212 +0.600000 0.550000 0.195475 +0.524276 -0.807341 0.107864 +-0.800000 0.300000 -0.190135 +-0.800000 0.150000 -0.198925 +-0.700000 0.350000 -0.197475 +0.922618 0.200000 0.125212 +0.996730 0.050000 -0.000000 +0.931936 0.050000 0.132385 +-0.807341 0.524276 -0.107864 +-0.800000 0.400000 -0.170278 +-0.650000 0.500000 -0.193353 +-0.250000 -0.800000 0.194057 +-0.200000 -0.700000 0.182725 +-0.500000 -0.860483 -0.000000 +-0.984299 0.150000 -0.000000 +-0.926578 0.150000 -0.128324 +-0.947786 0.300000 -0.000000 +0.800000 -0.400000 -0.170278 +-0.350000 -0.700000 0.197475 +0.200000 -0.975139 -0.000000 +0.800000 0.150000 0.198925 +-0.050000 0.931936 0.132385 +-0.550000 0.600000 0.195475 +-0.600000 0.730101 0.125212 +0.400000 -0.800000 0.170278 +-0.800000 -0.400000 -0.170278 +-0.901347 -0.403525 -0.039543 +0.144449 0.611414 0.100804 +-0.700000 0.200000 -0.182725 +-0.570402 -0.200000 -0.000000 +0.150000 0.926578 0.128324 +-0.996730 -0.050000 -0.000000 +0.984299 -0.150000 -0.000000 +-0.496174 -0.389558 0.103750 +-0.425343 -0.425343 -0.000000 +-0.300000 -0.800000 -0.190135 +-0.300000 -0.910540 -0.113155 +-0.150000 -0.800000 -0.198925 +0.800000 0.150000 -0.198925 +0.316354 -0.511607 -0.000000 +-0.500000 -0.500000 0.171236 +0.600000 -0.730101 0.125212 +-0.910540 0.300000 -0.113155 +-0.600000 0.400000 -0.179255 +-0.400000 -0.600000 -0.179255 +-0.300000 -0.578076 -0.122188 +0.050000 0.700000 -0.168951 +0.081250 -0.599573 0.008105 +0.403525 0.901347 -0.039543 +0.947786 0.300000 -0.000000 +0.389558 0.496174 -0.103750 +0.250000 0.800000 -0.194057 +0.200000 0.700000 -0.182725 +0.926578 -0.150000 0.128324 +-0.947786 -0.300000 -0.000000 +-0.100000 -0.598290 0.008105 +-0.350000 -0.700000 -0.197475 +-0.144449 0.611414 -0.100804 +-0.150000 -0.926578 0.128324 +0.947786 -0.300000 -0.000000 +-0.511607 -0.316354 -0.000000 +0.425343 -0.425343 -0.000000 +0.500000 0.650000 0.193353 +0.600000 0.730101 0.125212 +-0.931936 -0.050000 -0.132385 +-0.200000 -0.570402 -0.000000 +-0.916579 -0.250000 -0.119184 +-0.598290 0.100000 0.008105 +-0.700000 -0.350000 -0.197475 +0.300000 -0.947786 -0.000000 +-0.500000 -0.700000 -0.187907 +-0.500000 0.860483 -0.000000 +-0.345670 0.903201 0.096121 +-0.200000 0.922618 0.125212 +0.598290 0.100000 0.008105 +0.700000 0.150000 -0.176981 +0.611414 0.144449 -0.100804 +0.901347 0.403525 -0.039543 +0.500000 0.500000 0.171236 +0.200000 -0.570402 -0.000000 +-0.150000 -0.984299 -0.000000 +0.800000 -0.050000 -0.199935 +0.511607 0.316354 -0.000000 +0.633333 -0.000000 0.100000 +-0.300000 -0.947786 -0.000000 +0.800000 0.400000 -0.170278 +-0.300000 0.800000 0.190135 +0.050000 -0.996730 -0.000000 +0.800000 0.300000 -0.190135 +-0.800000 -0.250000 -0.194057 +0.570402 0.200000 -0.000000 +0.425343 0.425343 -0.000000 +0.730101 -0.600000 0.125212 +1 0 2 +4 3 5 +7 6 8 +10 9 11 +13 12 14 +16 15 17 +19 18 20 +22 21 23 +25 24 26 +28 27 29 +12 30 31 +33 32 34 +36 35 37 +39 38 40 +42 41 43 +45 44 12 +47 46 48 +50 49 51 +53 52 54 +3 55 5 +56 47 57 +58 17 59 +61 60 62 +63 36 64 +66 65 67 +69 68 70 +71 45 72 +74 73 75 +77 76 78 +80 79 81 +82 83 84 +9 85 25 +86 87 88 +83 89 90 +92 91 44 +93 49 94 +96 95 97 +27 98 29 +100 99 10 +87 86 101 +103 102 104 +106 105 107 +109 108 110 +63 111 36 +3 112 55 +114 113 115 +117 116 118 +61 119 60 +121 120 108 +123 122 124 +126 125 127 +128 5 129 +130 38 7 +132 131 133 +89 82 134 +135 64 74 +137 136 9 +36 138 35 +42 139 41 +140 40 141 +143 142 144 +146 145 147 +149 148 20 +151 150 152 +114 99 113 +154 153 155 +121 156 120 +158 157 140 +159 51 125 +32 160 161 +162 140 141 +138 163 164 +29 165 166 +167 158 140 +168 57 169 +38 6 7 +52 87 101 +48 46 170 +171 37 172 +149 18 173 +174 90 175 +177 176 136 +56 178 179 +165 54 180 +50 181 49 +182 109 110 +51 49 183 +184 185 186 +12 31 187 +188 28 189 +34 188 190 +91 191 173 +190 189 191 +28 29 166 +192 193 194 +196 195 197 +122 79 194 +77 170 76 +75 73 198 +200 199 150 +125 201 127 +203 202 204 +206 205 177 +116 207 181 +121 108 109 +78 102 103 +209 208 210 +110 108 211 +152 96 151 +190 188 189 +100 11 212 +214 213 215 +14 187 4 +19 216 84 +217 210 218 +184 219 220 +37 221 222 +194 193 223 +193 209 210 +224 175 225 +180 54 226 +214 215 227 +228 169 22 +229 50 51 +231 230 232 +168 178 233 +216 234 84 +183 153 235 +160 232 236 +238 237 239 +166 165 180 +241 240 93 +54 52 226 +18 242 173 +244 243 245 +247 246 248 +181 26 94 +250 249 251 +252 61 253 +63 80 81 +195 254 186 +256 255 257 +258 70 134 +196 259 16 +251 139 168 +260 91 92 +225 248 261 +253 61 62 +212 11 262 +96 198 151 +43 263 264 +265 30 12 +224 225 156 +266 192 267 +41 152 43 +10 99 268 +244 269 142 +157 39 140 +203 87 202 +146 164 270 +11 9 271 +135 74 272 +70 68 273 +275 274 17 +129 224 204 +277 276 278 +279 65 66 +233 56 57 +236 280 27 +105 281 274 +52 202 87 +108 155 211 +228 168 169 +36 37 171 +72 45 13 +18 282 242 +283 250 243 +108 133 155 +141 40 199 +245 284 158 +261 248 246 +285 218 286 +23 6 38 +1 287 213 +74 171 73 +23 115 113 +288 60 119 +68 66 247 +207 289 181 +67 290 131 +93 153 183 +179 264 239 +39 40 140 +142 167 147 +214 268 99 +117 118 291 +293 292 116 +112 174 55 +250 251 245 +287 2 292 +225 294 248 +295 64 135 +142 269 167 +16 259 15 +296 232 230 +122 220 219 +148 166 20 +200 141 199 +185 297 276 +16 17 281 +21 298 115 +299 71 72 +300 294 89 +98 53 165 +242 282 30 +208 270 301 +194 79 192 +53 98 302 +287 215 213 +156 204 224 +97 95 249 +265 242 30 +11 271 262 +89 83 82 +303 241 304 +122 219 124 +93 240 153 +58 59 62 +1 2 287 +305 256 244 +296 230 306 +252 253 259 +307 135 272 +112 83 90 +308 146 147 +193 309 209 +85 24 25 +191 310 190 +21 115 23 +184 311 297 +313 312 239 +46 313 314 +55 174 129 +291 50 229 +313 47 312 +291 118 50 +187 31 3 +168 233 57 +227 177 268 +114 298 213 +308 222 221 +315 88 203 +181 94 49 +144 142 147 +316 88 317 +215 293 116 +308 162 222 +31 112 3 +25 289 104 +292 103 289 +318 235 154 +319 241 303 +275 301 274 +234 258 134 +223 218 285 +90 89 175 +267 192 80 +259 253 62 +86 316 279 +320 119 14 +152 150 43 +302 4 5 +91 173 242 +277 33 321 +261 246 131 +86 279 322 +30 282 31 +277 278 33 +64 171 74 +25 26 289 +317 323 126 +283 97 250 +301 270 164 +197 195 252 +156 324 204 +305 272 255 +277 321 325 +10 137 9 +182 110 241 +280 14 4 +180 226 258 +212 262 314 +299 72 252 +65 290 67 +46 314 170 +120 261 132 +102 271 25 +226 69 258 +326 235 318 +58 275 17 +42 178 139 +73 200 198 +273 248 294 +259 62 59 +327 212 314 +118 116 50 +267 295 307 +288 320 236 +175 89 294 +189 149 191 +315 324 121 +89 134 300 +116 292 207 +328 260 92 +33 34 328 +251 168 228 +165 53 54 +159 125 126 +219 254 196 +316 127 329 +272 74 75 +256 283 243 +139 249 41 +150 130 263 +266 330 309 +42 179 178 +302 5 128 +309 144 145 +255 75 96 +143 244 142 +157 228 22 +316 329 279 +315 121 331 +111 138 36 +131 318 154 +206 332 205 +186 277 325 +315 317 88 +102 25 104 +131 154 155 +19 282 18 +161 236 27 +146 221 164 +315 203 324 +159 323 332 +32 161 188 +307 305 143 +317 126 127 +105 16 281 +198 200 151 +185 277 186 +329 326 318 +252 72 61 +42 264 179 +296 288 232 +43 264 42 +76 271 102 +166 180 216 +320 14 280 +307 330 266 +307 295 135 +214 227 268 +192 309 193 +91 310 191 +332 182 205 +92 44 45 +0 77 78 +317 127 316 +136 303 24 +162 141 222 +278 160 32 +29 98 165 +128 129 204 +114 213 214 +127 201 235 +6 113 100 +175 294 225 +93 94 304 +105 274 107 +215 117 206 +327 314 313 +263 238 264 +96 97 257 +84 83 333 +100 113 99 +309 208 209 +138 107 163 +73 172 200 +72 13 61 +321 328 71 +291 206 117 +199 130 150 +108 132 133 +56 179 312 +203 88 87 +249 139 251 +153 240 155 +205 319 303 +136 85 9 +61 13 119 +195 196 254 +177 205 176 +93 183 49 +305 255 256 +114 214 99 +144 147 145 +309 145 208 +296 60 288 +308 221 146 +160 236 161 +96 152 95 +52 101 226 +311 223 285 +280 4 302 +21 57 1 +97 283 257 +70 273 300 +156 225 261 +133 131 155 +288 236 232 +322 66 68 +223 217 218 +67 131 246 +35 164 37 +15 59 17 +269 245 158 +151 200 150 +289 103 104 +316 86 88 +237 327 313 +218 275 58 +247 67 246 +288 119 320 +126 323 159 +106 107 138 +269 158 167 +205 182 319 +174 175 224 +8 327 237 +52 53 128 +0 78 2 +333 83 112 +180 258 234 +264 238 239 +203 204 324 +157 22 39 +305 244 143 +81 123 106 +52 128 202 +51 183 201 +44 265 12 +20 166 216 +263 8 238 +159 229 51 +286 306 230 +313 46 47 +122 194 220 +107 274 163 +234 82 84 +22 23 39 +68 247 273 +284 251 228 +241 211 240 +210 275 218 +8 212 327 +98 27 280 +114 115 298 +295 63 64 +185 276 277 +47 56 312 +331 109 323 +19 84 333 +332 323 182 +287 293 215 +57 77 0 +297 286 230 +256 243 244 +100 10 11 +261 131 132 +79 123 81 +239 237 313 +125 51 201 +258 69 70 +276 231 278 +124 16 105 +19 20 216 +249 95 41 +171 172 73 +286 58 306 +34 260 328 +57 47 48 +91 265 44 +6 100 8 +75 198 96 +9 25 271 +301 164 163 +98 280 302 +194 223 220 +58 62 306 +76 262 271 +256 257 283 +201 183 235 +328 92 71 +172 222 141 +81 106 138 +317 331 323 +329 318 65 +110 211 241 +170 262 76 +111 63 81 +249 250 97 +8 100 212 +66 67 247 +284 228 157 +136 24 85 +23 113 6 +127 235 326 +134 70 300 +63 267 80 +170 314 262 +122 123 79 +48 170 77 +273 247 248 +184 297 185 +215 206 227 +291 229 159 +219 196 124 +235 153 154 +241 93 304 +321 71 299 +268 177 136 +120 132 108 +205 303 176 +265 91 242 +57 48 77 +81 138 111 +296 306 62 +112 90 174 +315 331 317 +45 12 13 +220 311 184 +167 140 162 +218 58 286 +130 7 263 +169 57 21 +331 121 109 +199 40 130 +131 290 318 +297 230 231 +297 285 286 +259 59 15 +311 285 297 +227 206 177 +291 332 206 +57 0 1 +245 251 284 +13 14 119 +323 109 182 +178 56 233 +23 38 39 +33 278 32 +10 268 137 +78 76 102 +281 17 274 +189 28 148 +95 152 41 +156 121 324 +325 321 299 +268 136 137 +287 292 293 +307 143 330 +197 252 259 +226 101 69 +260 310 91 +308 167 162 +53 302 128 +101 322 69 +325 299 195 +127 326 329 +276 297 231 +40 38 130 +192 79 80 +231 232 160 +176 303 136 +216 180 234 +279 329 65 +94 26 24 +223 193 217 +236 320 280 +123 124 105 +292 289 207 +134 82 234 +158 284 157 +318 290 65 +263 7 8 +37 222 172 +156 261 120 +211 155 240 +12 187 14 +282 19 333 +188 161 28 +69 322 68 +322 279 66 +71 92 45 +101 86 322 +187 3 4 +172 141 200 +123 105 106 +208 145 270 +182 241 319 +186 254 184 +308 147 167 +330 144 309 +184 254 219 +146 270 145 +37 164 221 +33 328 321 +193 210 217 +2 103 292 +31 333 112 +255 96 257 +195 299 252 +238 8 237 +150 263 43 +129 174 224 +138 164 35 +34 32 188 +116 181 50 +307 272 305 +124 196 16 +190 310 260 +208 301 210 +139 178 168 +192 266 309 +330 143 144 +307 266 267 +94 24 304 +196 197 259 +195 186 325 +300 273 294 +282 333 31 +34 190 260 +28 166 148 +191 149 173 +243 250 245 +1 213 298 +2 78 103 +189 148 149 +149 20 18 +296 62 60 +179 239 312 +63 295 267 +22 169 21 +159 332 291 +303 304 24 +215 116 117 +289 26 181 +161 27 28 +244 245 269 +5 55 129 +128 204 202 +278 231 160 +64 36 171 +210 301 275 +301 163 274 +21 1 298 +272 75 255 +220 223 311 diff --git a/tutorials/eve/lineset_test.C b/tutorials/eve/lineset_test.C new file mode 100644 index 0000000000..e600665ff2 --- /dev/null +++ b/tutorials/eve/lineset_test.C @@ -0,0 +1,26 @@ +// @(#)root/reve:$Id$ +// Author: Matevz Tadel + +TEveStraightLineSet* lineset_test(Int_t nlines = 40, Int_t nmarkers = 4) +{ + TEveStraightLineSet* ls = new TEveStraightLineSet(); + + TRandom r(0); + Float_t s = 100; + + for(Int_t i = 0; iAddLine( r.Uniform(-s,s), r.Uniform(-s,s), r.Uniform(-s,s), + r.Uniform(-s,s), r.Uniform(-s,s), r.Uniform(-s,s)); + // add random number of markers + Int_t nm = Int_t(nmarkers* r.Rndm()); + for(Int_t m = 0; m < nm; m++) { + ls->AddMarker(i, r.Rndm()); + } + } + + gEve->AddElement(ls); + gEve->Redraw3D(); + + return ls; +} diff --git a/tutorials/eve/nasashuttle.3ds b/tutorials/eve/nasashuttle.3ds new file mode 100644 index 0000000000000000000000000000000000000000..5f712bae4d26e9db81a0132daf5e30d10786cfa6 GIT binary patch literal 219441 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

SS}WJ2{-3PA(_6lgG*H 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, 0); + + TEveRGBAPalette* pal = new TEveRGBAPalette(0, 130); + + TEveQuadSet* q = new TEveQuadSet("RectangleXY"); + q->SetPalette(pal); + q->Reset(TEveQuadSet::QT_RectangleXY, kFALSE, 32); + for (Int_t i=0; iAddQuad(r.Uniform(-10, 10), r.Uniform(-10, 10), r.Uniform(-10, 10), + r.Uniform(0.2, 1), r.Uniform(0.2, 1)); + q->QuadValue(r.Uniform(0, 130)); + } + q->RefitPlex(); + + TEveTrans& t = q->RefHMTrans(); + t.SetPos(x, y, z); + + if (register) + { + gEve->AddElement(q); + gEve->Redraw3D(kTRUE); + } + + return q; +} + +TEveQuadSet* reve_quad_test_emc(Float_t x=0, Float_t y=0, Float_t z=0, + Int_t num=100) +{ + TRandom r(0); + + gStyle->SetPalette(1, 0); + + TEveQuadSet* q = new TEveQuadSet("EMC Supermodule"); + q->SetOwnIds(kTRUE); + q->Reset(TEveQuadSet::QT_RectangleXZFixedDimY, kFALSE, 32); + q->SetDefWidth(8); + q->SetDefHeight(8); + + for (Int_t i=0; iAddQuad(r.Uniform(-100, 100), r.Uniform(-100, 100)); + q->QuadValue(r.Uniform(0, 130)); + q->AddId(new TNamed(Form("Cell %d", i))); + } + q->RefitPlex(); + + TEveTrans& t = q->RefHMTrans(); + t.SetPos(x, y, z); + + gEve->AddElement(q); + gEve->Redraw3D(); + + return q; +} + +TEveQuadSet* reve_quad_test_circ() +{ + TRandom r(0); + + gStyle->SetPalette(1, 0); + + TEveQuadSet* q = new TEveQuadSet("Pepe"); + q->Reset(TEveQuadSet::QT_RectangleXY, kFALSE, 32); + + Float_t R = 10, dW = 1, dH = .5; + for (Int_t i=0; i<12; ++i) { + Float_t x = R * TMath::Cos(TMath::TwoPi()*i/12); + Float_t y = R * TMath::Sin(TMath::TwoPi()*i/12); + q->AddQuad(x-dW, y-dH, r.Uniform(-1, 1), 2*dW, 2*dH); + q->QuadValue(r.Uniform(0, 130)); + } + q->RefitPlex(); + + TEveTrans& t = q->RefHMTrans(); + t.SetPos(0, 0, 300); + + gEve->AddElement(q); + gEve->Redraw3D(); + + return q; +} + +TEveQuadSet* reve_quad_test_hex(Float_t x=0, Float_t y=0, Float_t z=0, + Int_t num=100, Bool_t register=kTRUE) +{ + TRandom r(0); + + gStyle->SetPalette(1, 0); + + { + TEveQuadSet* q = new TEveQuadSet("HexagonXY"); + q->Reset(TEveQuadSet::QT_HexagonXY, kFALSE, 32); + for (Int_t i=0; iAddHexagon(r.Uniform(-10, 10), r.Uniform(-10, 10), r.Uniform(-10, 10), + r.Uniform(0.2, 1)); + q->QuadValue(r.Uniform(0, 120)); + } + q->RefitPlex(); + + TEveTrans& t = q->RefHMTrans(); + t.SetPos(x, y, z); + + if (register) + { + gEve->AddElement(q); + gEve->Redraw3D(); + } + } + + { + TEveQuadSet* q = new TEveQuadSet("HexagonYX"); + q->Reset(TEveQuadSet::QT_HexagonYX, kFALSE, 32); + for (Int_t i=0; iAddHexagon(r.Uniform(-10, 10), r.Uniform(-10, 10), r.Uniform(-10, 10), + r.Uniform(0.2, 1)); + q->QuadValue(r.Uniform(0, 120)); + } + q->RefitPlex(); + + TEveTrans& t = q->RefHMTrans(); + t.SetPos(x, y, z); + + if (register) + { + gEve->AddElement(q); + gEve->Redraw3D(); + } + } + + return q; +} + +TEveQuadSet* reve_quad_test_hexid(Float_t x=0, Float_t y=0, Float_t z=0, + Int_t num=100, Bool_t register=kTRUE) +{ + TRandom r(0); + + gStyle->SetPalette(1, 0); + + { + TEveQuadSet* q = new TEveQuadSet("HexagonXY"); + q->SetOwnIds(kTRUE); + q->Reset(TEveQuadSet::QT_HexagonXY, kFALSE, 32); + for (Int_t i=0; iAddHexagon(r.Uniform(-10, 10), r.Uniform(-10, 10), r.Uniform(-10, 10), + r.Uniform(0.2, 1)); + q->QuadValue(r.Uniform(0, 120)); + q->QuadId(new TNamed(Form("Quad with idx=%d", i), "This title is not confusing.")); + } + q->RefitPlex(); + + TEveTrans& t = q->RefHMTrans(); + t.SetPos(x, y, z); + + if (register) + { + gEve->AddElement(q); + gEve->Redraw3D(); + } + } + + return q; +} + +void reve_quad_test_hierarchy(Int_t n=4) +{ + gStyle->SetPalette(1, 0); + + TEveRGBAPalette* pal = new TEveRGBAPalette(20, 100); + pal->SetLimits(0, 120); + + TEveFrameBox* box = new TEveFrameBox(); + box->SetAABox(-10, -10, -10, 20, 20, 20); + box->SetFrameColor((Color_t) 33); + + TEveElementList* l = new TEveElementList("Parent/Dir"); + l->SetTitle("Tooltip"); + // l->SetMainColor((Color_t)3); + gEve->AddElement(l); + + for (Int_t i=0; iSetPalette(pal); + qs->SetFrame(box); + gEve->AddElement(qs, l); + } + + gEve->Redraw3D(); +} diff --git a/tutorials/eve/triangleset.C b/tutorials/eve/triangleset.C new file mode 100644 index 0000000000..40a73ff7fd --- /dev/null +++ b/tutorials/eve/triangleset.C @@ -0,0 +1,56 @@ +// @(#)root/reve:$Id$ +// Author: Bertrand Bellenot + +#include "TCanvas.h" +#include "TStyle.h" +#include "TFile.h" +#include "TStopwatch.h" +#include "TError.h" + +class TEveTriangleSet; + +TEveTriangleSet *ts1=0, *ts2=0, *ts3=0; + +void triangleset() +{ + { + ts1 = TEveTriangleSet::ReadTrivialFile("broken_torus.tring"); + ts1->SetName("RandomColors"); + ts1->GenerateTriangleNormals(); + ts1->GenerateRandomColors(); + ts1->SetColor(0); + TGeoHMatrix m; + Double_t scale[3] = { 0.5, 0.5, 0.5 }; + m.SetScale(scale); + ts1->SetTransMatrix(m); + gEve->AddElement(ts1); + } + { + ts2 = TEveTriangleSet::ReadTrivialFile("broken_torus.tring"); + ts2->SetName("SmallBlue"); + ts2->GenerateTriangleNormals(); + ts2->SetColor(4); + TGeoHMatrix m; + m.RotateY(90); + Double_t scale[3] = { 0.8, 0.8, 1.2 }; + m.SetScale(scale); + ts2->SetTransMatrix(m); + gEve->AddElement(ts2); + } + { + ts3 = TEveTriangleSet::ReadTrivialFile("broken_torus.tring"); + ts3->SetName("Spectrum"); + ts3->GenerateTriangleNormals(); + gStyle->SetPalette(1, 0); + ts3->GenerateZNormalColors(50, -50, 50, kTRUE, kTRUE); + ts3->SetColor(0); + TGeoHMatrix m; + m.RotateZ(90); + Double_t scale[3] = { 1.3, 1.0, 1.6 }; + m.SetScale(scale); + ts3->SetTransMatrix(m); + gEve->AddElement(ts3); + } + + gEve->Redraw3D(kTRUE); +} diff --git a/tutorials/eve/view3ds.C b/tutorials/eve/view3ds.C new file mode 100644 index 0000000000..abb7e6890d --- /dev/null +++ b/tutorials/eve/view3ds.C @@ -0,0 +1,583 @@ +// @(#)root/reve:$Id$ +// Author: Matevz Tadel + +#include "TCanvas.h" +#include "TStyle.h" +#include "TFile.h" +#include "TStopwatch.h" +#include "TError.h" + +#include +#include +#include +#include + +class TEveTriangleSet; + +TEveTriangleSet *ts[2048]; + +// Believe3D Model file defines +#define MAGICNUMBER 0xB3D0 + +// types of 3DS Chunks +#define CHUNKMAIN 0x4D4D +#define CHUNKMAINVERSION 0x0002 +#define CHUNK3D 0x3D3D +#define CHUNK3DVERSION 0x3D3E +#define CHUNK3DOBJECT 0x4000 +#define CHUNK3DOBJECTMESH 0x4100 +#define CHUNK3DOBJECTMESHVERTICES 0x4110 +#define CHUNK3DOBJECTMESHFACES 0x4120 +#define CHUNK3DOBJECTMESHMATGROUP 0x4130 +#define CHUNK3DOBJECTMESHMAPPING 0x4140 + +#define CHUNK3DMATERIAL 0xAFFF +// Sub defines of MATERIAL +#define MATNAME 0xA000 +#define MATDIFFUSE 0xA020 +#define MATSPECULAR 0xA030 +#define MATTRANSPARENCY 0xA050 + +#define COLOR_F 0x0010 +#define COLOR_24 0x0011 +#define LIN_COLOR_24 0x0012 +#define LIN_COLOR_F 0x0013 +#define INT_PERCENTAGE 0x0030 +#define FLOAT_PERCENTAGE 0x0031 + +////////////////////////////////////// +//The tMaterialInfo Struct +////////////////////////////////////// +class Material { +public: + char name[256]; + UChar_t color[3]; + UShort_t transparency; + + Material() { + sprintf(name, ""); + color[0] = color[1] = color[2] = 0; + transparency = 0; + } + ~Material() { } +}; + + +// Chunk structure +typedef struct _Chunk { + UShort_t idnum; + ULong_t offset, len, endoffset; +} Chunk; + +// vertex structure +typedef struct _Vertex { + Float_t x, y, z; + Float_t u, v; +} Vertex; + +// face structure +typedef struct _Face { + ULong_t v1, v2, v3; +} Face; + +// model structure +class Model { +public: + char name[256]; + char matname[256]; + Vertex *vlist; + Face *flist; + ULong_t numverts, numfaces; + + Model() { + sprintf(name,""); + sprintf(matname,""); + vlist = 0; + flist = 0; + numverts = numfaces = 0; + } + ~Model() { + if (vlist != 0) delete [] vlist; + if (flist != 0) delete [] flist; + } +}; + +// chunk reading routines +Int_t ReadChunk(FILE*, Chunk*); + +// data reading routines +Int_t ReadMainChunk(FILE*); +Int_t Read3DChunk(FILE*, ULong_t); +Int_t ReadObjectChunk(FILE*, ULong_t); +Int_t ReadMeshChunk(FILE*, ULong_t, char*); +Int_t ReadVerticesChunk(FILE*); +Int_t ReadFacesChunk(FILE*); +Int_t ReadMappingChunk(FILE*); +Int_t ReadASCIIZ(FILE*, char*); +Int_t ReadMaterialChunk(FILE *, ULong_t); +Int_t ReadColor(FILE *, ULong_t); +Int_t ReadTransparency(FILE *, ULong_t); +Int_t ReadObjectMaterial(FILE *); +Int_t ConvertModel(); + +// global variables +Int_t nummodels = 0; +Model model = {"","",0,0,0,0}; + +Int_t nummaterials = 0; +Material *material[1024]; + +//______________________________________________________________________________ +Int_t Read3DSFile(const char *fname) +{ + // main function + + FILE *infile; + + infile = fopen(fname, "rb"); + if (infile == 0) { + printf("Error : Input File Could Not Be Opened!\n"); + return -1; + } + UShort_t magic = MAGICNUMBER; + if (ReadMainChunk(infile) != 0) { + printf("Error : Input File Could Not Be Read!\n"); + } + fclose(infile); + return 0; +} + +//______________________________________________________________________________ +Int_t ReadChunk(FILE *f, Chunk *c) +{ + // reads a chunk from an opened file + + if (feof(f)) return(-1); + c->idnum = 0; + c->offset = c->len = 0; + c->offset = (ULong_t) ftell(f); + fread(&c->idnum, sizeof(UShort_t), 1, f); + fread(&c->len, sizeof(ULong_t), 1, f); + c->endoffset = c->offset + c->len; + return(0); +} + +//______________________________________________________________________________ +Int_t ReadMainChunk(FILE *f) +{ + // handles the main body of the 3DS file + + Chunk chunk; + + ReadChunk(f, &chunk); + if (chunk.idnum != CHUNKMAIN) return(-1); + while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) { + if (chunk.idnum == CHUNK3D) { + Read3DChunk(f, chunk.endoffset); + } + else { + //printf("Debug : Unknown Chunk [Main Chunk] [0x%x]\n", chunk.idnum); + fseek(f, chunk.offset + chunk.len, SEEK_SET); + } + } + return 0; +} + +//______________________________________________________________________________ +Int_t Read3DChunk(FILE *f, ULong_t len) +{ + // reads the 3D Edit Chunk + + Chunk chunk; + + while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) { + if (chunk.idnum == CHUNK3DOBJECT) { + ReadObjectChunk(f, chunk.endoffset); + fseek(f, chunk.endoffset, SEEK_SET); + } + else if (chunk.idnum == CHUNK3DMATERIAL) { + ReadMaterialChunk(f, chunk.endoffset); + fseek(f, chunk.endoffset, SEEK_SET); + } + else { + if (chunk.endoffset < len) { + //printf("Debug : Unknown Chunk [3D Chunk] [0x%x]\n", chunk.idnum); + fseek(f, chunk.endoffset, SEEK_SET); + } + else { + break; + } + } + } + return 0; +} + +//______________________________________________________________________________ +Int_t ReadMaterialChunk(FILE *f, ULong_t len) +{ + // reads the Material sub-chunk of the 3D Edit Chunk + + Chunk chunk; + char name[256]; + char rgb[3]; + material[nummaterials] = new Material(); + while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) { + if (chunk.idnum == MATNAME) { + ReadASCIIZ(f, name); + strcpy(material[nummaterials]->name, name); + fseek(f, chunk.endoffset, SEEK_SET); + } + else if (chunk.idnum == MATDIFFUSE) { + ReadColor(f, chunk.endoffset); + fseek(f, chunk.endoffset, SEEK_SET); + } + else if (chunk.idnum == MATTRANSPARENCY) { + ReadTransparency(f, chunk.endoffset); + fseek(f, chunk.endoffset, SEEK_SET); + } + else { + if (chunk.endoffset < len) { + //printf("Debug : Unknown Chunk [Object Chunk] [0x%x]\n", chunk.idnum); + fseek(f, chunk.endoffset, SEEK_SET); + } + else { + break; + } + } + } + nummaterials++; + return 0; +} + +//______________________________________________________________________________ +Int_t ReadColor(FILE *f, ULong_t len) +{ + // reads the Color property of the Material Chunk + + Chunk chunk; + float fr, fg, fb; + int irgb[3]; + while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) { + if (chunk.idnum == LIN_COLOR_24) { + fread(&material[nummaterials]->color[0], sizeof(UChar_t), 1, f); + fread(&material[nummaterials]->color[1], sizeof(UChar_t), 1, f); + fread(&material[nummaterials]->color[2], sizeof(UChar_t), 1, f); + fseek(f, chunk.endoffset, SEEK_SET); + } + else if (chunk.idnum == COLOR_24) { + fread(&material[nummaterials]->color[0], sizeof(UChar_t), 1, f); + fread(&material[nummaterials]->color[1], sizeof(UChar_t), 1, f); + fread(&material[nummaterials]->color[2], sizeof(UChar_t), 1, f); + fseek(f, chunk.endoffset, SEEK_SET); + } + else if (chunk.idnum == LIN_COLOR_F) { + fread(&fr, sizeof(Float_t), 1, f); + fread(&fg, sizeof(Float_t), 1, f); + fread(&fb, sizeof(Float_t), 1, f); + fseek(f, chunk.endoffset, SEEK_SET); + } + else if (chunk.idnum == COLOR_F) { + fread(&fr, sizeof(Float_t), 1, f); + fread(&fg, sizeof(Float_t), 1, f); + fread(&fb, sizeof(Float_t), 1, f); + fseek(f, chunk.endoffset, SEEK_SET); + } + else { + if (chunk.endoffset < len) { + //printf("Debug : Unknown Chunk [Mesh Chunk] [0x%x]\n", chunk.idnum); + fseek(f, chunk.endoffset, SEEK_SET); + } + else { + break; + } + } + } + return 0; +} + +//______________________________________________________________________________ +Int_t ReadTransparency(FILE *f, ULong_t len) +{ + // reads the Transparency property of the Material Chunk + + Chunk chunk; + char byte[2]; + float ftransp; + UShort_t stransp; + while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) { + if (chunk.idnum == INT_PERCENTAGE) { + fread(&stransp, sizeof(UShort_t), 1, f); + material[nummaterials]->transparency = stransp; + fseek(f, chunk.endoffset, SEEK_SET); + } + else if (chunk.idnum == FLOAT_PERCENTAGE) { + fread(&ftransp, sizeof(float), 1, f); + fseek(f, chunk.endoffset, SEEK_SET); + } + else { + if (chunk.endoffset < len) { + //printf("Debug : Unknown Chunk [Mesh Chunk] [0x%x]\n", chunk.idnum); + fseek(f, chunk.endoffset, SEEK_SET); + } + else { + break; + } + } + } + return 0; +} + +//______________________________________________________________________________ +Int_t ReadObjectMaterial(FILE *f) +{ + // reads the name of material associated to the current Chunk + + ReadASCIIZ(f, model.matname); + return 0; +} + +//______________________________________________________________________________ +Int_t ReadObjectChunk(FILE *f, ULong_t len) +{ + // reads the Object sub-chunk of the 3D Edit Chunk + + Chunk chunk; + char name[256]; + ReadASCIIZ(f, name); + while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) { + if (chunk.idnum == CHUNK3DOBJECTMESH) { + ReadMeshChunk(f, chunk.endoffset, name); + } + else { + if (chunk.endoffset < len) { + //printf("Debug : Unknown Chunk [Object Chunk] [0x%x]\n", chunk.idnum); + fseek(f, chunk.endoffset, SEEK_SET); + } + else { + break; + } + } + } + return 0; +} + +//______________________________________________________________________________ +Int_t ReadMeshChunk(FILE *f, ULong_t len, char *objname) +{ + // reads the TriMesh sub-chunk of the Object Chunk + + Int_t i; + Chunk chunk; + model.vlist = 0; + model.flist = 0; + model.numverts = model.numfaces = 0; + sprintf(model.name, "%s", objname); + printf("Reading Mesh : %s\n", objname); + while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) { + if (chunk.idnum == CHUNK3DOBJECTMESHVERTICES) { + ReadVerticesChunk(f); + } + else if (chunk.idnum == CHUNK3DOBJECTMESHFACES) { + ReadFacesChunk(f); + } + else if (chunk.idnum == CHUNK3DOBJECTMESHMAPPING) { + ReadMappingChunk(f); + } + else if (chunk.idnum == CHUNK3DOBJECTMESHMATGROUP) { + ReadObjectMaterial(f); + } + else { + if (chunk.endoffset < len) { + //printf("Debug : Unknown Chunk [Mesh Chunk] [0x%x]\n", chunk.idnum); + fseek(f, chunk.endoffset, SEEK_SET); + } + else { + break; + } + } + } + if (model.numverts != 0 && model.numfaces != 0 && + model.vlist != 0 && model.flist != 0) { + ConvertModel(); + } + if (model.vlist != 0) delete [] model.vlist; + if (model.flist != 0) delete [] model.flist; + model.vlist = 0; + model.flist = 0; + model.numverts = model.numfaces = 0; + sprintf(model.name,""); + nummodels++; + return 0; +} + +//______________________________________________________________________________ +Int_t ReadVerticesChunk(FILE *f) +{ + // reads Vertex data of the TriMesh Chunk + + Int_t i; + UShort_t numv = 0; + Float_t x, y, z; + + fread(&numv, sizeof(UShort_t), 1, f); + printf("Reading %i Vertices...", numv); + model.vlist = new Vertex[numv]; + if (model.vlist == 0) { + for (i = 0; i < numv; i++) { + fread(&x, sizeof(Float_t), 1, f); + fread(&y, sizeof(Float_t), 1, f); + fread(&z, sizeof(Float_t), 1, f); + } + printf("\nWarning : Insufficient Memory to Load Vertices!\n"); + return -1; + } + for (i = 0; i < numv; i++) { + fread(&model.vlist[i].x, sizeof(Float_t), 1, f); + fread(&model.vlist[i].y, sizeof(Float_t), 1, f); + fread(&model.vlist[i].z, sizeof(Float_t), 1, f); + } + model.numverts = (ULong_t) numv; + printf("Done!\n"); + return 0; +} + +//______________________________________________________________________________ +Int_t ReadFacesChunk(FILE *f) +{ + // reads Face data of the TriMesh Chunk + + Int_t i; + UShort_t numf = 0, v1, v2, v3, attr; + + fread(&numf, sizeof(UShort_t), 1, f); + printf("Reading %i Faces...", numf); + model.flist = new Face[numf]; + if (model.flist == 0) { + for (i = 0; i < numf; i++) { + fread(&v1, sizeof(UShort_t), 1, f); + fread(&v2, sizeof(UShort_t), 1, f); + fread(&v3, sizeof(UShort_t), 1, f); + fread(&attr, sizeof(UShort_t), 1, f); + } + printf("\nWarning : Insufficient Memory to Load Faces!\n"); + return -1; + } + for (i = 0; i < numf; i++) { + fread(&v1, sizeof(UShort_t), 1, f); + fread(&v2, sizeof(UShort_t), 1, f); + fread(&v3, sizeof(UShort_t), 1, f); + fread(&attr, sizeof(UShort_t), 1, f); + model.flist[i].v1 = (ULong_t)(v1); + model.flist[i].v2 = (ULong_t)(v2); + model.flist[i].v3 = (ULong_t)(v3); + } + model.numfaces = (ULong_t)(numf); + printf("Done!\n"); + return 0; +} + +//______________________________________________________________________________ +Int_t ReadMappingChunk(FILE *f) +{ + // reads Texture Mapping data of the TriMesh Chunk + + UShort_t numuv = 0, i; + Float_t u, v; + + fread(&numuv, sizeof(UShort_t), 1, f); + printf("Reading %i Texture Coordinates...", numuv); + if (numuv != model.numverts) { + for (i = 0; i < numuv; i++) { + fread(&u, sizeof(Float_t), 1, f); + fread(&v, sizeof(Float_t), 1, f); + } + printf("\nWarning : Number of Vertices and Mapping Data do not match!\n"); + return -1; + } + for (i = 0; i < numuv; i++) { + fread(&model.vlist[i].u, sizeof(Float_t), 1, f); + fread(&model.vlist[i].v, sizeof(Float_t), 1, f); + } + printf("Done!\n"); + return 0; +} + +//______________________________________________________________________________ +Int_t ReadASCIIZ(FILE *f, char *name) +{ + // reads a null-terminated string from the given file + + char c = -1; + Int_t index = 0; + + do { + fread(&c, sizeof(char), 1, f); + name[index] = c; + index++; + if (index == 255) { + name[index] = 0; + c = 0; + } + } while ((c != 0) && (!feof(f))); + return 0; +} + +//______________________________________________________________________________ +Int_t ConvertModel() +{ + // Convert from Model structure to TEveTriangleSet + + Int_t i; + + ts[nummodels] = new TEveTriangleSet(model.numverts, model.numfaces); + if (ts[nummodels] == 0) + return -1; + for (i=0; iSetVertex(i, model.vlist[i].x, model.vlist[i].y, + model.vlist[i].z); + } + for (i=0; iSetTriangle(i, model.flist[i].v1, model.flist[i].v2, + model.flist[i].v3); + } + ts[nummodels]->SetName(model.name); + ts[nummodels]->SetTransparency(0); + ts[nummodels]->SetColor(0); + for (i = 0; i < nummaterials; i++) { + if (strcmp(model.matname, material[i]->name) == 0) { + ts[nummodels]->SetTransparency(material[i]->transparency); + ts[nummodels]->SetColor(Color_t(TColor::GetColor(material[i]->color[0], + material[i]->color[1], material[i]->color[2]))); + break; + } + } + return 0; +} + +//______________________________________________________________________________ +void view3ds(const char *fname = "nasashuttle.3ds") +{ + // main... + + Int_t i; + for (i=0;i<2048;i++) ts[i] = 0; + for (i=0;i<1024;i++) material[i] = 0; + model.vlist = 0; + model.flist = 0; + nummodels = 0; + if (Read3DSFile(fname) == 0) { + TEveTriangleSet* parent = new TEveTriangleSet(0, 0); + parent->SetName(fname); + gEve->AddElement(parent); + for (i=0;iGenerateTriangleNormals(); + ts[i]->RefHMTrans().RotateLF(1, 2, TMath::Pi()); + gEve->AddElement(ts[i], parent); + } + } + gEve->Redraw3D(kTRUE); + } + for (i = 0; i < nummaterials; i++) + if (material[i] != 0) delete material[i]; +}