Commit 6d3e4c83 authored by Yuanxin Liu's avatar Yuanxin Liu
Browse files

Implement vtkClipPlanesPainter::UpdateBounds(); Added new algorithm to vtkBoundingBox.

parent 493c7cd5
......@@ -21,6 +21,7 @@ CREATE_TEST_SOURCELIST(Tests ${KIT}CxxTests.cxx
TestNew.cxx
TestObservers.cxx
TestPlane.cxx
TestBoundingBox.cxx
TestPolynomialSolversUnivariate.cxx
TestSmartPointer.cxx
TestSortDataArray.cxx
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestBoundingBox.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkMath.h"
#include "vtkBoundingBox.h"
#include "vtkSmartPointer.h"
#include <limits>
#define TestBoundingBoxFailMacro(b,msg) if(!(b)){std::cerr <<msg<<std::endl;return EXIT_FAILURE;}
int TestBoundingBox(int,char *[])
{
{
double n[3]={-1,0.5,0};
double p[3]={-1,-1,-1};
double bb[6] = {-1,1,-1,1,-1,1};
vtkBoundingBox bbox(bb);
bool res = bbox.IntersectPlane(p,n);
bbox.GetBounds(bb);
TestBoundingBoxFailMacro(res && bb[0]==-1 && bb[1]==0,"Intersect Plane Failed!")
}
{
double n[3]={0,0,1};
double p[3]={0,0,0};
double bb[6] = {-1,1,-1,1,-1,1};
vtkBoundingBox bbox(bb);
bool res = bbox.IntersectPlane(p,n);
bbox.GetBounds(bb);
TestBoundingBoxFailMacro(res && bb[4]==0 && bb[5]==1,"Intersect Plane Failed!")
}
{
double n[3]={0,0,-1};
double p[3]={0,0,0};
double bb[6] = {-1,1,-1,1,-1,1};
vtkBoundingBox bbox(bb);
bool res = bbox.IntersectPlane(p,n);
bbox.GetBounds(bb);
TestBoundingBoxFailMacro(res && bb[4]==-1 && bb[5]==0,"Intersect Plane Failed!")
}
{
double n[3]={0,-1,0};
double p[3]={0,0,0};
double bb[6] = {-1,1,-1,1,-1,1};
vtkBoundingBox bbox(bb);
bool res = bbox.IntersectPlane(p,n);
bbox.GetBounds(bb);
TestBoundingBoxFailMacro(res && bb[2]==-1 && bb[3]==0,"Intersect Plane Failed!")
}
{
double n[3]={1,1,1};
double p[3]={0,0,0};
double bb[6] = {-1,1,-1,1,-1,1};
vtkBoundingBox bbox(bb);
bool res = bbox.IntersectPlane(p,n);
bbox.GetBounds(bb);
TestBoundingBoxFailMacro( !res
&& bb[0] ==-1 && bb[1]==1
&& bb[2] ==-1 && bb[3]==1
&& bb[4] ==-1 && bb[5] ==1,"Intersect Plane Failed!")
}
return EXIT_SUCCESS;
}
......@@ -13,9 +13,24 @@
=========================================================================*/
#include "vtkBoundingBox.h"
#include <vtkMath.h>
#include <vtkPlane.h>
#include <assert.h>
#include <math.h>
// ---------------------------------------------------------------------------
namespace
{
inline double Sign(const double& a)
{
return a>0.0? 1.0 : ( a<0? -1.0 : 0.0);
}
inline bool OppSign(const double& a, const double& b)
{
return (a<=0 && b>=0) || (a>=0 && b<=0);
}
};
// ---------------------------------------------------------------------------
void vtkBoundingBox::AddPoint(double px, double py, double pz)
{
......@@ -370,3 +385,92 @@ void vtkBoundingBox::Scale(double s[3])
{
this->Scale(s[0],s[1],s[2]);
}
// ---------------------------------------------------------------------------
// Desciption:
// Intersect this box with the half space defined by plane.
//Returns 1 if there is intersection---which implies that the box has been modified
// Returns 0 otherwise
// The algorithm:
// Because the change can only happens in one axis aligned direction,
// we first figure out which direction it is (stored in dir), then
// update the bounding interval in that direction based on intersection
// of the plane with the four edges
bool vtkBoundingBox::IntersectPlane(double origin[3],double normal[3])
{
double* bounds[2] = {this->MinPnt,this->MaxPnt};
assert(this->IsValid());
//Index[0..2] represents the order of traversing the corners of a cube
// in (x,y,z), (y,x,z) and (z,x,y) ordering, respectively
static const char Index[3][8] =
{ {0, 1, 2, 3, 4, 5, 6, 7},
{0, 1, 4, 5, 2, 3, 6, 7},
{0, 2, 4, 6, 1, 3, 5, 7}};
double d[8]={0,0,0,0,0,0,0,0}; //stores the signed distance to a plane
{
int index(-1);
for(int ix = 0; ix<=1; ix++)
{
for(int iy = 0; iy<=1; iy++)
{
for(int iz = 0; iz<=1; iz++)
{
double x[3]={bounds[ix][0],bounds[iy][1],bounds[iz][2]};
d[++index] = vtkPlane::Evaluate(normal,origin,x);
}
}
}
}
int dir(-1);
for(dir=2;dir>=0; dir--)
{
//in each direction, we test if the vertices of two orthogonal faces
//are on either side of the plane
if( OppSign(d[Index[dir][0]], d[Index[dir][4]]) &&
OppSign(d[Index[dir][1]], d[Index[dir][5]]) &&
OppSign(d[Index[dir][2]], d[Index[dir][6]]) &&
OppSign(d[Index[dir][3]], d[Index[dir][7]]) )
{
break;
}
}
if(dir<0)
{
return false;
}
double sign = Sign(normal[dir]);
double size = fabs((bounds[1][dir] - bounds[0][dir])*normal[dir]);
double t = sign>0? 1 : 0;
for(int i=0; i<4; i++)
{
if(size==0) continue; //shouldn't happen
double ti = fabs(d[Index[dir][i]])/ size;
if(sign>0 && ti<t )
{
t = ti;
}
if(sign<0 && ti>t)
{
t = ti;
}
}
double bound = (1.0-t)*bounds[0][dir] + t*bounds[1][dir];
if(sign>0)
{
bounds[0][dir] = bound;
}
else
{
bounds[1][dir] = bound;
}
return true;
}
......@@ -24,7 +24,7 @@ PURPOSE. See the above copyright notice for more information.
#ifndef __vtkBoundingBox_h
#define __vtkBoundingBox_h
#include "vtkSystemIncludes.h"
class VTK_COMMON_EXPORT vtkBoundingBox
{
public:
......@@ -95,6 +95,14 @@ public:
// Returns 1 if the boxes intersect else returns 0
int Intersects(const vtkBoundingBox &bbox) const;
// Desciption:
// Intersect this box with the half space defined by plane.
//Returns true if there is intersection---which implies that the box has been modified
// Returns false otherwise
bool IntersectPlane(double origin[3],double normal[3]);
// Description:
// Returns 1 if the min and max points of bbox are contained
// within the bounds of this box, else returns 0.
......
......@@ -20,6 +20,7 @@
#include "vtkGraphicsFactory.h"
#include "vtkObjectFactory.h"
#include "vtkPlaneCollection.h"
#include "vtkBoundingBox.h"
vtkCxxSetObjectMacro(vtkClipPlanesPainter, ClippingPlanes, vtkPlaneCollection);
......@@ -71,3 +72,32 @@ void vtkClipPlanesPainter::PrintSelf(ostream& os, vtkIndent indent)
os << " (none)" << endl;
}
}
//-----------------------------------------------------------------------------
void vtkClipPlanesPainter::UpdateBounds(double bounds[6])
{
if(!vtkBoundingBox::IsValid(bounds))
{
return;
}
vtkPlaneCollection* planes =this->ClippingPlanes;
if(planes)
{
int n = planes->GetNumberOfItems();
for(int i=0; i<n; i++)
{
vtkPlane *plane = planes->GetItem(i);
if(plane)
{
double n[3],p[3];
plane->GetNormal(n);
plane->GetOrigin(p);
vtkBoundingBox bb(bounds);
if(bb.IntersectPlane(p,n))
{
bb.GetBounds(bounds);
}
}
}
}
}
\ No newline at end of file
......@@ -34,6 +34,10 @@ public:
// Get/Set the vtkPlaneCollection which specifies the clipping planes.
static vtkInformationObjectBaseKey* CLIPPING_PLANES();
// Description:
// Update the bounds based on the clip planes
virtual void UpdateBounds(double bounds[6]);
protected:
vtkClipPlanesPainter();
~vtkClipPlanesPainter();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment