vtk example from vtk book does not work with 9.1 - c++

In the VTK book at page 63 there is an example which I pasted below.
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkConeSource.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
int main(int, char* [])
{
vtkNew<vtkNamedColors> colors;
vtkNew<vtkConeSource> cone;
cone->SetHeight(3.0);
cone->SetRadius(1.0);
cone->SetResolution(10);
vtkNew<vtkPolyDataMapper> coneMapper;
coneMapper->SetInputConnection(cone->GetOutputPort());
vtkNew <vtkActor> coneActor;
coneActor->SetMapper(coneMapper);
vtkNew <vtkRenderer > ren1;
ren1->AddActor(coneActor);
ren1->SetBackground(
colors->GetColor3d("MidnightBlue").GetData());
vtkNew <vtkRenderWindow > renWin;
renWin->AddRenderer(ren1);
renWin->SetSize(300, 300);
for (auto i = 0; i < 360; ++i)
{
// render the image
renWin->Render();
// rotate the active camera by one degree
ren1->GetActiveCamera()->Azimuth(1);
}
return EXIT_SUCCESS;
}
I have downloaded and compiled VTK 9.1 on my Windows 10 machine. I tried to run the example as it is and it crashes on the following line:
ren1->SetBackground(
colors->GetColor3d("MidnightBlue").GetData());
The culprit is actually the call to colors->GetColor3d("MidnightBlue").GetData(). Since I do not care what color the background is at this very early point, I replaced the crashing line with
ren1->SetBackground(0.20, 0.20, 0.20);
Now it runs to the end, but no window shows up. My expectation was that a window would pop up with a rotating cone inside. No such luck. Can anybody point me in the right direction? What am I doing wrong?

Related

How to correctly use VTK ConstrainedDelaunay2D?

