From 222d6f61d3629e25f6bfc72be66309d7132e9875 Mon Sep 17 00:00:00 2001
From: Matevz Tadel <matevz.tadel@cern.ch>
Date: Fri, 3 Dec 2010 16:55:15 +0000
Subject: [PATCH] * TEveShape:   Add functions:     Bool_t
 IsBoxOrientationConsistentXx();     void   CheckAndFixBoxOrientationXx();  
 that check and fix box orientation so that the face normals point   outwards.

* TEveBox, TEveBoxSet:
  Ensure proper box orientation.


git-svn-id: http://root.cern.ch/svn/root/trunk@37228 27541ba8-7e3a-0410-8455-c3a389f83636
---
 graf3d/eve/inc/TEveShape.h    |  8 ++++-
 graf3d/eve/src/TEveBox.cxx    |  5 +++
 graf3d/eve/src/TEveBoxSet.cxx |  7 ++---
 graf3d/eve/src/TEveShape.cxx  | 59 +++++++++++++++++++++++++++++++++++
 4 files changed, 74 insertions(+), 5 deletions(-)

diff --git a/graf3d/eve/inc/TEveShape.h b/graf3d/eve/inc/TEveShape.h
index fa9321712cb..e0079048fef 100644
--- a/graf3d/eve/inc/TEveShape.h
+++ b/graf3d/eve/inc/TEveShape.h
@@ -81,7 +81,13 @@ public:
 
    // ----------------------------------------------------------------
 
-   static Int_t FindConvexHull(const vVector2_t& pin, vVector2_t& pout, TEveElement* caller=0);
+   static Int_t  FindConvexHull(const vVector2_t& pin, vVector2_t& pout, TEveElement* caller=0);
+
+   static Bool_t IsBoxOrientationConsistentEv(const TEveVector box[8]);
+   static Bool_t IsBoxOrientationConsistentFv(const Float_t    box[8][3]);
+
+   static void   CheckAndFixBoxOrientationEv(TEveVector box[8]);
+   static void   CheckAndFixBoxOrientationFv(Float_t    box[8][3]);
 
    ClassDef(TEveShape, 0); // Abstract base-class for 2D/3D shapes.
 };
diff --git a/graf3d/eve/src/TEveBox.cxx b/graf3d/eve/src/TEveBox.cxx
index e0fa5a3fa07..aca41faca96 100644
--- a/graf3d/eve/src/TEveBox.cxx
+++ b/graf3d/eve/src/TEveBox.cxx
@@ -51,6 +51,7 @@ void TEveBox::SetVertex(Int_t i, Float_t x, Float_t y, Float_t z)
    fVertices[i][0] = x;
    fVertices[i][1] = y;
    fVertices[i][2] = z;
+   ResetBBox();
 }
 
 //______________________________________________________________________________
@@ -61,6 +62,7 @@ void TEveBox::SetVertex(Int_t i, const Float_t* v)
    fVertices[i][0] = v[0];
    fVertices[i][1] = v[1];
    fVertices[i][2] = v[2];
+   ResetBBox();
 }
 
 //______________________________________________________________________________
@@ -69,6 +71,7 @@ void TEveBox::SetVertices(const Float_t* vs)
    // Set vertices.
 
    memcpy(fVertices, vs, sizeof(fVertices));
+   ResetBBox();
 }
 
 //==============================================================================
@@ -78,6 +81,8 @@ void TEveBox::ComputeBBox()
 {
    // Compute bounding-box of the data.
 
+   TEveShape::CheckAndFixBoxOrientationFv(fVertices);
+
    BBoxInit();
    for (Int_t i=0; i<8; ++i)
    {
diff --git a/graf3d/eve/src/TEveBoxSet.cxx b/graf3d/eve/src/TEveBoxSet.cxx
index 4816727699a..052d2c9891f 100644
--- a/graf3d/eve/src/TEveBoxSet.cxx
+++ b/graf3d/eve/src/TEveBoxSet.cxx
@@ -10,11 +10,9 @@
  *************************************************************************/
 
 #include "TEveBoxSet.h"
+#include "TEveShape.h"
+
 #include "TRandom.h"
-#include "TBuffer3D.h"
-#include "TBuffer3DTypes.h"
-#include "TVirtualPad.h"
-#include "TVirtualViewer3D.h"
 
 //==============================================================================
 // TEveBoxSet
@@ -126,6 +124,7 @@ void TEveBoxSet::AddBox(const Float_t* verts)
 
    BFreeBox_t* b = (BFreeBox_t*) NewDigit();
    memcpy(b->fVertices, verts, sizeof(b->fVertices));
+   TEveShape::IsBoxOrientationConsistentFv(b->fVertices);
 }
 
 //______________________________________________________________________________
diff --git a/graf3d/eve/src/TEveShape.cxx b/graf3d/eve/src/TEveShape.cxx
index 3a7681130b9..4e762bc9c4e 100644
--- a/graf3d/eve/src/TEveShape.cxx
+++ b/graf3d/eve/src/TEveShape.cxx
@@ -212,3 +212,62 @@ Int_t TEveShape::FindConvexHull(const vVector2_t& pin, vVector2_t& pout, TEveEle
 
    return N;
 }
+
+//==============================================================================
+
+//______________________________________________________________________________
+Bool_t TEveShape::IsBoxOrientationConsistentEv(const TEveVector box[8])
+{
+   // Checks if the first face normal is pointing into the other
+   // direction as the vector pointing towards the opposite face.
+   // This assumes standard box vertex arrangement.
+
+   TEveVector f1 = box[1] - box[0];
+   TEveVector f2 = box[3] - box[0];
+   TEveVector up = box[4] - box[0];
+
+   return up.Dot(f1.Cross(f2)) < 0;
+}
+
+//______________________________________________________________________________
+Bool_t TEveShape::IsBoxOrientationConsistentFv(const Float_t box[8][3])
+{
+   // Checks if the first face normal is pointing into the other
+   // direction as the vector pointing towards the opposite face.
+   // This assumes standard box vertex arrangement.
+
+   TEveVector b0(box[0]);
+   TEveVector f1(box[1]); f1 -= b0;
+   TEveVector f2(box[3]); f2 -= b0;
+   TEveVector up(box[4]); up -= b0;
+
+   return up.Dot(f1.Cross(f2)) < 0;
+}
+
+//______________________________________________________________________________
+void TEveShape::CheckAndFixBoxOrientationEv(TEveVector box[8])
+{
+   // Make sure box orientation is consistent with standard arrangement.
+
+   if ( ! IsBoxOrientationConsistentEv(box))
+   {
+      std::swap(box[1], box[3]);
+      std::swap(box[5], box[7]);
+   }
+}
+
+//______________________________________________________________________________
+void TEveShape::CheckAndFixBoxOrientationFv(Float_t box[8][3])
+{
+   // Make sure box orientation is consistent with standard arrangement.
+
+   if ( ! IsBoxOrientationConsistentFv(box))
+   {
+      std::swap(box[1][0], box[3][0]);
+      std::swap(box[1][1], box[3][1]);
+      std::swap(box[1][2], box[3][2]);
+      std::swap(box[5][0], box[7][0]);
+      std::swap(box[5][1], box[7][1]);
+      std::swap(box[5][2], box[7][2]);
+   }
+}
-- 
GitLab