[vtkusers] pipeline setup question

Geoff Woodcock geoff.woodcock at velo3d.com
Thu May 31 14:24:32 EDT 2018


Hi,

I've created a pipeline to try and do "collision detection" for use with copy/paste using vtkIntersectionPolyDataFilter. Basically, I get a set of bounding boxes for objects already in the scene and then another set for the objects being pasted. Then I move the position of the pasted objects around, recalculate the bounding boxes, and test for intersection until it fails.

The pipeline is like this:

CubeSource(1..n) -> appendfilter -> geometry filter -> trianglefilter -intersectfilter

2 pipelines, one for objects already in scene, one for objects being pasted.

I have several problems:


  *   vtkIntersectionPolyDataFilter crashes sometimes when there are multiple objects in the scene or being pasted. It might be a known bug related to https://gitlab.kitware.com/vtk/vtk/commit/eb975a3742de5aa5592fbb7ba2dd4726c9a51313
  *   vtkIntersectionPolyDataFilter does not handle the case where one object is inside of the other (no intersection occurs)
  *   I tried to work around this bug by testing each bounding box separately. So I assign the cubesources one at a time to the appendfilter. When I do this, I get a message, "Can't build OBB tree, no data available", followed by a crash in vtkOBBTree::DisjointOBBNodes. ("nodeA was nullPtr")

Other than an any general advice anyone can give me, can anyone explain the third  item? If I assign the cubesources as I build the pipeline, it works correctly. But if I assign them after the pipeline is built, it crashes...why? There is something fundamental I am not understanding about the pipeline.