I've started from the VTK ConstrainedDelaunay2D example and added my own points:
#include <vtkSmartPointer.h>
#include <vtkDelaunay2D.h>
#include <vtkCellArray.h>
#include <vtkProperty.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolygon.h>
#include <vtkMath.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkNamedColors.h>
#include <vtkVersionMacros.h> // For version macros
int main(int, char *[])
{
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
int ptsHeight = 400;
std::vector<std::vector<int>> pts{ {166, 127},{103, 220},{166, 190},{174, 291},{189, 226},{227, 282},{213, 187},{242, 105},{196, 131},{182, 83} };
for (size_t i = 0; i < pts.size(); i++)
{
// !important: flip y
int x = pts[i][0];
int y = ptsHeight - pts[i][1];
points->InsertNextPoint(x, y, 0);
}
vtkSmartPointer<vtkPolyData> aPolyData = vtkSmartPointer<vtkPolyData>::New();
aPolyData->SetPoints(points);
// Create a cell array to store the polygon in
vtkSmartPointer<vtkCellArray> aCellArray = vtkSmartPointer<vtkCellArray>::New();
// Define a polygonal hole with a clockwise polygon
vtkSmartPointer<vtkPolygon> aPolygon = vtkSmartPointer<vtkPolygon>::New();
for (unsigned int i = 0; i < pts.size(); i++)
{
aPolygon->GetPointIds()->InsertNextId(i);
}
aCellArray->InsertNextCell(aPolygon);
// Create a polydata to store the boundary. The points must be the
// same as the points we will triangulate.
vtkSmartPointer<vtkPolyData> boundary =
vtkSmartPointer<vtkPolyData>::New();
boundary->SetPoints(aPolyData->GetPoints());
boundary->SetPolys(aCellArray);
// Triangulate the grid points
vtkSmartPointer<vtkDelaunay2D> delaunay =
vtkSmartPointer<vtkDelaunay2D>::New();
delaunay->SetInputData(aPolyData);
delaunay->SetSourceData(boundary);
// Visualize
vtkSmartPointer<vtkPolyDataMapper> meshMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
meshMapper->SetInputConnection(delaunay->GetOutputPort());
vtkSmartPointer<vtkNamedColors> colors =
vtkSmartPointer<vtkNamedColors>::New();
vtkSmartPointer<vtkActor> meshActor =
vtkSmartPointer<vtkActor>::New();
meshActor->SetMapper(meshMapper);
meshActor->GetProperty()->EdgeVisibilityOn();
meshActor->GetProperty()->SetEdgeColor(colors->GetColor3d("Peacock").GetData());
meshActor->GetProperty()->SetInterpolationToFlat();
meshActor->GetProperty()->SetBackfaceCulling(true);
// Create a renderer, render window, and interactor
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
// Add the actor to the scene
renderer->AddActor(meshActor);
//renderer->AddActor(boundaryActor);
renderer->SetBackground(colors->GetColor3d("Mint").GetData());
// Render and interact
renderWindow->SetSize(640, 480);
renderWindow->Render();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
I'm experiencing two issues:
I get different results if I flip the Y coordinates: why is that ?
Why are there faces pointing in the wrong direction (flipped normal / wrong winding )?
Here's what I mean by the 1st issue:
If I don't flip the Y coordinates I get this:
I get the same effect if I don't flip the Y axis but insert the boundary polygon in reverse order:
for (unsigned int i = 0; i < pts.size(); i++)
{
aPolygon->GetPointIds()->InsertNextId(pts.size() - 1 - i);
}
I don't think I fully understand how the boundary/constraint works.
I thoght that the same points should produce the same triangulation wether the vertices are flipped vertically or not. (I suspect the order of indices changes then ?)
Regarding the second issue (unpredictable flipped faces) I'm not sure what the best way forward is. I had a look at the vtkDelaunay2D class and couldn't find anything related.
(I've tried setting projection plane mode to VTK_DELAUNAY_XY_PLANE, but it didn't seem to affect the output)
I've also tried to use vtkPolyDataNormals but got no output:
vtkSmartPointer<vtkPolyDataNormals> normalGenerator = vtkSmartPointer<vtkPolyDataNormals>::New();
normalGenerator->SetInputData(delaunay->GetOutput());
normalGenerator->ComputePointNormalsOff();
normalGenerator->ComputeCellNormalsOn();
normalGenerator->FlipNormalsOn();
normalGenerator->Update();
(normalGenerator's output has 0 cells and points)
Is there a way to compute constrained delaunay triangulation for a list of 2d points and ensure all the faces point the same way ? (If so, how ? Would it be possible to do this with the vtkDelaunay2D class alone or is it necessary to use other filters?)
Any hints/tips are more than welcome :)
I'm using VTK 8.2 by the way.
the flipping in y effectively reverses the faces orientation (what is clockwise becomes anti-clockwise, like in a mirror).
I'm not sure I can reproduce your example above. A quick test in python seems to give the expected behavior, maybe you can start from this and map it to your c++ version:
import vedo
pts = [
[166, 127],
[103, 220],
[166, 190],
[174, 291],
[189, 226],
[227, 282],
[213, 187],
[242, 105],
[196, 131],
[182, 83],
]
ids = [[2,4,6], [0,2,8]] # faces to erase by pt-index (clockwise)
dly = vedo.delaunay2D(pts, mode='xy', boundaries=ids)
dly.c('grey5').lc('red4').lw(2)
labels = vedo.Points(pts).labels('id').z(1)
vedo.show(labels, dly, axes=1)

Shrink/Expand the outline of a polygon with holes

I want to expand/shrink a polygon with holes using boost::polygon. So to clarify that a bit, I have a single data structure
boost::polygon::polygon_with_holes_data<int> inPoly
where inPoly contains data that describe a rectangular outline and a triangle which forms the hole within this rectangle (in picture below this is the left, black drawing).
Now I want to
a) expand the whole stuff so that the rectangle becomes bigger and the hole becomes smaller (resulting in the red polygon in image below) or
b) shrink it so that the rectangle becomes smaller and the hole bigger (resulting in the green image below).
The corners don't necessarily need to be straight, the also can be rounded or somehow "rough".
My question: how can this be done using boost::polygon?
Thanks!
I answered this Expand polygons with boost::geometry?
And yes you can teach Boost Geometry to act on Boost Polygon types:
#include <boost/geometry/geometries/adapted/boost_polygon.hpp>
I came up with a test polygon like you described:
boost::polygon::polygon_with_holes_data<int> inPoly;
bg::read_wkt("POLYGON ((0 0,0 1000,1000 1000,1000 0,0 0),(100 100,900 100,500 700,100 100))", inPoly);
Now, apparently we can't just buffer on the adapted polygon, nor can we bg::assign or bg::convert directly. So, I came up with an ugly workaround of converting to WKT and back. And then you can do the buffer, and conver back similarly.
It's not very elegant, but it does work:
poly in;
bg::read_wkt(boost::lexical_cast<std::string>(bg::wkt(inPoly)), in);
Full Demo
Include SVG output:
Live On Coliru
#include <boost/polygon/polygon.hpp>
#include <boost/polygon/polygon_set_data.hpp>
#include <boost/polygon/polygon_with_holes_data.hpp>
#include <boost/geometry.hpp>
#include <boost/geometry/strategies/buffer.hpp>
#include <boost/geometry/algorithms/buffer.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/geometry/geometries/multi_polygon.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/adapted/boost_polygon.hpp>
#include <fstream>
namespace bp = boost::polygon;
namespace bg = boost::geometry;
using P = bp::polygon_with_holes_data<int>;
using PS = bp::polygon_set_data<int>;
using coordinate_type = bg::coordinate_type<P>::type;
int main() {
P inPoly, grow, shrink;
bg::read_wkt("POLYGON ((0 0,0 1000,1000 1000,1000 0,0 0),(100 100,900 100,500 700,100 100))", inPoly);
{
// define our boost geometry types
namespace bs = bg::strategy::buffer;
namespace bgm = bg::model;
using pt = bgm::d2::point_xy<coordinate_type>;
using poly = bgm::polygon<pt>;
using mpoly = bgm::multi_polygon<poly>;
// define our buffering strategies
using dist = bs::distance_symmetric<coordinate_type>;
bs::side_straight side_strategy;
const int points_per_circle = 12;
bs::join_round join_strategy(points_per_circle);
bs::end_round end_strategy(points_per_circle);
bs::point_circle point_strategy(points_per_circle);
poly in;
bg::read_wkt(boost::lexical_cast<std::string>(bg::wkt(inPoly)), in);
for (auto [offset, output_p] : { std::tuple(+15, &grow), std::tuple(-15, &shrink) }) {
mpoly out;
bg::buffer(in, out, dist(offset), side_strategy, join_strategy, end_strategy, point_strategy);
assert(out.size() == 1);
bg::read_wkt(boost::lexical_cast<std::string>(bg::wkt(out.front())), *output_p);
}
}
{
std::ofstream svg("output.svg");
using pt = bg::model::d2::point_xy<coordinate_type>;
boost::geometry::svg_mapper<pt> mapper(svg, 400, 400);
mapper.add(inPoly);
mapper.add(grow);
mapper.add(shrink);
mapper.map(inPoly, "fill-opacity:0.3;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:2");
mapper.map(grow, "fill-opacity:0.05;fill:rgb(255,0,0);stroke:rgb(255,0,0);stroke-width:2");
mapper.map(shrink, "fill-opacity:0.05;fill:rgb(0,0,255);stroke:rgb(0,0,255);stroke-width:2");
}
}
The output.svg written:
More or less accidentally I found boost::polygon also provides a single function for that which is quite easy to use: boost::polygon::polygon_set_data offers a function resize() which is doing exactly what is described above. Using the additional, parameters corner_fill_arc and num_segments rounded corners can be created.
No idea why this function is located in boost::polygon::polygon_set_data and not in boost::polygon::polygon_with_holes_data which in my opinion would be the more logically place for such a function...

