IVtkTools_ShapePicker doesn't pick anything

83 views Asked by At

Hi everyone,

I use Qt5, Opencascade 7.7.0 and VTK 9.2.6 on windows.

I want to load and display a step file and then being able to clic and select part of the loaded object.

I have already coded the loader and now I'm trying to code the picker using IVtkTools_ShapePicker but it doesn't work at all. The picker return nothing.

Thank you all for any replies and hintchs!

Best regards.

Here is some of my codlines:

In my main:

vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputConnection(occSource->GetOutputPort()); // occSource type : IVtkTools_ShapeDataSource
mapper->ScalarVisibilityOff();

vtkNew<vtkActor> actor;
actor->GetProperty()->SetPointSize(5);
actor->GetProperty()->SetDiffuseColor(colors->GetColor3d("SeaGreen").GetData());
actor->GetProperty()->EdgeVisibilityOn();
actor->SetMapper(mapper);

...

vtkNew<StepElementPicker> picker;
picker->Init(renderWindow->GetRenderers()->GetFirstRenderer());
vtkRenderWindowInteractor* renderWindowInteractor = renderWindow->GetInteractor(); // renderWindow type : vtkRenderWindow
renderWindowInteractor->SetInteractorStyle(picker);

And my class StepElementPicker inherited from vtkInteractorStyleTrackballCamera contains an init function:

void Init(vtkRenderer* renderer)
{
    vtkInteractorStyleTrackballCamera::SetDefaultRenderer(renderer);
}

void OnLeftButtonDown() override
{
    // Get the location of the click (in window coordinates)
    int* pos = this->GetInteractor()->GetEventPosition();

    vtkNew<IVtkTools_ShapePicker> picker;
    picker->SetRenderer(this->GetDefaultRenderer());
    picker->SetTolerance(0.0005);
    picker->SetSelectionMode(SM_Face);

    // Pick from this location
    int nb = picker->Pick(pos[0], pos[1], 0);
    std::cout << "nb : " << nb << std::endl; // <<== always return 0
    
    IVtk_ShapeIdList ids = picker->GetPickedShapesIds(true);
    std::cout << "ids.Size : " << ids.Size() << std::endl; // <<== always return 0
}

In my function my picker (picker->Pick(pos[0], pos[1], 0)) always return 0 and the ids.Size() always return 0 so I cannot get anything from my picker.

I have tried with another picker from VTK and it works but I need to use the one from Opencascade to be able to get all subshapes.

vtkNew<vtkCellPicker> picker;
picker->SetTolerance(0.005f);
// Pick from this location.
int nb = picker->Pick(pos[0], pos[1], 0, this->GetDefaultRenderer());
std::cout << "nb : " << nb << std::endl; // return 1 or 0
std::cout << "Cell id : " << picker->GetCellId() << std::endl; // return the VTK ID of the selected cell (or -1 if any)
1

There are 1 answers

0
CognitiveRebound On

I'm struggling with a similiar problem, but instead of a single shape I add multiple TopoDS_Shape seperately which each individual actors to the vtk renderer.

I tried to use the IVtkTools_ShapePicker, but it did not select anything. I made it work by using the standard vtkPropPicker.

This is the callback:

virtual void OnLeftButtonDown()
{
    int *clickPos = this->GetInteractor()->GetEventPosition();

    // Pick from this location.
    auto defaultPicker = vtkSmartPointer<vtkPropPicker>::New();
    defaultPicker->Pick(clickPos[0], clickPos[1], 0, this->GetDefaultRenderer());

    double *pos = defaultPicker->GetPickPosition();
    std::cout << "Pick position (world coordinates) is: "
              << pos[0] << " " << pos[1] << " " << pos[2] << std::endl;

    auto actor = defaultPicker->GetActor();

    if (actor)
    {
        std::cout << "Picked actor (addr): " << actor << std::endl;

        IVtkTools_ShapeDataSource *aDataSource = IVtkTools_ShapeObject::GetShapeSource(actor);
        if (aDataSource)
        {
            IVtkOCC_Shape::Handle anOccShape = aDataSource->GetShape();
            if (!anOccShape.IsNull())
            {

                // use the shape from anOccShape->GetShape() to do something...
            }
        }
    }

    // Forward events
    vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
}

And this is how I add the shape:

IVtkOCC_Shape::Handle aShapeImpl = new IVtkOCC_Shape(shape);
auto dataSource = vtkSmartPointer<IVtkTools_ShapeDataSource>::New();
dataSource->SetShape(aShapeImpl);
auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(dataSource->GetOutputPort());
auto actor = vtkSmartPointer<vtkActor>::New();
actor->SetPickable(true);
actor->SetMapper(mapper);
IVtkTools_ShapeObject::SetShapeSource(dataSource, actor); // <--- MVP: sets a property on the actor and links shape and actor together
renderer->AddActor(actor);