Read/Write vtk file not displaying properly - c++

I Have an unstructured grid that which I need to write into a file and open elsewhere. The original file looks like this;
When I write the file and read it again, it displays as following,
The code for writing the file is;
std::string filename = "ouputTest.vtu";
//pre-constructed grid
(vtkSmartPointer<vtkUnstructuredGrid>) grid;
vtkSmartPointer<vtkGeometryFilter> geometryFilter = vtkSmartPointer<vtkGeometryFilter>::New();
vtkSmartPointer<vtkPolyData> polydata;
geometryFilter->SetInput(grid);
geometryFilter->Update();
polydata = geometryFilter->GetOutput();
vtkSmartPointer<vtkDoubleArray> tempArray = vtkSmartPointer<vtkDoubleArray>::New();
for(int i=0;i<4;i++)
{
tempArray->InsertNextValue(i/2.5);
}
polydata->GetPointData()->SetScalars(tempArray);
grid->GetPointData()->SetScalars(tempArray);
vtkSmartPointer<vtkLookupTable> colorLookupTable = vtkSmartPointer<vtkLookupTable>::New();
colorLookupTable->SetTableRange(-100,500);
double vmin,vmax;
colorLookupTable->GetHueRange(vmin,vmax);
if(vmin!=vmax)
{
colorLookupTable->SetHueRange(0.6667,0.0);
}
colorLookupTable->Build();
vtkSmartPointer<vtkContourFilter> contourFilter = vtkSmartPointer<vtkContourFilter>::New();
contourFilter->SetInputConnection(polydata->GetProducerPort());
contourFilter->ComputeScalarsOn();
contourFilter->GenerateValues(10,-100,500);
vtkSmartPointer<vtkPolyDataMapper> mapper1 = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper1->SetInputConnection(contourFilter->GetOutputPort());
mapper1->SetScalarRange(-100,500);
mapper1->SetLookupTable(colorLookupTable);
mapper1->ScalarVisibilityOn();
vtkSmartPointer<vtkActor> actor1 = vtkSmartPointer<vtkActor>::New();
actor1->SetMapper(mapper1);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInput(polydata);
mapper->ScalarVisibilityOn();
mapper->InterpolateScalarsBeforeMappingOn();
mapper->SetLookupTable(colorLookupTable);
mapper->SetScalarRange(-100,500);
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
// Visualize
vtkSmartPointer<vtkRenderer> renderer =vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderer->AddActor(actor1);
renderer->AddActor(actor);
renderer->SetBackground(.3, .6, .3); // Background color green
// Write file
vtkSmartPointer<vtkXMLUnstructuredGridWriter> writer =
vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
writer->SetFileName(filename.c_str());
#if VTK_MAJOR_VERSION <= 5
writer->SetInput(grid);
#else
writer->SetInputData(grid);
#endif
writer->SetDataModeToAscii();
writer->Write();
renderWindow->Render();
renderWindowInteractor->Start();
The code for reading the file is;
std::string filename = "ouputTest.vtu";
vtkSmartPointer reader = vtkSmartPointer::New();
reader->SetFileName(filename.c_str());
reader->Update();
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
mapper->SetInputConnection(reader->GetOutputPort());
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderer->AddActor(actor);
renderer->SetBackground(1, 1, 1);
renderWindow->Render();
renderWindowInteractor->Start();
What should I do to make it appear as the original. I don't know if the problem is with the file writing or reading. Any help would be appreciated.
Thanks.

