Visualization Toolkit - Как читать и визуализировать несколько объектов? - PullRequest
1 голос
/ 26 марта 2019

Я пытаюсь читать и рендерить несколько файлов в каталоге (при объединении они образуют объект) с помощью vtk.Но до сих пор я получаю следующую ошибку:

ERROR: In D:\VTK\VTK-src\IO\XML\vtkXMLReader.cxx, line 283
vtkXMLPolyDataReader (00D1B560): Error opening file D:\3d models\Dist\.

ERROR: In D:\VTK\VTK-src\Common\ExecutionModel\vtkExecutive.cxx, line 782
vtkCompositeDataPipeline (00CC2078): Algorithm
vtkXMLPolyDataReader(00D1B560) returned failure for request: vtkInformation
(00D20688)
  Debug: Off
  Modified Time: 8721
  Reference Count: 1
  Registered Events: (none)
  Request: REQUEST_DATA
  FORWARD_DIRECTION: 0
  ALGORITHM_AFTER_FORWARD: 1
  FROM_OUTPUT_PORT: 0 

Пока что я пробовал читать только 1 файл вместо нескольких файлов, но я все еще упоминал об ошибке, упомянутой выше.

Вот код, над которым я работаю:

int main(int argc, char *argv[])
{
  std::string directoryName = "D:\\3d models\\Dist\\" ;

  vtkSmartPointer<vtkDirectory> directory = vtkSmartPointer<vtkDirectory>::New();
  int opened = directory->Open(directoryName.c_str());

  if(!opened)
  {
    std::cout << "No es posible abrir este directorio!" << std::endl;
    return EXIT_FAILURE;
  }

  int numberOfFiles = directory->GetNumberOfFiles();
  std::cout << "NUmero de archivos: " << numberOfFiles << std::endl;

  for (int i = 0; i < numberOfFiles; i++)
  {
    std::string fileString = directoryName;
    ////fileString += "/";
    fileString += directory->GetFile(i);

    std::string ext = vtksys::SystemTools::GetFilenameLastExtension(fileString);
    std::cout << fileString.c_str() << " extension: " << ext << std::endl;

    std::string name = vtksys::SystemTools::GetFilenameWithoutLastExtension(fileString);    
    std::cout << "nombre: " << name << std::endl;

    const char*cstr = fileString.c_str();
    std::cout << cstr << endl;

        vtkSmartPointer<vtkXMLPolyDataReader> reader =
            vtkSmartPointer<vtkXMLPolyDataReader>::New();
        reader->SetFileName(cstr);
        reader->Update();
        reader->GetOutput();

        vtkSmartPointer<vtkTransform> transform =
            vtkSmartPointer<vtkTransform>::New();
        transform->Scale(.005, .005, .005);

        vtkSmartPointer<vtkTransformFilter> transformFilter =
            vtkSmartPointer<vtkTransformFilter>::New();
        transformFilter->SetInputConnection(reader->GetOutputPort());
        transformFilter->SetTransform(transform);

        // Visualizar
        vtkSmartPointer<vtkPolyDataMapper> mapper =
            vtkSmartPointer<vtkPolyDataMapper>::New();
        mapper->SetInputConnection(transformFilter->GetOutputPort());

        vtkSmartPointer<vtkActor> actor =
            vtkSmartPointer<vtkActor>::New();
        actor->SetPosition(1.1, .5, .1);
        actor->SetMapper(mapper);

        vtkSmartPointer<vtkOpenVRRenderer> renderer =
            vtkSmartPointer<vtkOpenVRRenderer>::New();
        vtkSmartPointer<vtkOpenVRRenderWindow> renderWindow =
            vtkSmartPointer<vtkOpenVRRenderWindow>::New();
        renderWindow->AddRenderer(renderer);
        vtkSmartPointer<vtkOpenVRRenderWindowInteractor> renderWindowInteractor =
            vtkSmartPointer<vtkOpenVRRenderWindowInteractor>::New();
        renderWindowInteractor->SetRenderWindow(renderWindow);

        vtkNew<vtkOpenVRCamera> cam;
        renderer->SetActiveCamera(cam);

        renderer->AddActor(actor);
        renderer->SetBackground(.2, .3, .4);

        renderWindow->Render();
        renderWindowInteractor->Start();

  }

  return EXIT_SUCCESS;
}

Чего мне не хватает?Я пробовал с другими типами файлов, но я все еще не мог читать и рендерить что-либо с помощью этого метода.

1 Ответ

1 голос
/ 27 марта 2019

Похоже, что первая запись, когда вы перечисляете файлы в папке "."(что нормально), поэтому путь к файлу, который вы пытаетесь открыть, - "D: \ 3d models \ Dist \."и это не правильный файл для vtkXMLPolyDataReader.

