// @(#)root/gl:$Name: $:$Id: TGLClip.cxx,v 1.7 2006/02/20 11:02:19 brun Exp $
// Author: Richard Maunder 16/09/2005
/*************************************************************************
* Copyright (C) 1995-2005, 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 "TGLClip.h"
#include "TGLIncludes.h"
#include "TGLFaceSet.h"
#include "TBuffer3D.h"
#include "TBuffer3DTypes.h"
TGLLogicalShape * CreateLogicalBox(TGLVector3 halfLengths)
{
// Helper function to construct a TGLLogicalShape box based on
// supplied half lengths
// y
// |
// |
// |________x
// / 3-------2
// / /| /|
// z 7-------6 |
// | 0-----|-1
// |/ |/
// 4-------5
//
// Construct box of points / segments / polys
TBuffer3D buff(TBuffer3DTypes::kGeneric, 8, 3*8, 12, 3*12, 6, 6*6);
buff.fPnts[ 0] = -halfLengths.X(); buff.fPnts[ 1] = -halfLengths.Y(); buff.fPnts[ 2] = -halfLengths.Z(); // 0
buff.fPnts[ 3] = halfLengths.X(); buff.fPnts[ 4] = -halfLengths.Y(); buff.fPnts[ 5] = -halfLengths.Z(); // 1
buff.fPnts[ 6] = halfLengths.X(); buff.fPnts[ 7] = halfLengths.Y(); buff.fPnts[ 8] = -halfLengths.Z(); // 2
buff.fPnts[ 9] = -halfLengths.X(); buff.fPnts[10] = halfLengths.Y(); buff.fPnts[11] = -halfLengths.Z(); // 3
buff.fPnts[12] = -halfLengths.X(); buff.fPnts[13] = -halfLengths.Y(); buff.fPnts[14] = halfLengths.Z(); // 4
buff.fPnts[15] = halfLengths.X(); buff.fPnts[16] = -halfLengths.Y(); buff.fPnts[17] = halfLengths.Z(); // 5
buff.fPnts[18] = halfLengths.X(); buff.fPnts[19] = halfLengths.Y(); buff.fPnts[20] = halfLengths.Z(); // 6
buff.fPnts[21] = -halfLengths.X(); buff.fPnts[22] = halfLengths.Y(); buff.fPnts[23] = halfLengths.Z(); // 7
buff.fSegs[ 0] = 1 ; buff.fSegs[ 1] = 0 ; buff.fSegs[ 2] = 1 ; // 0
buff.fSegs[ 3] = 1 ; buff.fSegs[ 4] = 1 ; buff.fSegs[ 5] = 2 ; // 1
buff.fSegs[ 6] = 1 ; buff.fSegs[ 7] = 2 ; buff.fSegs[ 8] = 3 ; // 2
buff.fSegs[ 9] = 1 ; buff.fSegs[10] = 3 ; buff.fSegs[11] = 0 ; // 3
buff.fSegs[12] = 1 ; buff.fSegs[13] = 4 ; buff.fSegs[14] = 5 ; // 4
buff.fSegs[15] = 1 ; buff.fSegs[16] = 5 ; buff.fSegs[17] = 6 ; // 5
buff.fSegs[18] = 1 ; buff.fSegs[19] = 6 ; buff.fSegs[20] = 7 ; // 6
buff.fSegs[21] = 1 ; buff.fSegs[22] = 7 ; buff.fSegs[23] = 4 ; // 7
buff.fSegs[24] = 1 ; buff.fSegs[25] = 0 ; buff.fSegs[26] = 4 ; // 8
buff.fSegs[27] = 1 ; buff.fSegs[28] = 1 ; buff.fSegs[29] = 5 ; // 9
buff.fSegs[30] = 1 ; buff.fSegs[31] = 2 ; buff.fSegs[32] = 6 ; // 10
buff.fSegs[33] = 1 ; buff.fSegs[34] = 3 ; buff.fSegs[35] = 7 ; // 11
buff.fPols[ 0] = 1 ; buff.fPols[ 1] = 4 ; buff.fPols[ 2] = 0 ; // 0
buff.fPols[ 3] = 9 ; buff.fPols[ 4] = 4 ; buff.fPols[ 5] = 8 ;
buff.fPols[ 6] = 1 ; buff.fPols[ 7] = 4 ; buff.fPols[ 8] = 1 ; // 1
buff.fPols[ 9] = 10 ; buff.fPols[10] = 5 ; buff.fPols[11] = 9 ;
buff.fPols[12] = 1 ; buff.fPols[13] = 4 ; buff.fPols[14] = 2 ; // 2
buff.fPols[15] = 11 ; buff.fPols[16] = 6 ; buff.fPols[17] = 10 ;
buff.fPols[18] = 1 ; buff.fPols[19] = 4 ; buff.fPols[20] = 3 ; // 3
buff.fPols[21] = 8 ; buff.fPols[22] = 7 ; buff.fPols[23] = 11 ;
buff.fPols[24] = 1 ; buff.fPols[25] = 4 ; buff.fPols[26] = 0 ; // 4
buff.fPols[27] = 3 ; buff.fPols[28] = 2 ; buff.fPols[29] = 1 ;
buff.fPols[30] = 1 ; buff.fPols[31] = 4 ; buff.fPols[32] = 4 ; // 5
buff.fPols[33] = 5 ; buff.fPols[34] = 6 ; buff.fPols[35] = 7 ;
buff.SetSectionsValid(TBuffer3D::kRawSizes | TBuffer3D::kRaw);
return new TGLFaceSet(buff);
}
TGLLogicalShape * CreateLogicalFace(Double_t width, Double_t depth)
{
// Helper function to construct a TGLLogicalShape face (retangle)
// based on supplied width/depth
TBuffer3D buff(TBuffer3DTypes::kGeneric, 4, 3*4, 4, 3*4, 1, 6);
buff.fPnts[ 0] = -width; buff.fPnts[ 1] = -depth; buff.fPnts[ 2] = 0.0; // 0
buff.fPnts[ 3] = width; buff.fPnts[ 4] = -depth; buff.fPnts[ 5] = 0.0; // 1
buff.fPnts[ 6] = width; buff.fPnts[ 7] = depth; buff.fPnts[ 8] = 0.0; // 2
buff.fPnts[ 9] = -width; buff.fPnts[10] = depth; buff.fPnts[11] = 0.0; // 3
buff.fSegs[ 0] = 1 ; buff.fSegs[ 1] = 0 ; buff.fSegs[ 2] = 1 ; // 0
buff.fSegs[ 3] = 1 ; buff.fSegs[ 4] = 1 ; buff.fSegs[ 5] = 2 ; // 1
buff.fSegs[ 6] = 1 ; buff.fSegs[ 7] = 2 ; buff.fSegs[ 8] = 3 ; // 2
buff.fSegs[ 9] = 1 ; buff.fSegs[10] = 3 ; buff.fSegs[11] = 0 ; // 3
buff.fPols[ 0] = 1 ; buff.fPols[ 1] = 4 ; buff.fPols[ 2] = 0 ; // 0
buff.fPols[ 3] = 1 ; buff.fPols[ 4] = 2 ; buff.fPols[ 5] = 3 ;
buff.SetSectionsValid(TBuffer3D::kRawSizes | TBuffer3D::kRaw);
return new TGLFaceSet(buff);
}
//////////////////////////////////////////////////////////////////////////
// //
// TGLClip //
// //
// Abstract clipping shape - derives from TGLPhysicalShape //
// Adds clip mode (inside/outside) and pure virtual method to //
// approximate shape as set of planes. This plane set is used to perform//
// interactive clipping using OpenGL clip planes. //
//////////////////////////////////////////////////////////////////////////
ClassImp(TGLClip)
//______________________________________________________________________________
TGLClip::TGLClip(const TGLLogicalShape & logical, const TGLMatrix & transform, const float color[4]) :
TGLPhysicalShape(0, logical, transform, kTRUE, color),
fMode(kInside)
{
// Construct a physical clipping object, taking the 'logical' shape, a
// 'transform' matrix for placing this, and 'color'.
//
// Takes 'ownership' of logical and it will be destroyed when this is.
// Take strong reference - destroy logical when ref released in
// TGLPhysical::~TGLPhysical()
logical.StrongRef(kTRUE);
}
//______________________________________________________________________________
TGLClip::~TGLClip()
{
// Destroy clip object
}
//______________________________________________________________________________
void TGLClip::Draw(const TGLDrawFlags & flags) const
{
// Draw out clipping object with blending and back + front filling.
// Some clip objects are single face which we want to see both sides of.
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
TGLPhysicalShape::Draw(flags);
glPolygonMode(GL_FRONT, GL_FILL);
glEnable(GL_CULL_FACE);
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
}
//////////////////////////////////////////////////////////////////////////
// //
// TGLClipPlane //
// //
// Concrete clip plane object. This can be translated in all directions //
// rotated about the Y/Z local axes (the in-plane axes). It cannot be //
// scaled. //
// //
//////////////////////////////////////////////////////////////////////////
ClassImp(TGLClipPlane)
const float TGLClipPlane::fgColor[4] = { 1.0, 0.6, 0.2, 0.5 };
//______________________________________________________________________________
TGLClipPlane::TGLClipPlane(const TGLVector3 & norm, const TGLVertex3 & center, Double_t extents) :
TGLClip(*CreateLogicalFace(extents, extents), TGLMatrix(center), fgColor)
{
// Construct a clip plane object, based on supplied 'plane', with initial manipulation
// pivot at 'center', with drawn extents (in local x/y axes) of 'extents'
//
// Plane can have center pivot translated in all directions, and rotated round
// center in X/Y axes , the in-plane axes. It cannot be scaled
//
// Note theorectically a plane is of course infinite - however we want to draw
// the object in viewer - so we fake it with a single GL face (polygon) - extents
// defines the width/depth of this - should be several times scene extents.
//
SetManip(EManip(kTranslateAll | kRotateX | kRotateY));
TGLPlane plane(norm, center);
Set(plane);
}
//______________________________________________________________________________
TGLClipPlane::~TGLClipPlane()
{
// Destroy clip plane object
}
//______________________________________________________________________________
void TGLClipPlane::Set(const TGLPlane & plane)
{
// Update clip plane object to follow passed 'plane' equation. Center pivot
// is shifted to nearest point on new plane.
TGLVertex3 oldCenter = BoundingBox().Center();
TGLVertex3 newCenter = plane.NearestOn(oldCenter);
SetTransform(TGLMatrix(newCenter, plane.Norm()));
}
//______________________________________________________________________________
void TGLClipPlane::PlaneSet(TGLPlaneSet_t & set) const
{
// Return set of planes (actually a single) describing this clip plane
// Get complete set from bounding box and discard all except first (top)
BoundingBox().PlaneSet(set);
set.resize(1);
}
//////////////////////////////////////////////////////////////////////////
// //
// TGLClipBox //
// //
// Concrete clip box object. Can be translated, rotated and scaled in //
// all (xyz) axes. //
// //
//////////////////////////////////////////////////////////////////////////
ClassImp(TGLClipBox)
const float TGLClipBox::fgColor[4] = { 1.0, 0.6, 0.2, 0.3 };
//______________________________________________________________________________
TGLClipBox::TGLClipBox(const TGLVector3 & halfLengths, const TGLVertex3 & center) :
TGLClip(*CreateLogicalBox(halfLengths), TGLMatrix(center), fgColor)
{
// Construct an (initially) axis aligned clip pbox object, extents 'halfLengths',
// centered on 'center' vertex.
// Box can be translated, rotated and scaled in all (xyz) local axes.
}
//______________________________________________________________________________
TGLClipBox::~TGLClipBox()
{
// Destroy clip box object
}
//______________________________________________________________________________
void TGLClipBox::PlaneSet(TGLPlaneSet_t & set) const
{
// Return set of 6 planes describing faces of the box
BoundingBox().PlaneSet(set);
}
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.