When you load, make sure of the following:
You have a visualization pipeline similar than the one you initially created. (Contour filter and similar Look Up Table)
The scalars are loaded (you may know this using the PrintSelf Method of the reader's output: reader->GetDataObject(0)->PrintSelf()). Check out the scalars have same elements as before saving.

Related

QVTKOpenGLWidget doesn't respond to signal, while other widgets in the same .ui do respond to it

I am trying to draw a cylinder in a QVTKOpenGLWidget. I use Qt Creator, with qt version 5.12.0 (msvc2017_64). The QVTKOpenGLWidget is promoted from QWidget, and I use QVTKOpenGLWidget.h in the VTK include folder.
When I create cylinder, renderer, vtkGenericOpenGLRenderWindow etc in constructor like most of examples available, nothing goes wrong, the cylinder is shown in the QVTKOpenGLWidget. The code is like below:
mainui::mainui(QWidget *parent) : QMainWindow(parent), ui(new Ui::mainui)
{
ui->setupUi(this);
auto cylinderSource = vtkSmartPointer<vtkCylinderSource>::New();
cylinderSource->SetCenter(0, 0, 0);
cylinderSource->SetRadius(5.0);
cylinderSource->SetHeight(7.0);
cylinderSource->SetResolution(100);
auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(cylinderSource->GetOutputPort());
auto actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
auto renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
auto win = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
win->AddRenderer(renderer);
ui->display3d->SetRenderWindow(win);
}
In this condition, the result is like below:
However when I add an action with function "triggered()" as a signal, add VTK-related code in a function and add that function as a slot function, and connect them, the QVTKOpenGLWidget seems not working (totally black, no cylinder). But other widgets seems working well. The code is like below:
void mainui::paint() {
ui->textEdit->append("Hello vtk!");
auto cylinderSource = vtkSmartPointer<vtkCylinderSource>::New();
cylinderSource->SetCenter(0, 0, 0);
cylinderSource->SetRadius(5.0);
cylinderSource->SetHeight(7.0);
cylinderSource->SetResolution(100);
auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(cylinderSource->GetOutputPort());
auto actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
auto renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
auto win = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
win->AddRenderer(renderer);
ui->display3d->SetRenderWindow(win);
ui->textEdit->append("textEdit respond to trigger signal");
}
The constructor:
mainui::mainui(QWidget *parent) : QMainWindow(parent), ui(new Ui::mainui)
{
ui->setupUi(this);
}
The connector:
And run result:
I've noticed that your cylinder is drawn when you interact with the QVTKOpenGLWidget (after action_open is triggered, you move the 3D display and the cylinder will appear). This is because the QVTKOpenGLWidget is not updated when you create your renderers, windows and so on. So you need to add ui->display3d->update(); before exiting void mainui::paint() function to force an update on the display3d widget:
void mainui::paint()
{
ui->textEdit->append("Nope");
auto cylinderSource = vtkSmartPointer<vtkCylinderSource>::New();
cylinderSource->SetCenter(0, 0, 0);
cylinderSource->SetRadius(5.0);
cylinderSource->SetHeight(7.0);
cylinderSource->SetResolution(100);
auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(cylinderSource->GetOutputPort());
auto actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
auto renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
auto win = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
win->AddRenderer(renderer);
ui->display3d->SetRenderWindow(win);
ui->display3d->update();//This is the new line
}
You do not need to manually call QWidget::update() manully when you create your cylinder in the constructor because the widget is drawn after the constructor.
Here you can see it working:
Note: I learned this in the pcl tutorial: Create a PCL visualizer in Qt with cmake.

Importing an Obj File into vtk

I'm using vtk and I want to visualise an objFile but i don't know how to do it
I think I should use ReadObj.cxx but where should I put the name of my ObjFile.
int main(int argc, char* argv[])
{
// Parse command line arguments
if(argc != 2)
{
std::cout << "Usage: " << argv[0] << " Filename(.obj)" << std::endl;
return EXIT_FAILURE;
}
std::string filename = argv[1];
vtkSmartPointer<vtkOBJReader> reader =
vtkSmartPointer<vtkOBJReader>::New();
reader->SetFileName(filename.c_str());
reader->Update();
// Visualize
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(reader->GetOutputPort());
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
renderer->SetBackground(.3, .6, .3); // Background color green
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
can anyone help me ? Thanks.
Is your file a valid .obj? Can you import it into blender or unity or 3dsmax to validate it?
You didn't set the color. In the hello world example ( Hello World ) a polydata, just like your file, is shown and it's color is set.
Also, you didn't reset the camera after adding your actor, so the camera is in an incorrect position. The hello world exemple also shows how to do reset the camera.
You could just connect your obj loader's output to the vtkPolyDataMapper in the hello world example and it should just work.
Not sure what your question is.
Your code is correct and the name of your ObjFile is filename. You should specify it when you run your program as command line :
ReadObj.exe myobjfile.obj

How to use vtkImplicitPlaneWidget2 in Qt

I have trouble while combining Qt with vtkImplicitPlaneWidget2 then.
Without Qt, I could have the result shown like this.
Without Qt
But with Qt, I could not display the basic function of vtkImplicitPlaneWidget2, or in other words, it only shows the volume data, but the clipper of the plane could not be shown, just like the picture below.
With Qt
I try to find the result, and it seems that the callback function is never called in Qt. I think it is because that I don't connect the Qt event to the callback function, but I don't know how to deal with this.
And the following is the code.
void planeWidgetPara::showLabelPlane()
{
this->setupUi(this);
#pragma region image_process
vtkSmartPointer<vtkImageData> imageData =
vtkSmartPointer<vtkImageData>::New();
imageData->SetExtent(0, dims[0] / scaledown - 1,
0, dims[1] / scaledown - 1,
0, dims[2]);
imageData->SetSpacing(this->getSpacing());
imageData->AllocateScalars(VTK_UNSIGNED_CHAR, 3);
int scaledown = this->getScaledown();
for (int i = 0;i < dims[0] / scaledown;i++)
{
for (int j = 0;j < dims[1] / scaledown;j++)
{
for (int k = 0;k < dims[2];k++)
{
imageData->SetScalarComponentFromDouble(i, j, k, 0, getLabelScaledownColor(i, j, k, 0, scaledown));
imageData->SetScalarComponentFromDouble(i, j, k, 1, getLabelScaledownColor(i, j, k, 1, scaledown));
imageData->SetScalarComponentFromDouble(i, j, k, 2, getLabelScaledownColor(i, j, k, 2, scaledown));
}
}
}
vtkSmartPointer<vtkImageDataGeometryFilter> imageDataGeometryFilter =
vtkSmartPointer<vtkImageDataGeometryFilter>::New();
imageDataGeometryFilter->SetInputData(imageData);
imageDataGeometryFilter->Update();
// Setup a visualization pipeline
vtkSmartPointer<vtkPlane> plane =
vtkSmartPointer<vtkPlane>::New();
plane->SetOrigin(this->getRawOrigin());
vtkSmartPointer<vtkClipPolyData> clipper =
vtkSmartPointer<vtkClipPolyData>::New();
clipper->SetClipFunction(plane);
clipper->InsideOutOn();
clipper->SetInputConnection(imageDataGeometryFilter->GetOutputPort());
// Create a mapper and actor
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(clipper->GetOutputPort());
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
vtkSmartPointer<vtkProperty> backFaces =
vtkSmartPointer<vtkProperty>::New();
backFaces->SetDiffuseColor(.8, .8, .4);
actor->SetBackfaceProperty(backFaces);
#pragma endregion
// A renderer and render window
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow =
this->qvtkWidget->GetRenderWindow();
renderWindow->AddRenderer(renderer);
renderer->AddActor(actor);
//// An interactor
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
this->qvtkWidget->GetRenderWindow()->GetInteractor();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindow->Render();
// The callback will do the work
vtkSmartPointer<vtkIPWCallback> myCallback =
vtkSmartPointer<vtkIPWCallback>::New();
myCallback->Plane = plane;
myCallback->Actor = actor;
vtkSmartPointer<vtkImplicitPlaneRepresentation> rep =
vtkSmartPointer<vtkImplicitPlaneRepresentation>::New();
rep->SetPlaceFactor(1.25); // This must be set prior to placing the widget
rep->PlaceWidget(actor->GetBounds());
rep->SetNormal(plane->GetNormal());
vtkSmartPointer<vtkImplicitPlaneWidget2> planeWidget =
vtkSmartPointer<vtkImplicitPlaneWidget2>::New();
planeWidget->SetInteractor(renderWindowInteractor);
planeWidget->SetRepresentation(rep);
planeWidget->AddObserver(vtkCommand::InteractionEvent, myCallback);
// Render
renderWindowInteractor->Initialize();
renderWindow->Render();
planeWidget->On();
// Begin mouse interaction
//renderWindowInteractor->Start();
// VTK/Qt wedded
this->qvtkWidget->GetRenderWindow()->AddRenderer(renderer);
// Set up action signals and slots
connect(this->actionExit, SIGNAL(triggered()), this, SLOT(slotExit()));
}

How to close VTKRenderWindow automatically

I am using some simple code to render a mesh in a loop. In practice on each iteration I will change the viewpoint and save an image of the rendering. I have reduced this to a small compilable example below:
int main(int argc, char **argv) {
vtkSmartPointer<vtkPLYReader> fileReader = vtkSmartPointer<vtkPLYReader>::New();
fileReader->SetFileName("benchvise_mesh.ply");
fileReader->Update();
vtkSmartPointer<vtkPolyData> polydata_ = fileReader->GetOutput();
vtkSmartPointer<vtkRenderWindow> render_win = vtkSmartPointer<vtkRenderWindow>::New();
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkActor> actor_view = vtkSmartPointer<vtkActor>::New();
vtkSmartPointer<vtkCamera> cam = vtkSmartPointer<vtkCamera>::New();
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
for (int i = 0; i < 100; i++) {
mapper->SetInput(polydata_);
mapper->Update();
cam->SetViewAngle(58);
cam->SetClippingRange(0.00001, 10000);
//Invert view Up
cam->SetViewUp(0, -1, 0);
cam->SetPosition(0, 0, -500);
cam->SetFocalPoint(0, 0, 1);
cam->Modified();
actor_view->SetMapper(mapper);
actor_view->Modified();
renderer->SetActiveCamera(cam);
renderer->AddActor(actor_view);
renderer->SetBackground(1.0, 1.0, 1.0);
renderer->Modified();
render_win->AddRenderer(renderer);
render_win->SetSize(640, 480);
//white
render_win->Modified();
render_win->Start();
render_win->Render();
render_win->Finalize();
}
}
The problem is, when I run this many vtkWindow icons appear on my taskbar and eventually bring the pc to a halt. It appears as though on each loop the rendering window stays alive. However, when I click on an icon the window doesn't actually appear.
Is there something I am missing that will clean up the render windows on each iteration.
BTW, I am running under Ubntu with vtk 5.8
You do several things 'wrong' there. Remove everything wrong the loop, most importantly render_win->Start(), initialize at begin and just call render_win->Render() at each loop after the appreciated modifications to viewing has been made ( calls to mappers or cameras SetPosition and similars affect your view without reconnection, reconnection being call to Add????() -methods). Modified() calls should be implicit and not required manually.

VTK: visualize depth buffer

I am trying to follow the example here: http://www.vtk.org/Wiki/VTK/Examples/Cxx/Utilities/ZBuffer to visualize the zbuffer. This works fine until I try to change the camera viewpoint.
My code is as follows: which is the same as the example except for the bit in bold:
// This demo creates depth map for a polydata instance by extracting
// exact ZBuffer values.
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkBMPWriter.h>
#include <vtkWindowToImageFilter.h>
#include <vtkImageShiftScale.h>
int main(int argc, char *argv[]) {
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();
vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkPLYReader> fileReader = vtkSmartPointer<vtkPLYReader>::New();
vtkSmartPointer<vtkWindowToImageFilter> filter = vtkSmartPointer<vtkWindowToImageFilter>::New();
vtkSmartPointer<vtkBMPWriter> imageWriter = vtkSmartPointer<vtkBMPWriter>::New();
vtkSmartPointer<vtkImageShiftScale> scale = vtkSmartPointer<vtkImageShiftScale>::New();
// Read .vtp file
fileReader->SetFileName("mesh.ply");
//Build visualization enviroment
mapper->SetInputConnection(fileReader->GetOutputPort());
actor->SetMapper(mapper);
renderer->AddActor(actor);
//change camera viewpoint
vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();
camera->SetPosition(0, 0, 650);
renderer->SetActiveCamera(camera);
renWin->AddRenderer(renderer);
interactor->SetRenderWindow(renWin);
renWin->Render();
// Create Depth Map
filter->SetInput(renWin);
filter->SetMagnification(1);
filter->SetInputBufferTypeToZBuffer(); //Extract z buffer value
scale->SetOutputScalarTypeToUnsignedChar();
scale->SetInputConnection(filter->GetOutputPort());
scale->SetShift(0);
scale->SetScale(-255);
// Write depth map as a .bmp image
imageWriter->SetFileName("out2.bmp");
imageWriter->SetInputConnection(scale->GetOutputPort());
imageWriter->Write();
return EXIT_SUCCESS;
}
Now the entire depth visualization is completely black. However, at this camera position the mesh renders just fine, so I don't think it's due to camera being too far away. Any ideas what I am doing wrong?
That probably because your far plane is near the object that is being rendered. Try to put, after camera creation, a better clip plane, as example:
camera->SetClippingRange(640, 1000);