Here is my messy test code... commenting and uncommenting the two indicated lines makes the crash come and go...

    vtkSmartPointer<vtkIntersectionPolyDataFilter> intersectFilter = vtkSmartPointer<vtkIntersectionPolyDataFilter>::New();
    vtkSmartPointer<vtkAppendFilter> appendFilter = vtkSmartPointer<vtkAppendFilter>::New();

    // get bounding box of all existing actors
    std::vector<std::vector<double>> bboxes;
    std::vector<vtkSmartPointer<vtkCubeSource>> cubes;
    double bounds[6];
    double maxBounds[3] = {0};
    for (const auto& object : doc->getChildren()) {
        auto actor = vtkProp3D::SafeDownCast(Core::Application::get()->getContext().getActorForPart(object));
        if (actor->GetPickable()) {
            double origin[3];
            actor->GetOrigin(origin);
            actor->GetBounds(bounds);
            if (bounds[1] > maxBounds[0]) {
                maxBounds[0] = bounds[1];
            }
            if (bounds[3] > maxBounds[1]) {
                maxBounds[1] = bounds[3];
            }
            if (bounds[5] > maxBounds[2]) {
                maxBounds[2] = bounds[5];
            }
        }
        std::vector<double> values = {bounds[0], bounds[1], bounds[2], bounds[3], bounds[4], bounds[5], bounds[6]};
        bboxes.push_back(values);
        vtkSmartPointer<vtkCubeSource> cube = vtkSmartPointer<vtkCubeSource>::New();
        cube->SetBounds(bounds);
        cube->Update();
        cubes.push_back(cube);
        appendFilter->AddInputConnection(cube->GetOutputPort()); // <---- works if I add connections here.
    }
    vtkSmartPointer<vtkGeometryFilter> geometryFilter = vtkSmartPointer<vtkGeometryFilter>::New();
    geometryFilter->SetInputConnection(appendFilter->GetOutputPort());
    vtkSmartPointer<vtkTriangleFilter> triFilter = vtkSmartPointer<vtkTriangleFilter>::New();
    triFilter->SetInputConnection(geometryFilter->GetOutputPort(0));
    intersectFilter->SetInputConnection(0, triFilter->GetOutputPort());

    // get bounding box of all objects
    std::vector<vtkSmartPointer<vtkCubeSource>> pasteObjectBounds;
    vtkSmartPointer<vtkAppendFilter> pastedObjAppendFilter = vtkSmartPointer<vtkAppendFilter>::New();

    for (const auto& object : _copyPasteBuffer) {
        vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
        polyData->ShallowCopy(object->data());
        polyData->ComputeBounds();
        polyData->GetBounds(bounds);
        vtkSmartPointer<vtkCubeSource> cube = vtkSmartPointer<vtkCubeSource>::New();
        auto layout = object->layout();
        auto x = layout._matrix->GetElement(0, 3);
        auto y = layout._matrix->GetElement(1, 3);
        cube->SetBounds(bounds);
        cube->SetCenter(x, y, 0);
        cube->Update();
        pastedObjAppendFilter->AddInputConnection(cube->GetOutputPort());

        pasteObjectBounds.push_back(cube);
    }

    pastedObjAppendFilter->Update();
    vtkSmartPointer<vtkGeometryFilter> pastedObjGeometryFilter = vtkSmartPointer<vtkGeometryFilter>::New();
    pastedObjGeometryFilter->SetInputConnection(pastedObjAppendFilter->GetOutputPort());
    pastedObjGeometryFilter->Update();
    vtkSmartPointer<vtkTriangleFilter> pasteTriFilter = vtkSmartPointer<vtkTriangleFilter>::New();
    pasteTriFilter->SetInputConnection(pastedObjGeometryFilter->GetOutputPort(0));
    pasteTriFilter->Update();
    vtkSmartPointer<vtkCleanPolyData> pasteCleanData = vtkSmartPointer<vtkCleanPolyData>::New();
    pasteCleanData->SetInputConnection(pasteTriFilter->GetOutputPort());
    pasteCleanData->Update();

    intersectFilter->SetInputConnection(1, pasteCleanData->GetOutputPort());

    bool foundASpot = false;
    auto polyData = vtkPolyData::SafeDownCast(pastedObjGeometryFilter->GetOutputDataObject(0));
    polyData->ComputeBounds();
    polyData->GetBounds(bounds);
    double p1[3] = {bounds[0], bounds[2], 0};
    double p2[3] = {bounds[1], bounds[3], 0};

    double length = sqrt(vtkMath::Distance2BetweenPoints(p1, p2));
    double step = length / 4.0;
    double radius = 0;
    while (!foundASpot) {
        for (int ii = 0; ii < 6 && !foundASpot; ii++) {
            double angle = 45 * ii;
            double x = radius * sin(angle);
            double y = radius * cos(angle);

            for (auto cube : pasteObjectBounds) {
                double center[3];
                cube->GetCenter(center);
                center[0] += x;
                center[1] += y;
                cube->SetCenter(center);
                cube->Update();
                cube->Modified();
            }

            // check for intersection.
            foundASpot = true;
            for (auto cube : cubes) {
                //appendFilter->SetInputConnection(cube->GetOutputPort());// <----fails if I set input connection here.
                appendFilter->Update();
                appendFilter->Modified();
                geometryFilter->Update();
                geometryFilter->Modified();
                triFilter->Update();
                triFilter->Modified();
                intersectFilter->Update();
                if (intersectFilter->GetNumberOfIntersectionPoints()) {
                    foundASpot = false;
                }
            }
            if (!foundASpot) {
                for (auto pasteCubes : pasteObjectBounds) {
                    double center[3];
                    pasteCubes->GetCenter(center);
                    center[0] -= x;
                    center[1] -= y;
                    pasteCubes->SetCenter(center);
                    pasteCubes->Update();
                    pasteCubes->Modified();
                }
            } else {
                // found a spot!
                foundASpot = true;
                maxBounds[0] = x;
                maxBounds[1] = y;
            }
        }

        radius += step;
    }



CONFIDENTIALITY NOTICE:This message (including any attachments) may contain confidential, proprietary, privileged and/or private information. If you are not the intended recipient of this message, please notify the sender immediately, and delete the message and any attachments. Any disclosure, reproduction, distribution or other use of this message or any attachments by an individual or entity other than the intended recipient is prohibited
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://public.kitware.com/pipermail/vtkusers/attachments/20180531/4ba4e975/attachment.html>


More information about the vtkusers mailing list