QRenderPassFilter hides plane mesh even if QFilterKey matches

We are aiming to replace our previous 3D Engine with Qt3D. As a last obstacle we need to correctly implement a pixel correct transparency. We are now trying to implement depth peeling as a possible approach to make pixel correct transparency workable. For this algorithm one has to do perform a deferred (multipass) rendering, which can be achieved with QRenderPassFilter and QFilterKey inside an effect.
Now, I already had big problems to make the combination of QRenderPassFilter and QFilterKey together with the material QDiffuseSpecularMaterial going to work correctly. Even if there is just one pass.
This is my source code:
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QFrame>
#include <Qt3DCore/QTransform>
#include <Qt3DRender/QSortPolicy>
#include <Qt3DRender/QRenderSettings>
#include <Qt3DRender/QRenderSurfaceSelector>
#include <Qt3DRender/QViewport>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QCameraSelector>
#include <Qt3DRender/QClearBuffers>
#include <Qt3DRender/QDirectionalLight>
#include <Qt3DRender/QTexture>
#include <Qt3DExtras/QPlaneMesh>
#include <Qt3DExtras/QDiffuseSpecularMaterial>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DRender/QFilterKey>
#include <Qt3DRender/QParameter>
#include <Qt3DRender/QRenderPass>
#include <Qt3DRender/QRenderPassFilter>
#include <Qt3DRender/QTechnique>
#include <QDebug>
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
auto view = new Qt3DExtras::Qt3DWindow();
auto mClearBuffers = new Qt3DRender::QClearBuffers;
auto mMainCameraSelector = new Qt3DRender::QCameraSelector;
mMainCameraSelector->setCamera(view->camera());
auto mRenderSurfaceSelector = new Qt3DRender::QRenderSurfaceSelector;
auto mMainViewport = new Qt3DRender::QViewport;
auto renderPassFilter = new Qt3DRender::QRenderPassFilter;
{
auto filterKey = new Qt3DRender::QFilterKey(renderPassFilter);
filterKey->setName(QStringLiteral("renderingStyle"));
filterKey->setValue(QStringLiteral("forward"));
// Adding the filterKey to the renderPassFilter hides the plane
// Name and Value of filterKey matches the FilterKey inside the QDiffuseSpecularMaterial
renderPassFilter->addMatch(filterKey); // Removing this lines shows the plane mesh
mClearBuffers->setClearColor(Qt::lightGray);
mClearBuffers->setBuffers(Qt3DRender::QClearBuffers::BufferType::ColorDepthBuffer);
mMainCameraSelector->setParent(mClearBuffers);
mClearBuffers->setParent(renderPassFilter);
}
renderPassFilter->setParent(mRenderSurfaceSelector);
mRenderSurfaceSelector->setParent(mMainViewport);
view->setActiveFrameGraph(mMainViewport);
view->activeFrameGraph()->dumpObjectTree();
auto rootEntity = new Qt3DCore::QEntity();
view->setRootEntity(rootEntity);
view->camera()->lens()->setPerspectiveProjection(45.0f, 1., 0.1f, 10000.0f);
view->camera()->setPosition(QVector3D(0, 2, 0));
view->camera()->setUpVector(QVector3D(0, 1, 0));
view->camera()->setViewCenter(QVector3D(0, 0, 0));
auto planeEntity = new Qt3DCore::QEntity(rootEntity);
auto meshMaterial = new Qt3DExtras::QDiffuseSpecularMaterial;
meshMaterial->setDiffuse(QColor("#ff00ff"));
planeEntity->addComponent(meshMaterial);
auto mesh = new Qt3DExtras::QPlaneMesh;
mesh->setWidth(0.3);
mesh->setHeight(0.3);
planeEntity->addComponent(mesh);
auto container = QWidget::createWindowContainer(view);
QFrame frame;
frame.setLayout(new QVBoxLayout);
frame.layout()->addWidget(container);
frame.resize(QSize(400, 300));
frame.show();
return a.exec();
}
The console outputs my framegraph as:
Qt3DRender::QViewport::
Qt3DRender::QRenderSurfaceSelector::
Qt3DRender::QRenderPassFilter::
Qt3DRender::QFilterKey::
Qt3DRender::QClearBuffers::
Qt3DRender::QCameraSelector::
Now, if I remove the line
renderPassFilter->addMatch(filterKey);
everything works as expected and I see my simple plane mesh.
However, adding the line, which should not filter anything the plane mesh is no longer displayed.
I'm really running out of ideas, what I'm possibly doing wrong here. How, can I make my small program with my renderPassFilter going to work and what are my errors?
I also didn't really understood, what are purposes of the settings name and value in the QFilterKey, which of both is necessary to filter out certain effects?
After carefully studying my application and particularly the QDiffuseSpecularMaterial I figured out, that the QFilterKey inside the QDiffuseSpecularMaterial is not added to the QRenderPass Object, but moreover added to the QTechnique, which I found rather obscure.
Now, adding a QTechniqueFilter instead of a QRenderPassFilter made the program working as expected. Changing the string forward to something different e.g. xxx hides the plane as expected.
Adding the line
meshMaterial->dumpObjectTree();
indeed gave me the clue
Qt3DExtras::QDiffuseSpecularMaterial::
Qt3DRender::QShaderProgramBuilder::
Qt3DRender::QShaderProgram::
Qt3DRender::QShaderProgramBuilder::
Qt3DRender::QShaderProgram::
Qt3DRender::QFilterKey::
Qt3DRender::QEffect::
Qt3DRender::QTechnique::
Qt3DRender::QRenderPass::
Qt3DRender::QNoDepthMask::
Qt3DRender::QBlendEquationArguments::
Qt3DRender::QBlendEquation::
Qt3DRender::QTechnique::
Qt3DRender::QRenderPass::
Qt3DRender::QTechnique::
Qt3DRender::QRenderPass::
Qt3DRender::QParameter::
Qt3DRender::QParameter::
Qt3DRender::QParameter::
Qt3DRender::QParameter::
Qt3DRender::QParameter::
So dumpObjectTree() seems to a good of the shelf debugging tool, when dealing with Qt3D and Qt in general.
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QFrame>
#include <Qt3DCore/QTransform>
#include <Qt3DRender/QSortPolicy>
#include <Qt3DRender/QRenderSettings>
#include <Qt3DRender/QRenderSurfaceSelector>
#include <Qt3DRender/QViewport>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QCameraSelector>
#include <Qt3DRender/QClearBuffers>
#include <Qt3DRender/QTechniqueFilter>
#include <Qt3DRender/QDirectionalLight>
#include <Qt3DRender/QTexture>
#include <Qt3DExtras/QPlaneMesh>
#include <Qt3DExtras/QDiffuseSpecularMaterial>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DRender/QFilterKey>
#include <Qt3DRender/QParameter>
#include <Qt3DRender/QRenderPass>
#include <Qt3DRender/QRenderPassFilter>
#include <Qt3DRender/QTechnique>
#include <QDebug>
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
auto view = new Qt3DExtras::Qt3DWindow();
auto mClearBuffers = new Qt3DRender::QClearBuffers;
auto mMainCameraSelector = new Qt3DRender::QCameraSelector;
mMainCameraSelector->setCamera(view->camera());
auto mRenderSurfaceSelector = new Qt3DRender::QRenderSurfaceSelector;
auto mMainViewport = new Qt3DRender::QViewport;
auto renderPassFilter = new Qt3DRender::QTechniqueFilter;
{
auto filterKey = new Qt3DRender::QFilterKey(renderPassFilter);
filterKey->setName(QStringLiteral("renderingStyle"));
filterKey->setValue(QStringLiteral("forward"));
// Adding the filterKey to the renderPassFilter hides the plane
// Name and Value of filterKey matches the FilterKey inside the QDiffuseSpecularMaterial
renderPassFilter->addMatch(filterKey); // Removing this lines shows the plane mesh
mClearBuffers->setClearColor(Qt::lightGray);
mClearBuffers->setBuffers(Qt3DRender::QClearBuffers::BufferType::ColorDepthBuffer);
mMainCameraSelector->setParent(mClearBuffers);
mClearBuffers->setParent(renderPassFilter);
}
renderPassFilter->setParent(mRenderSurfaceSelector);
mRenderSurfaceSelector->setParent(mMainViewport);
view->setActiveFrameGraph(mMainViewport);
view->activeFrameGraph()->dumpObjectTree();
auto rootEntity = new Qt3DCore::QEntity();
view->setRootEntity(rootEntity);
view->camera()->lens()->setPerspectiveProjection(45.0f, 1., 0.1f, 10000.0f);
view->camera()->setPosition(QVector3D(0, 2, 0));
view->camera()->setUpVector(QVector3D(0, 1, 0));
view->camera()->setViewCenter(QVector3D(0, 0, 0));
auto planeEntity = new Qt3DCore::QEntity(rootEntity);
auto meshMaterial = new Qt3DExtras::QDiffuseSpecularMaterial;
meshMaterial->setDiffuse(QColor("#ff00ff"));
planeEntity->addComponent(meshMaterial);
auto mesh = new Qt3DExtras::QPlaneMesh;
mesh->setWidth(0.3);
mesh->setHeight(0.3);
planeEntity->addComponent(mesh);
auto container = QWidget::createWindowContainer(view);
QFrame frame;
frame.setLayout(new QVBoxLayout);
frame.layout()->addWidget(container);
frame.resize(QSize(400, 300));
frame.show();
return a.exec();
}

