[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