Recently I am working on a project which involves working on 3D Object files. I have to used VTK and C++ for the code. I used the code available from tutorials of VTK for importing a 3d Object File, but after building the solution I am not able to open the ReadObj.exe file.
Following is the code:-
#include <vtkSmartPointer.h>
#include <vtkOBJReader.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkCamera.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkNamedColors.h>
#include <string>
int main(int argc, char* argv[])
{
// Parse command line arguments
if(argc != 2)
{
std::cout << "Usage: " << argv[0] << "Filename(.obj) e.g trumpet.obj " << std::endl;
return EXIT_FAILURE;
}
std::string filename = "Data/elephanm.obj";
vtkSmartPointer<vtkOBJReader> reader =
vtkSmartPointer<vtkOBJReader>::New();
reader->SetFileName(filename.c_str());
reader->Update();
// Visualize
vtkSmartPointer<vtkNamedColors> colors =
vtkSmartPointer<vtkNamedColors>::New();
vtkColor3d backgroundColor = colors->GetColor3d("SpringGreen");
vtkColor3d actorColor = colors->GetColor3d("HoneyDew");
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(reader->GetOutputPort());
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->GetProperty()->SetDiffuseColor(actorColor.GetData());
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
renderer->SetBackground(backgroundColor.GetData());
renderer->ResetCamera();
renderer->GetActiveCamera()->Azimuth(30);
renderer->GetActiveCamera()->Elevation(30);
renderer->GetActiveCamera()->Dolly(1.5);
renderer->ResetCameraClippingRange();
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindow->SetSize(640, 480);
renderWindow->Render();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
Also, Build is successful in Visual Studio and ReadObj.exe gets created. But the exe file does not open and does not show the result
Can anyone help me to fix this?
Related
I'm having a lot of issues to have a simple working app that load a light mesh in Qt3D, nothing shows up on screen.
Here's some code I put together to have a have striped down to show.
You'll notice that it's a shorter version of this Qt example
You won't see it in this example but in my actual project I already
tried loading it with
qrc and
localfile QUrl
Qt3DExtras::QTorusMesh work without an issue.
I tried to watch the loading status of the mesh, on my actual project it does go from None though Loading to Loaded
Also, I have no trouble loading the file su.obj using a Qt QML example, so it's
not the file that is corrupted. The file being a simple Suzanne from Blender, exported.
I used Qt5 and 6.
Finally, I know the question has been asked a few times, but nothing helped.
#include <QGuiApplication>
#include <Qt3DCore/QEntity>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QCameraLens>
#include <Qt3DCore/QTransform>
#include <Qt3DCore/QAspectEngine>
#include <Qt3DInput/QInputAspect>
#include <Qt3DRender/QRenderAspect>
#include <Qt3DRender/QGeometryRenderer>
#include <Qt3DExtras/QForwardRenderer>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DExtras/QSphereMesh>
#include <Qt3DExtras/QTorusMesh>
#include <QMesh>
#include <QPropertyAnimation>
#include "orbittransformcontroller.h"
#include "qorbitcameracontroller.h"
#include "qt3dwindow.h"
#include <qdebug.h>
Qt3DCore::QEntity *createScene()
{
// Root entity
Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity;
// Material
Qt3DRender::QMaterial *material = new Qt3DExtras::QPhongMaterial(rootEntity);
// Sphere
Qt3DCore::QEntity *sphereEntity = new Qt3DCore::QEntity(rootEntity);
auto *sphereMesh = new Qt3DRender::QMesh();
sphereMesh->setSource(QUrl::fromLocalFile("su.obj"));
Qt3DCore::QTransform *sphereTransform = new Qt3DCore::QTransform;
OrbitTransformController *controller = new OrbitTransformController(sphereTransform);
controller->setTarget(sphereTransform);
controller->setRadius(20.0f);
QPropertyAnimation *sphereRotateTransformAnimation = new QPropertyAnimation(sphereTransform);
sphereRotateTransformAnimation->setTargetObject(controller);
sphereRotateTransformAnimation->setPropertyName("angle");
sphereRotateTransformAnimation->setStartValue(QVariant::fromValue(0));
sphereRotateTransformAnimation->setEndValue(QVariant::fromValue(360));
sphereRotateTransformAnimation->setDuration(10000);
sphereRotateTransformAnimation->setLoopCount(-1);
sphereRotateTransformAnimation->start();
sphereEntity->addComponent(sphereMesh);
sphereEntity->addComponent(sphereTransform);
sphereEntity->addComponent(material);
return rootEntity;
}
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
Qt3DExtras::Qt3DWindow view;
Qt3DCore::QEntity *scene = createScene();
// Camera
Qt3DRender::QCamera *camera = view.camera();
camera->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 1000.0f);
camera->setPosition(QVector3D(0, 0, 40.0f));
camera->setViewCenter(QVector3D(0, 0, 0));
// For camera controls
Qt3DExtras::QOrbitCameraController *camController = new Qt3DExtras::QOrbitCameraController(scene);
camController->setLinearSpeed( 50.0f );
camController->setLookSpeed( 180.0f );
camController->setCamera(camera);
view.setRootEntity(scene);
view.show();
return app.exec();
}
With the help from #eyllanesc and qDebug, I found how to write it in three ways:
const QUrl url = QUrl( "qrc:/path/copied/from/qtcreator/su.obj");
const QUrl url = QUrl::fromLocalFile( "C:/path/to/folder/su.obj");
const QUrl url = QUrl::fromLocalFile( "su.obj");
qDebug() << QDir::currentPath(); // I used this to make sure I was at the right place
and
sphereMesh->setSource(url);
I use WSL and tried to render a simple image with VTK. I used the following c++ code:
#include <vtkVersion.h>
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkDataSetMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
int main(int, char*[])
{
// Create an image data
vtkSmartPointer<vtkImageData> imageData =
vtkSmartPointer<vtkImageData>::New();
// Specify the size of the image data
imageData->SetDimensions(3,3,2);
imageData->SetSpacing(1.0, 1.0, 1.0);
imageData->SetOrigin(0.0, 0.0, 0.0);
vtkSmartPointer<vtkDataSetMapper> mapper =
vtkSmartPointer<vtkDataSetMapper>::New();
#if VTK_MAJOR_VERSION <= 5
mapper->SetInputConnection(imageData->GetProducerPort());
#else
mapper->SetInputData(imageData);
#endif
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
// Add both renderers to the window
renderWindow->AddRenderer(renderer);
// Add a sphere to the left and a cube to the right
renderer->AddActor(actor);
renderer->ResetCamera();
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
//renderWindow->Render();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
and used CMake with the following CMakeLists.txt:
project(test)
find_package(VTK)
message (STATUS "VTK_VERSION: ${VTK_VERSION}")
add_executable(test test.cxx )
target_link_libraries(test ${VTK_LIBRARIES})
vtk_module_autoinit(
TARGETS ${PROJECT_NAME}
MODULES ${VTK_LIBRARIES}
)
I can compile and run it but I just get a window but it's black. It is by the way a simple example of VTK. I use VcXsrv and disabled native OpenGL. I also set export GL_ALWAYS_INDIRECT=0 and when I run glxgears they are rotating.
I always get the following printed to my console:
[ 80D00780]vtkOpenGLFramebufferObj:1390 WARN| failed at glBlitFramebuffer 1 OpenGL errors detected
0 : (1282) Invalid operation
Thank you for your help!
It is commonly known bug in VcXsrv. It's quite tricky, but there is a simple work-around. You have to change your CMakeList. This YouTube-Tutorial explains it very well. If you have further questions, I'm happy to offer other excellent answers.
I am trying to create a new C++ project that uses VTK in Visual Studio.
I followed the instructions on to how to download, access and build VTK on Windows using CMake and that seemed to go ok. I then tried to create a new project that includes VTK functionality and visualisation but it generates errors where it cannot open any of the VTK header files (it maybe due to the additional dependencies in the project properties but I am not sure what to change or update to make this work).
Does anyone know how to fix this issue? (at the moment I am trying to view a simple cube using the following code):
#include <vtkSmartPointer.h>
#include <vtkActor.h>
#include <vtkCubeSource.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <cmath>
#include <algorithm>
int main(int t) {
if (t==1) {
vtkSmartPointer<vtkCubeSource> cubeSource =
vtkSmartPointer<vtkCubeSource>::New();
// Create a mapper and actor.
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(cubeSource->GetOutputPort());
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
// 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 actors to the scene
renderer->AddActor(actor);
renderer->SetBackground(.3, .2, .1);
// Render and interact
renderWindow->Render();
renderWindowInteractor->Start();
actor->Delete();
mapper->Delete();
renderer->Delete();
renderWindow->Delete();
renderWindowInteractor->Delete();
}
return 0;
}
Also, my CMakeLists file is this:
cmake_minimum_required(VERSION 2.8)
PROJECT(karman)
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
add_executable(karman MACOSX_BUNDLE karman)
if(VTK_LIBRARIES)
target_link_libraries(karman ${VTK_LIBRARIES})
else()
target_link_libraries(karman vtkHybrid vtkWidgets)
endif()
GTK uses cairo for drawing. So I'm trying to create a hello world app that writes to an image (svg, png, ...) instead of X11. I'm facing 2 problems:
- The image is empty
- When starting without X11 running (which is the actual goal) I get the error "** (a.out:9021): WARNING **: Could not open X display"
The code is draft!
#include <string>
#include <iostream>
#include <thread>
#include <chrono>
#include <cmath>
#include <cairo.h>
#include <cairommconfig.h>
#include <cairomm/context.h>
#include <cairomm/surface.h>
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
int main(int argc, char *argv[])
{
gtk_init(&argc, &argv);
GtkWidget *window;
GtkWidget *button;
// GtkWidget *main_window = gtk_initialize();
window = gtk_offscreen_window_new();
button = gtk_button_new_with_label ("Hello World");
gtk_container_add (GTK_CONTAINER (window), button);
gtk_widget_show (window);
GdkWindow *gdk_window = gtk_widget_get_window(GTK_WIDGET(window));
std::cout << "gdk window: " << gdk_window << std::endl;
cairo_surface_t * surfp = gdk_offscreen_window_get_surface(gdk_window);
std::cout << "Created Window will now draw to png" << std::endl;
std::string filename = "image.svg";
double width = 600;
double height = 400;
Cairo::SvgSurface srfobj(surfp);
Cairo::RefPtr<Cairo::SvgSurface> refptr(&srfobj);
Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create(refptr);
cr->save(); // save the state of the context
cr->show_page();
std::cout << "Wrote SVG file \"" << filename << "\"" << std::endl;
std::chrono::milliseconds dura( 200 );
std::this_thread::sleep_for(dura);
return 0;
}
Why is this code not working?
Can I run a gtk app without X11 running, or should I just ignore the warning?
Here is my solution based on your example code - keep in mind it is a dirty solution and may not work using newer versions of GTK3. It works to save the UI of a window (only tested with the one button), but still requires (somewhere) a running X-server. It also ignores / don't use your settings for the picture size - you'll have to resize it at your own. I don't know if (and how) it is possible to cut this string (X-Server // X-Framebuffer) too (DirectFB seems not to be really supported anymore), but...
Have fun!
// Default
#include <string>
#include <iostream>
#include <thread>
#include <chrono>
// cairo / cairomm / gtk
#include <cairo.h>
#include <cairomm/context.h> //libcairomm-1.0-dev
#include <gtk/gtk.h>
int main(int argc, char *argv[]) {
// Init
gtk_init(&argc, &argv);
// Create window with a button
GtkWidget *window;
GtkWidget *button;
window = gtk_offscreen_window_new();
button = gtk_button_new_with_label("Hello World");
gtk_container_add(GTK_CONTAINER(window), button);
gtk_widget_show_all(window);
// Make a gdk window out of it, prepare cairo and draw it to it
GdkWindow* gdk_window = gtk_widget_get_window(GTK_WIDGET(window));
cairo_surface_t* surfp = gdk_offscreen_window_get_surface(gdk_window);
cairo_t* context = cairo_create(surfp);
gtk_widget_draw(GTK_WIDGET(window), context);
// Yay - begin the dump!
Cairo::SvgSurface srfobj(surfp);
std::string filename = "image.png";
srfobj.write_to_png(filename);
std::cout << "Done." << std::endl;
// Aaand a little sleep...
std::chrono::milliseconds dura(1000);
std::this_thread::sleep_for(dura);
return 0;
}
Try to use gtk_widget_draw (widget_ptr, cairo_ctx_ptr); to draw a widget (or a hierarchy of widgets) to a cario context?
The answer to both your questions is that you cannot run GTK+ applications without some sort of output. You're using gtk-x11 which requires an XServer. You might have some luck with the DirectFB backend, but I wouldn't hold your breath as I don't know if it's even maintained anymore.
Because Gtk doesn't run without an XServer the resulting image is empty.
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);