Вы должны только пытаться открывать файлы vtk, написанные с помощью vtkXMLPolyDataWriter.Например, проверив расширение «.vtp» (или любое другое расширение, которое вы использовали для сохранения файлов, содержащих ваши модели vtkPolyData).

Проверьте расширение в первой части цикла:

for (int i = 0; i < numberOfFiles; i++)
  {
    std::string fileString = directoryName;
    ////fileString += "/";
    fileString += directory->GetFile(i);

    std::string ext = vtksys::SystemTools::GetFilenameLastExtension(fileString);
    std::cout << fileString.c_str() << " extension: " << ext << std::endl;

    // add this line here to skip "." and "..", also fix the extension if not .xml
    if (ext.find(".vtp") == std::string::npos) continue;

    (...)

Я также подозреваю, что вы пытаетесь использовать vtkXMLPolyDataReader, тогда как вам следует использовать vtkPolyDataReader (это действительно зависит от того, какой модуль записи использовался для создания файлов).vtkXMLPolyDataReader - это стандартное средство чтения файлов .vtp.

Наконец, вы создаете средство рендеринга, окно рендеринга и камеру внутри цикла: это означает, что одно окно на объект.Это необычно, это то, что вы хотите?

Короче говоря: вам нужен как минимум один рендер и одно окно для отображения одной или нескольких моделей.Ваши модели представлены актером каждый: окно - это место, где визуализатор рисует (одного или нескольких) актеров.Рендерер - это проход рендеринга: конечно, у вас может быть один проход рендеринга для каждого актера, но если вы не уверены, что он вам нужен, вы этого не сделаете.

Вот ваш код, измененный так, как я сделал бы на вашемместо:

int main(int argc, char *argv[])
{
    std::string directoryName = "D:\\3d models\\Dist\\" ;

    vtkSmartPointer<vtkOpenVRRenderer> renderer =
        vtkSmartPointer<vtkOpenVRRenderer>::New();
    vtkSmartPointer<vtkOpenVRRenderWindow> renderWindow =
            vtkSmartPointer<vtkOpenVRRenderWindow>::New();
    renderWindow->AddRenderer(renderer);
    vtkSmartPointer<vtkOpenVRRenderWindowInteractor> renderWindowInteractor =
            vtkSmartPointer<vtkOpenVRRenderWindowInteractor>::New();
    renderWindowInteractor->SetRenderWindow(renderWindow);
    vtkNew<vtkOpenVRCamera> cam;
    renderer->SetActiveCamera(cam);
    renderer->SetBackground(.2, .3, .4);

    vtkSmartPointer<vtkDirectory> directory = vtkSmartPointer<vtkDirectory>::New();
    int opened = directory->Open(directoryName.c_str());

    if(!opened)
    {
        std::cout << "No es posible abrir este directorio!" << std::endl;
        return EXIT_FAILURE;
    }

    int numberOfFiles = directory->GetNumberOfFiles();
    std::cout << "NUmero de archivos: " << numberOfFiles << std::endl;

    for (int i = 0; i < numberOfFiles; i++)
    {
        std::string fileString = directoryName;
        ////fileString += "/";
        fileString += directory->GetFile(i);

        std::string ext = vtksys::SystemTools::GetFilenameLastExtension(fileString);
        std::cout << fileString.c_str() << " extension: " << ext << std::endl;

        if (ext.find(".vtp") == std::string::npos) continue;

        std::string name = vtksys::SystemTools::GetFilenameWithoutLastExtension(fileString);    
        std::cout << "nombre: " << name << std::endl;

        const char*cstr = fileString.c_str();
        std::cout << cstr << endl;

        vtkSmartPointer<vtkXMLPolyDataReader> reader =
                vtkSmartPointer<vtkXMLPolyDataReader>::New();
        reader->SetFileName(cstr);
        reader->Update();
        reader->GetOutput();

        vtkSmartPointer<vtkTransform> transform =
                vtkSmartPointer<vtkTransform>::New();
        transform->Scale(.005, .005, .005);

        vtkSmartPointer<vtkTransformFilter> transformFilter =
                vtkSmartPointer<vtkTransformFilter>::New();
        transformFilter->SetInputConnection(reader->GetOutputPort());
        transformFilter->SetTransform(transform);

        // Visualizar
        vtkSmartPointer<vtkPolyDataMapper> mapper =
                vtkSmartPointer<vtkPolyDataMapper>::New();
        mapper->SetInputConnection(transformFilter->GetOutputPort());

        vtkSmartPointer<vtkActor> actor =
                vtkSmartPointer<vtkActor>::New();
        actor->SetPosition(1.1, .5, .1);
        actor->SetMapper(mapper);

        renderer->AddActor(actor);
    }

    renderWindow->Render();
    renderWindowInteractor->Start();

    return EXIT_SUCCESS;
}
...