Выбор ВТК и GlobalIds - PullRequest
       22

Выбор ВТК и GlobalIds

0 голосов
/ 24 ноября 2018

Я пытаюсь установить и получить vtkPolyData GlobalIdsНиже приведен фрагмент кода для создания поли данных

pcl::PointCloud<pcl::PointNormal>::Ptr pointCloud(new pcl::PointCloud<pcl::PointNormal>);
pcl::io::loadPLYFile("scansample/constructedcloud.ply", *pointCloud);
qInfo() << "Size of point cloud " << pointCloud->size();

vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New();
colors->SetNumberOfComponents(3);
colors->SetName ("Colors");

// Set point normals
vtkSmartPointer<vtkDoubleArray> pointNormalsArray = vtkSmartPointer<vtkDoubleArray>::New();
pointNormalsArray->SetNumberOfComponents(3); //3d normals (ie x,y,z)
pointNormalsArray->SetName("Normals");

vtkSmartPointer<vtkIdTypeArray> pointIds = vtkSmartPointer<vtkIdTypeArray>::New();
pointIds->SetNumberOfComponents(1);
pointIds->SetName("pointIds");

vtkSmartPointer<vtkIdTypeArray> globalIds = vtkSmartPointer<vtkIdTypeArray>::New();
globalIds->SetNumberOfComponents(1);
globalIds->SetName("globalIds");

unsigned char tmpColor[3] = {200, 200, 100};
for(unsigned int i=0; i<pointCloud->size(); i++){
    points->InsertNextPoint(pointCloud->points[i].x, pointCloud->points[i].y, pointCloud->points[i].z);
    double pn[3] = {pointCloud->points[i].normal_x, pointCloud->points[i].normal_y, pointCloud->points[i].normal_z};
    pointNormalsArray->InsertNextTypedTuple(pn);
    colors->InsertNextTypedTuple(tmpColor);
    pointIds->InsertNextValue(i);
    globalIds->InsertNextValue(i);
}

vtkSmartPointer<vtkPolyData> pointsPoly = vtkSmartPointer<vtkPolyData>::New();
pointsPoly->SetPoints(points);

vtkSmartPointer<vtkVertexGlyphFilter> vertexFilter = vtkSmartPointer<vtkVertexGlyphFilter>::New();
vertexFilter->SetInputData(pointsPoly);
vertexFilter->Update();

vPointCloud = vtkSmartPointer<vtkPolyData>::New();
vPointCloud->ShallowCopy(vertexFilter->GetOutput());
vPointCloud->GetPointData()->SetScalars(colors);
vPointCloud->GetPointData()->SetNormals(pointNormalsArray);
vPointCloud->GetPointData()->AddArray(pointIds);

vPointCloud->GetPointData()->SetGlobalIds(globalIds);
vPointCloud->GetPointData()->CopyGlobalIdsOn();

Затем я установил интерактивный инструмент выбора резиновой ленты и хочу получить глобальные идентификаторы выбранных точек.Ниже приведен фрагмент связанного кода

void interactorArea::OnLeftButtonUp(){   
    vtkInteractorStyleRubberBandPick::OnLeftButtonUp();

    vtkPlanes* frustum = static_cast<vtkAreaPicker*>(this->GetInteractor()->GetPicker())->GetFrustum();
    vtkSmartPointer<vtkExtractGeometry> extractGeometry = vtkSmartPointer<vtkExtractGeometry>::New();
    extractGeometry->SetImplicitFunction(frustum);
    extractGeometry->SetInputData(this->Points);
    extractGeometry->Update();
    extractGeometry->GetOutput()->GetPointData()->CopyGlobalIdsOn();

    vtkSmartPointer<vtkSelectVisiblePoints> visiblePoints = vtkSmartPointer<vtkSelectVisiblePoints>::New();
    visiblePoints->SetInputConnection(extractGeometry->GetOutputPort());
    visiblePoints->SetRenderer(this->GetInteractor()->GetRenderWindow()->GetRenderers()->GetFirstRenderer());
    visiblePoints->Update();
    visiblePoints->GetOutput()->GetPointData()->CopyGlobalIdsOn();

    vtkSmartPointer<vtkVertexGlyphFilter> glyphFilter = vtkSmartPointer<vtkVertexGlyphFilter>::New();
    glyphFilter->SetInputConnection(extractGeometry->GetOutputPort());
    glyphFilter->Update();
    glyphFilter->GetOutput()->GetPointData()->CopyGlobalIdsOn();
    vtkPolyData* selected = glyphFilter->GetOutput();

    vtkSmartPointer<vtkVertexGlyphFilter> visibleFilter = vtkSmartPointer<vtkVertexGlyphFilter>::New();
    visibleFilter->SetInputConnection(visiblePoints->GetOutputPort());
    visibleFilter->Update();
    visibleFilter->GetOutput()->GetPointData()->CopyGlobalIdsOn();
    vtkPolyData* visibles = visibleFilter->GetOutput();

    std::cout << "Selected points " << selected->GetNumberOfPoints() << std::endl;
    std::cout << "Visible points " << visibles->GetNumberOfPoints() << std::endl;

    selectedIds = vtkSmartPointer<vtkIdTypeArray>::New();
    selectedIds = vtkIdTypeArray::SafeDownCast(visibles->GetPointData()->GetArray("pointIds"));
    unsigned int idsize = selectedIds->GetNumberOfTuples();

    for(unsigned int j=0; j<idsize; j++)
        std::cout << selectedIds->GetValue(j) << " ";
    std::cout << std::endl;


    // This part is crashing when I try to reach visibles' globalids. I could get if I replace visibles with selected 
    // selected->GetPointData()->GetGlobalIds() working
    vtkSmartPointer<vtkIdTypeArray> globalIds = vtkSmartPointer<vtkIdTypeArray>::New();
    globalIds = vtkIdTypeArray::SafeDownCast(visibles->GetPointData()->GetGlobalIds());
    assert(globalIds);
    std::cout << "Nof globalIds " << globalIds->GetNumberOfComponents() << " " << globalIds->GetNumberOfTuples() << std::endl;

    }
}

Программа падает в той части, где я пытаюсь получить размер массивов, связанных с globalids.Но если я попытаюсь добраться до "отобранных" глобалидов, это сработает.Я думаю, что есть проблема с классом vtkSelectVisiblePoints, но я не смог найти.

Есть предложения?

...