Trying to remove background and make it transparent in c++, using magick++

I am having an image "objects.png" with a red background and I'm trying to make the background transparent. The code is straight forward but somehow I am not able to get the desired result. I am quite new to this ImageMagick business and this is my first program using Magick++. So, it would be great if you can explain things in detail. Thanks in advance. Code goes like this,
#include <iostream>
#include <Magick++.h>
using namespace std;
using namespace Magick;
int main(){
Image my_image("objects.png");
Color bg_color = my_image.pixelColor(0,0);
Color new_bg_color(0, MaxRGB, 0, MaxRGB);
for (int i=0;i<my_image.columns();i++){
for (int j=0;j<my_image.rows();j++){
//cout<<"(i,j) : ("<<i<<","<<j<<")\n";
if (my_image.pixelColor(i,j) == bg_color){
my_image.pixelColor(i,j,new_bg_color);
}
}
}
my_image.write("new_objects.png");
}
Image objects.png is
and I'm getting this as output
I think there is a Magick::Image.transparent method that should handle transparency assignment.
#include <iostream>
#include <Magick++.h>
using namespace std;
using namespace Magick;
int main(){
Image my_image("objects.png");
Color bg_color = my_image.pixelColor(0,0);
my_image.transparent(bg_color);
my_image.write("new_objects.png");
}
Edit
To allow the Magick::Color's opacity to be respected. You need to enable the alpha channel of the image by setting Magick::Image.matte, or Magick::Image.opacity attributes.
#include <iostream>
#include <Magick++.h>
using namespace std;
using namespace Magick;
int main(){
Image my_image("objects.png");
Color bg_color = my_image.pixelColor(0,0);
Color new_bg_color(0, MaxRGB, 0, MaxRGB);
my_image.matte(true); // or my_image.opacity();
for (int i=0;i<my_image.columns();i++){
for (int j=0;j<my_image.rows();j++){
if (my_image.pixelColor(i,j) == bg_color){
my_image.pixelColor(i,j,new_bg_color);
}
}
}
my_image.write("new_objects.png");
}

