#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include vtkSmartPointer contourWidget; vtkSmartPointer pd; vtkSmartPointer interactor; vtkSmartPointer contourRep; // class for handling interaction on/off class KeyPressInteractorStyle : public vtkInteractorStyleImage//vtkInteractorStyleTrackballCamera { public: static KeyPressInteractorStyle* New(); vtkTypeMacro(KeyPressInteractorStyle, vtkInteractorStyleTrackballCamera); virtual void OnKeyPress() { // Get the keypress vtkRenderWindowInteractor *rwi = this->Interactor; std::string key = rwi->GetKeySym(); // Output the key that was pressed std::cout << "Pressed " << key << std::endl; // Handle an arrow key if (key == "Up") { contourWidget = vtkSmartPointer::New(); contourWidget->SetInteractor(interactor); contourWidget->SetRepresentation(contourRep); contourWidget->On(); std::cout << "add and move points" << std::endl; contourWidget->GetEventTranslator()->RemoveTranslation( vtkCommand::LeftButtonPressEvent); contourWidget->GetEventTranslator()->SetTranslation( vtkCommand::LeftButtonPressEvent, vtkWidgetEvent::Translate); //contourWidget->Initialize(pd); //contourWidget->Render(); //interactor->Initialize(); //interactor->Start(); //Interactor->Disable(); } // Handle a "normal" key if (key == "Down") { std::cout << "Remove points" << std::endl; contourWidget->GetEventTranslator()->RemoveTranslation( vtkCommand::LeftButtonPressEvent); contourWidget->GetEventTranslator()->SetTranslation( vtkCommand::LeftButtonPressEvent, vtkWidgetEvent::Delete); } // Forward events vtkInteractorStyleTrackballCamera::OnKeyPress(); } }; vtkStandardNewMacro(KeyPressInteractorStyle); double* GetClosesstPointToPlane(double * n, double * p) { double* closest = new double[2](); double c = -(n[0]*p[0] + n[1]*p[1] + n[2]*p[2]) / (n[0]*n[0] + n[1]*n[1] + n[2]*n[2]); closest[0] = p[0] + c*n[0]; closest[1] = p[1] + c*n[1]; closest[2] = p[2] + c*n[2]; return closest; } double* normal; double* center; // class for handling click over the contour class ContourCallBack : public vtkCommand { public: static ContourCallBack *New() { return new ContourCallBack; } ContourCallBack(){} virtual void Execute(vtkObject *caller, unsigned long eid, void* clientData) { vtkContourWidget *contourWidget = reinterpret_cast(caller); // Retrieve the windows event x, y, z std::cout << "window click " << contourWidget->GetInteractor()->GetEventPosition()[0] << " " << contourWidget->GetInteractor()->GetEventPosition()[1] << " " << contourWidget->GetInteractor()->GetEventPosition()[2] << std::endl; // get the node postiion (the world position) vtkContourRepresentation * rep=contourWidget->GetContourRepresentation(); double* worldclick = new double[2](); rep->GetActiveNodeWorldPosition(worldclick); std::cout << "worldclick click " << worldclick[0] << " " << worldclick[1] << " " << worldclick[2] << std::endl; // change position double* projection = new double[2](); //restringedPosition[0] = nodepos[0]; //restringedPosition[1] = nodepos[1]; //restringedPosition[2] = 0; // ToDo: change is hard coded but must work for every plane/image projection = GetClosesstPointToPlane(normal, worldclick); std::cout << "projection click " << projection[0] << " " << projection[1] << " " << projection[2] << std::endl; rep->SetActiveNodeToWorldPosition(projection); //delete(nodepos); } }; int main(int argc, char *argv[]) { normal = new double[2](); normal[0] = 1; normal[1] = 1; normal[2] = 1; center = new double[2](); // Create the RenderWindow, Renderer and both Actors // vtkSmartPointer renderer = vtkSmartPointer::New(); vtkSmartPointer renderWindow = vtkSmartPointer::New(); renderWindow->AddRenderer(renderer); vtkSmartPointer interactor = vtkSmartPointer::New(); interactor->SetRenderWindow(renderWindow); renderer->SetBackground(0.1, 0.2, 0.4); renderWindow->SetSize(600, 600); // visual reference // Create a plane vtkSmartPointer planeSource = vtkSmartPointer::New(); planeSource->SetCenter(center); // 0.0, 0.0, 0.0); planeSource->SetNormal(normal); //1.0, 0.0, 1.0); planeSource->Update(); vtkPolyData* plane = planeSource->GetOutput(); // Create a mapper and actor vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputData(plane); vtkSmartPointer planeActor = vtkSmartPointer::New(); planeActor->SetMapper(mapper); /*vtkSmartPointer style = vtkSmartPointer::New(); interactor->SetInteractorStyle(style);*/ // create the contour stuff vtkSmartPointer contourRep = vtkSmartPointer::New(); contourRep->GetLinesProperty()->SetColor(0, 0, 1); //set color to red vtkSmartPointer contourWidget = vtkSmartPointer::New(); contourWidget->SetInteractor(interactor); contourWidget->SetRepresentation(contourRep); contourWidget->On(); for (int i = 0; i < argc; i++) { if (strcmp("-Shift", argv[i]) == 0) { contourWidget->GetEventTranslator()->RemoveTranslation( vtkCommand::LeftButtonPressEvent); contourWidget->GetEventTranslator()->SetTranslation( vtkCommand::LeftButtonPressEvent, vtkWidgetEvent::Translate); } else if (strcmp("-Scale", argv[i]) == 0) { contourWidget->GetEventTranslator()->RemoveTranslation( vtkCommand::LeftButtonPressEvent); contourWidget->GetEventTranslator()->SetTranslation( vtkCommand::LeftButtonPressEvent, vtkWidgetEvent::Scale); } } //Add an observer to contour widget vtkSmartPointer contourCallBack = vtkSmartPointer::New(); contourWidget->AddObserver(vtkCommand::InteractionEvent, contourCallBack); // quick points for representation vtkSmartPointer pd = vtkSmartPointer::New(); vtkSmartPointer points = vtkSmartPointer::New(); vtkSmartPointer lines = vtkSmartPointer::New(); vtkIdType* lineIndices = new vtkIdType[21]; for (int i = 0; i< 20; i++) { const double angle = 2.0*vtkMath::Pi()*i / 20.0; double* closest = new double[2](); double* p = new double[2](); p[0] = 0.2*cos(angle); p[1] = 0.2*sin(angle); p[2] = 0.0; closest = GetClosesstPointToPlane(normal, p); points->InsertPoint(static_cast(i), closest); lineIndices[i] = static_cast(i); } lineIndices[20] = 0; lines->InsertNextCell(21, lineIndices); delete[] lineIndices; pd->SetPoints(points); pd->SetLines(lines); contourWidget->Initialize(pd); contourWidget->Render(); renderer->GetActiveCamera()->SetPosition(0, 0, 2.1); renderer->AddActor(planeActor); renderWindow->Render(); interactor->Initialize(); interactor->Start(); contourWidget->Off(); return EXIT_SUCCESS; }