Sunday, November 25, 2018

c++ / vtk trackball camera style

https://www.vtk.org/Wiki/VTK/Examples/Cxx/Interaction/TrackballCamera

vtk 만으로 style을 수정하려면 위 링크처럼 하면된다.

단, Qt를 사용할경우, QVTKWidget은 기본 스타일이 트랙볼카메라 이므로 속편하게 그냥 쓰면 된다.
$ sudo apt-get install libvtk6-qt-dev  # QVTKWidget이 제공되는 vtk 설치

CMakeLists.txt --------------------------------------------------------
find_package(VTK 6 REQUIRED)
include(${VTK_USE_FILE}) # Not include_directories

find_package(Qt5Widgets REQUIRED)
include_directories( ${Qt5Widgets_INCLUDE_DIRS})
QT5_WRAP_CPP(moc_src viewer.h)

add_executable(${PROJECT_NAME} 
main.cpp
${moc_src}
)

target_link_libraries(${PROJECT_NAME}
${VTK_LIBRARIES}
${QT_LIBRARIES}
)

main.cpp ------------------------------------------------
#include <stdio.h>
#include <QVTKWidget.h>
#include <QWidget>
#include <QApplication>
#include <QVBoxLayout>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkSphere.h>
#include <vtkSphereSource.h>
#include <vtkCone.h>
#include <vtkConeSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <QKeyEvent>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCamera.h>

class MyWidget : public QWidget {
public:
  MyWidget()
    :qvtk_widget_(new QVTKWidget(this))
  {
    QVBoxLayout* layout = new QVBoxLayout;
    setLayout(layout);
    layout->addWidget(qvtk_widget_);
    qvtk_widget_->setFixedSize(640,480);
    renderer_ = vtkSmartPointer<vtkRenderer>::New();
    renderer_->SetBackground(1.0, 1.0, 1.0);
    render_window_ = vtkSmartPointer<vtkRenderWindow>::New();
    render_window_->AddRenderer(renderer_);
    qvtk_widget_->SetRenderWindow(render_window_);

    qvtk_widget_->installEventFilter((QWidget*)this);

    tarckball_style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
    auto qvtk_interactor = vtkSmartPointer<QVTKInteractor>::New();
    // Make sure that don't auto adjust camera clipping range, because of zoom in/out.
    // AutoAdjust will cause glitch because of wrong adjustment.
    tarckball_style->SetAutoAdjustCameraClippingRange(false);
    qvtk_interactor->SetInteractorStyle(tarckball_style);
    qvtk_interactor->SetRenderWindow(render_window_);

    Initialize();
  }

  vtkSmartPointer<vtkInteractorStyleTrackballCamera> tarckball_style;

  void Initialize(){
    auto sphereSource = vtkSmartPointer<vtkSphereSource>::New();
    sphereSource->SetCenter(1.0, 0.0, 0.0);
    sphereSource->Update();
    auto sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    sphereMapper->SetInputConnection(sphereSource->GetOutputPort());
    auto sphereActor = vtkSmartPointer<vtkActor>::New();
    sphereActor->SetMapper(sphereMapper);
    auto coneSource = vtkSmartPointer<vtkConeSource>::New();
    auto coneMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    coneMapper->SetInputConnection(coneSource->GetOutputPort());
    vtkSmartPointer<vtkActor> coneActor = vtkSmartPointer<vtkActor>::New();
    coneActor->SetMapper(coneMapper);
    renderer_->AddActor(sphereActor);
    renderer_->AddActor(coneActor);
    ResetCamera();
    return;
  }

  void ResetCamera(){
    renderer_->ResetCamera();
    // Don't forget reset clipiing range after Reset camera.
    vtkCamera* camera = renderer_->GetActiveCamera();
    camera->SetClippingRange(0.001, 1e+8);
    render_window_->Render();
    return;
  }

  bool eventFilter(QObject *obj, QEvent *ev){
    if (ev->type() == QEvent::KeyPress ) {
      QKeyEvent* keyevent = dynamic_cast<QKeyEvent*>(ev);
      if(keyevent->key() == Qt::Key_Q){
        close();
        // eventFilter intercepts the event.
        return true;
      }
      else if(keyevent->key() == Qt::Key_R){
        ResetCamera();
        return true;
      }
      else{
        vtkCamera* camera = renderer_->GetActiveCamera();
        std::cout << tarckball_style->GetAutoAdjustCameraClippingRange()
          << " : " << camera->GetClippingRange()[0]
          << " : " << camera->GetClippingRange()[1] << std::endl;
      }
    }
    // eventFilter doesn't intercept the event.
    return false;
  }

private:
  QVTKWidget*const qvtk_widget_;
  vtkSmartPointer<vtkRenderer> renderer_;
  vtkSmartPointer<vtkRenderWindow> render_window_;
};

int main(int argc, char**argv){
  QApplication app(argc, argv);
  MyWidget mywidget;
  mywidget.show();
  app.exec();
  return 1;
}
------------------------------------------------------------

Friday, November 2, 2018

Logging

1) glog를 이용한 logging 예시
-------------------------------------------------------------------------------------------

int f3(){
  print_stacktrace();
  printf("hello f3\n");
  LOG(INFO) << "Hello" << std::endl;
  std::vector<int> vec = {1, 2, 3, 4};
  int j = vec.at(20);
  return j;
}
void f2(){
  f3();
  return;
}

void f1(){
  f2();
  return;
}

void WriteToStderr(const char* data, int size) {
  //LOG(ERROR) << __pretty_function__ << ":Error..." << std::string(data,size);
  LOG(ERROR) << __func__ << ":Error..." << std::string(data,size);
}

int main(int argc, char** argv){
  std::string log_destination = "/home/geonuk/atlas/ws/test/output/log";
  google::InstallFailureSignalHandler();
  google::InstallFailureWriter(WriteToStderr);
  google::InitGoogleLogging(argv[0]);
  google::SetLogDestination(google::GLOG_INFO, log_destination.c_str() );
  f3();
  return 0;
}

-------------------------------------------------------------------------------------------
2) subtrace를 얻는법 예시

void print_trace(void) {
  void *array[10];
  char **strings;
  size_t size = backtrace(array, 10);
  backtrace_symbols_fd(array, size, STDERR_FILENO);
}
-------------------------------------------------------------------------------------------