[vtkusers] Bug in vtkOBBTree.InsideOrOutside
Carlos Martínez Burgos
cmarbur at iti.upv.es
Thu May 22 07:41:20 EDT 2003
Hi all.
I think I've found a bug in vtkOBBTree class.
I try to do a random point set generation so each of the points is inside
a surface. To do this I have a polydata surface. I build it's OBBTree.
Then I get random points inside the bounding box of the surface. Then I
test if this point is inside the surface using InsideOrOutside method of
OBBTree. If the result is -1 the point is inside and it is accepted
otherwise another point is generated and tested again until it is inside
(-1). I think this is a good approach to solve this question, what do you
think?
When I try this solution most of the points are inside the surface, but
some are outside. I think this is a bug, because if InsideOrOutside
returns -1 only if the point is inside, and I get -1 with some points that
are outside, it is not correct, isn't it?
Good. In the API it is said that this method works well only if the
surface is closed. I think it is closed but I'm not sure. I have tried
with the file cow.g from VTK data files. I have tried using procedural
sources (ConeSource, SphereSource and so on) too. These times the result
is correct I think. Does this mean that the surface in cow.g is not
closed? How could I asure that a surface is closed?
I send a program (in java) to show the problem. You can change the code
easily to use procedural sources.
I wish to know if this is a bug or it is my mistake, because I need to do
an algorithm to get a random set of points inside a surface and I don't
know if this is a good approach. Have you another idea?
Thanks in advance.
--
----------------------------------------------------------------------
Carlos Martínez Burgos | Instituto Tecnológico de Informática
Ingeniero Informático | Universidad Politécnica de Valencia
Tlf: +34 963877237 | Camí de Vera, S/N
cmarbur at iti.upv.es | 46071 Valencia - Spain
www.iti.upv.es/~cmarbur | www.iti.upv.es
----------------------------------------------------------------------
-------------- next part --------------
import vtk.*;
// Program to test that vtkOBBTree.InserOrOutside has a bug, because when I create
// some points and test if they are inside a surface, sometimes it says that it is
// true, but if you draw the points then it seems not is true.
public class InsideOutsideTest {
static {
System.loadLibrary("vtkCommonJava");
System.loadLibrary("vtkIOJava");
System.loadLibrary("vtkGraphicsJava");
System.loadLibrary("vtkRenderingJava");
};
public static void main(String[] args) {
if (args.length > 0) {
int n = 100;
if (args.length > 1) {
try {
n = Integer.valueOf(args[1]).intValue();
} catch (NumberFormatException e) {}
}
// Read the surface
vtkPolyDataReader reader = new vtkPolyDataReader();
reader.SetFileName(args[0]);
reader.Update();
vtkPolyData surface = reader.GetOutput();
// vtkConeSource source = new vtkConeSource();
// vtkSphereSource source = new vtkSphereSource();
// vtkCubeSource source = new vtkCubeSource();
// vtkCylinderSource source = new vtkCylinderSource();
// source.Update();
// vtkPolyData surface = source.GetOutput();
// Build the OBBTree to test random points
vtkOBBTree obbTree = new vtkOBBTree();
obbTree.SetDataSet(surface);
obbTree.SetMaxLevel(10);
obbTree.BuildLocator();
// Create the points polydata
vtkPolyData points = new vtkPolyData();
points.SetPoints(new vtkPoints());
points.SetVerts(new vtkCellArray());
// Points are located inside surface bounds
double[] bb = surface.GetBounds();
for (int i = 0; i < n; i++) {
// Get a new random point
double[] point = new double[3];
point[0] = bb[0] + Math.random() * (bb[1] - bb[0]);
point[1] = bb[2] + Math.random() * (bb[3] - bb[2]);
point[2] = bb[4] + Math.random() * (bb[5] - bb[4]);
// Get new random points while they are not inside the surface
while (obbTree.InsideOrOutside(point) != -1) {
point[0] = bb[0] + Math.random() * (bb[1] - bb[0]);
point[1] = bb[2] + Math.random() * (bb[3] - bb[2]);
point[2] = bb[4] + Math.random() * (bb[5] - bb[4]);
}
// Add the point to the polydata
points.GetPoints().InsertNextPoint(point);
points.GetVerts().InsertNextCell(1);
points.GetVerts().InsertCellPoint(i);
}
// Create the surface actor
vtkPolyDataMapper surfaceMapper = new vtkPolyDataMapper();
surfaceMapper.SetInput(surface);
vtkLODActor surfaceActor = new vtkLODActor();
surfaceActor.SetMapper(surfaceMapper);
// Create the OBBTree actor
vtkPolyData obb = new vtkPolyData();
obbTree.GenerateRepresentation(5, obb);
vtkPolyDataMapper obbMapper = new vtkPolyDataMapper();
obbMapper.SetInput(obb);
vtkActor obbActor = new vtkActor();
obbActor.SetMapper(obbMapper);
obbActor.GetProperty().SetColor(1.0, 0.0, 0.0);
obbActor.GetProperty().SetRepresentationToWireframe();
// Create the points actor (using glyphs)
vtkSphereSource glyph = new vtkSphereSource();
glyph.SetRadius(0.1);
glyph.SetPhiResolution(3);
glyph.SetThetaResolution(3);
vtkGlyph3D glyphs = new vtkGlyph3D();
glyphs.SetInput(points);
glyphs.SetSource(glyph.GetOutput());
glyphs.Update();
vtkPolyDataMapper pointsMapper = new vtkPolyDataMapper();
pointsMapper.SetInput(points);
// pointsMapper.SetInput(glyphs.GetOutput());
vtkLODActor pointsActor = new vtkLODActor();
pointsActor.SetMapper(pointsMapper);
pointsActor.GetProperty().SetColor(1.0, 1.0, 0.0);
// Create the renderer and add the actors
vtkRenderer renderer = new vtkRenderer();
renderer.AddActor(surfaceActor);
renderer.AddActor(obbActor);
renderer.AddActor(pointsActor);
// Create the window
vtkRenderWindow window = new vtkRenderWindow();
window.AddRenderer(renderer);
window.SetSize(500, 500);
// Create the interactor
vtkRenderWindowInteractor iren = new vtkRenderWindowInteractor();
iren.SetRenderWindow(window);
iren.Initialize();
iren.Start();
} else {
System.out.println("Error: \"InsideOutsideTest <filename (byu files)> [npoints]\"");
}
}
}
More information about the vtkusers
mailing list