Segmentation fault when using graph function (vtk 6.1, Qt5.3, Ubuntu)

Update: Debug info
I am working on a Qt 5.3 project and need to plot data in 2D and 3D coordinate systems. I've been looking into vtk 6.1 because it seems very powerful overall and I will also need to visualize image data at a later point. I have using Qvtkwidget smoothly with this example
Qvtkwidget example
#include "mainwindow.h"
#include <QApplication>
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkImageViewer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkRenderer.h>
#include <vtkJPEGReader.h>
#include <QVTKWidget.h>
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QVTKWidget widget;
widget.resize(256,256);
// Setup sphere
vtkSmartPointer<vtkSphereSource> sphereSource =
vtkSmartPointer<vtkSphereSource>::New();
sphereSource->Update();
vtkSmartPointer<vtkPolyDataMapper> sphereMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
sphereMapper->SetInputConnection(sphereSource->GetOutputPort());
vtkSmartPointer<vtkActor> sphereActor =
vtkSmartPointer<vtkActor>::New();
sphereActor->SetMapper(sphereMapper);
// Setup window
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
// Setup renderer
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderWindow->AddRenderer(renderer);
renderer->AddActor(sphereActor);
renderer->ResetCamera();
widget.SetRenderWindow(renderWindow);
widget.show();
app.exec();
return EXIT_SUCCESS;
}
But when I tried to implement the graph example (/Examples/Charts/Cxx/QChartTable.cxx ), the program show Segmentation Fault errors.
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL)
#include "vtkFloatArray.h"
#include "vtkMath.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSmartPointer.h"
#include "vtkContextView.h"
#include "vtkContextScene.h"
#include "vtkChartXY.h"
#include "vtkPlot.h"
#include "vtkTable.h"
#include "vtkTimerLog.h"
#include <QApplication>
#include <QWidget>
#include <QMainWindow>
#include <QHBoxLayout>
#include "QVTKWidget.h"
#include "vtkQtTableView.h"
#define VTK_CREATE(type, name) \
vtkSmartPointer<type> name = vtkSmartPointer<type>::New()
int main(int argc, char** argv)
{
// Qt initialization
QApplication app(argc, argv);
QMainWindow mainWindow;
mainWindow.setGeometry(0, 0, 1150, 600);
// QVTK set up and initialization
QVTKWidget *qvtkWidget = new QVTKWidget(&mainWindow);
// Set up my 2D world...
VTK_CREATE(vtkContextView, view); // This contains a chart object
view->SetInteractor(qvtkWidget->GetInteractor());
qvtkWidget->SetRenderWindow(view->GetRenderWindow());
// Create a table with some points in it...
VTK_CREATE(vtkTable, table);
VTK_CREATE(vtkFloatArray, arrX);
arrX->SetName("X Axis");
table->AddColumn(arrX);
VTK_CREATE(vtkFloatArray, arrC);
arrC->SetName("Cosine");
table->AddColumn(arrC);
VTK_CREATE(vtkFloatArray, arrS);
arrS->SetName("Sine");
table->AddColumn(arrS);
// Make a timer object - need to get some frame rates/render times
VTK_CREATE(vtkTimerLog, timer);
// Test charting with a few more points...
int numPoints = 29;
float inc = 7.0 / (numPoints-1);
table->SetNumberOfRows(numPoints);
for (int i = 0; i < numPoints; ++i)
{
table->SetValue(i, 0, i * inc);
table->SetValue(i, 1, cos(i * inc) + 0.0);
table->SetValue(i, 2, sin(i * inc) + 0.0);
}
// table->Update();
// Add multiple line plots, setting the colors etc
vtkSmartPointer<vtkChartXY> chart = vtkSmartPointer<vtkChartXY>::New();
view->GetScene()->AddItem(chart);
vtkPlot *line = chart->AddPlot(vtkChart::LINE);
line->SetInputData(table, 0, 1);
line->SetColor(255, 0, 0, 255);
line = chart->AddPlot(vtkChart::LINE);
line->SetInputData(table, 0, 2);
line->SetColor(0, 255, 0, 255);
line->SetWidth(2.0);
// Instantiate a vtkQtChart and use that too
/* vtkQtChart *qtChart = new vtkQtChart;
chart = qtChart->chart();
line = chart->AddPlot(vtkChart::LINE);
line->SetTable(table, 0, 1);
line->SetColor(255, 0, 0, 255);
line = chart->AddPlot(vtkChart::LINE);
line->SetTable(table, 0, 2);
line->SetColor(0, 255, 0, 255);
line->SetWidth(2.0);
*/
// Now lets try to add a table view
QWidget *widget = new QWidget(&mainWindow);
QHBoxLayout *layout = new QHBoxLayout(widget);
VTK_CREATE(vtkQtTableView, tableView);
tableView->SetSplitMultiComponentColumns(true);
tableView->AddRepresentationFromInput(table);
tableView->Update();
layout->addWidget(qvtkWidget, 2);
//layout->addWidget(qtChart, 2);
layout->addWidget(tableView->GetWidget());
mainWindow.setCentralWidget(widget);
// Now show the application and start the event loop
mainWindow.show();
return app.exec();
}
I have no idea how this error occurs.
I have recompiled VTK in debug mode and get more debug info. This is the backtrace for this program. In this screenshot show that problem could come form "this" pointer "this" should be vtkTextRenderer * but "this" point to null pointer. I think this could be a bug in VTK 6.1 but have no idea how to fix it.Please give me some suggestion. Thanks
I am newbie and still can not post picture so I upload it to this link
Debug Screenshot
0 vtkTextRenderer::GetBoundingBox vtkTextRenderer.h 136 0x7ffff0fbda58
1 vtkTextRendererStringToImage::GetBounds vtkTextRendererStringToImage.cxx 62 0x7ffff0fbd68b
2 vtkOpenGLContextDevice2D::ComputeStringBounds vtkOpenGLContextDevice2D.cxx 885 0x7ffff650d338
3 vtkOpenGLContextDevice2D::ComputeStringBounds vtkOpenGLContextDevice2D.cxx 809 0x7ffff650cab4
4 vtkContext2D::ComputeStringBounds vtkContext2D.cxx 619 0x7ffff64f24dd
5 vtkAxis::GetBoundingRect vtkAxis.cxx 871 0x7ffff7a9d66d
6 vtkChartXY::UpdateLayout vtkChartXY.cxx 762 0x7ffff7ac6064
7 vtkChartXY::Paint vtkChartXY.cxx 325 0x7ffff7ac4450
8 vtkContextScenePrivate::PaintItems vtkContextScenePrivate.h 80 0x7ffff64ea83a
9 vtkContextScene::Paint vtkContextScene.cxx 120 0x7ffff64fc2f2
10 vtkContextActor::RenderOverlay vtkContextActor.cxx 239 0x7ffff64f5787
11 vtkRenderer::UpdateGeometry vtkRenderer.cxx 585 0x7ffff3518bc3
12 vtkOpenGLRenderer::DeviceRender vtkOpenGLRenderer.cxx 270 0x7ffff61102c0
13 vtkRenderer::Render vtkRenderer.cxx 292 0x7ffff3517dfb
14 vtkRendererCollection::Render vtkRendererCollection.cxx 51 0x7ffff35164d3
15 vtkRenderWindow::DoStereoRender vtkRenderWindow.cxx 759 0x7ffff352bc36
16 vtkRenderWindow::DoFDRender vtkRenderWindow.cxx 728 0x7ffff352bb46
17 vtkRenderWindow::DoAARender vtkRenderWindow.cxx 607 0x7ffff352b4f2
18 vtkRenderWindow::Render vtkRenderWindow.cxx 423 0x7ffff352aac2
19 vtkXOpenGLRenderWindow::Render vtkXOpenGLRenderWindow.cxx 1831 0x7ffff61abc51
20 vtkRenderWindowInteractor::Render vtkRenderWindowInteractor.cxx 168 0x7ffff3537751
... <More>
It is NOT a bug. The object vtkTextRenderer point to null bescause the Text Font module has NOT been implemented. It should been implemented using vtkRenderingFreeType.
Please try including this snippet in your code:
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingFreeType);
more detail information can be found here: http://www.vtk.org/Wiki/VTK/VTK_6_Migration/Factories_now_require_defines
I have recompiled VTK in debug mode and get more debug info. This is the backtrace for this program. In this screenshot show that problem could come form "this" pointer "this" should be vtkTextRenderer * but "this" point to null pointer. I think this could be a bug in VTK 6.1 but have no idea how to fix it.Please give me some suggestion. Thanks
Update Debug Info in first post.