/*========================================================================= Program: Visualization Toolkit Module: TestPolygonalHandleRepresentations.cxx Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkDEMReader.h" #include "vtkPolyData.h" #include "vtkPolyDataMapper.h" #include "vtkActor.h" #include "vtkRenderer.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkProperty.h" #include "vtkCamera.h" #include "vtkImageDataGeometryFilter.h" #include "vtkWarpScalar.h" #include "vtkPolyDataNormals.h" #include "vtkLODActor.h" #include "vtkImageData.h" #include "vtkLookupTable.h" #include "vtkPoints.h" #include "vtkCellArray.h" #include "vtkPolyDataCollection.h" #include "vtkTriangleFilter.h" #include "vtkImageResample.h" #include "vtkInteractorEventRecorder.h" #include "vtkHandleWidget.h" #include "vtkPolygonalHandleRepresentation3D.h" #include "vtkOrientedPolygonalHandleRepresentation3D.h" #include "vtkPointHandleRepresentation3D.h" #include "vtkPolygonalSurfacePointPlacer.h" #include "vtkSphereSource.h" #include "vtkGlyphSource2D.h" #include "vtkTestUtilities.h" #include "vtkSmartPointer.h" #define VTK_CREATE(type, name) \ vtkSmartPointer name = vtkSmartPointer::New() vtkSmartPointer< vtkHandleWidget > CreateWidget( vtkRenderWindowInteractor * iren, int shape, double x, double y, double z, bool cameraFacing = false, const char * label = nullptr, vtkActor * demActor = nullptr, vtkPolyData * demPolys = nullptr, bool constrainedToSurface = false, double heightOffsetAboveSurface = 0.0 ) { VTK_CREATE( vtkHandleWidget, widget ); vtkHandleRepresentation *rep = nullptr; if (cameraFacing && shape <= 12) { rep = vtkOrientedPolygonalHandleRepresentation3D::New(); VTK_CREATE( vtkGlyphSource2D, glyphs ); glyphs->SetGlyphType( shape ); glyphs->SetScale( 600 ); glyphs->Update(); static_cast(rep)-> SetHandle(glyphs->GetOutput()); } else { if (shape == 12) { rep = vtkPolygonalHandleRepresentation3D::New(); VTK_CREATE( vtkSphereSource, sphere ); sphere->SetThetaResolution(10); sphere->SetPhiResolution(10); sphere->SetRadius(300.0); sphere->Update(); static_cast(rep)->SetHandle(sphere->GetOutput()); } if (shape == 13) { rep = vtkPointHandleRepresentation3D::New(); } } if (constrainedToSurface) { VTK_CREATE( vtkPolygonalSurfacePointPlacer, pointPlacer ); pointPlacer->AddProp(demActor); pointPlacer->GetPolys()->AddItem( demPolys ); pointPlacer->SetDistanceOffset( heightOffsetAboveSurface ); rep->SetPointPlacer(pointPlacer); // Let the surface constrained point-placer be the sole constraint dictating // the placement of handles. Lets not over-constrain it allowing axis // constrained interactions. widget->EnableAxisConstraintOff(); } double xyz[3] = {x, y, z}; rep->SetWorldPosition( xyz ); widget->SetInteractor(iren); widget->SetRepresentation( rep ); // Set some defaults on the handle widget double color[3] = { ((double)(shape%4))/3.0, ((double)((shape+3)%7))/6.0, (double)(shape%2) }; double selectedColor[3] = { 1.0, 0.0, 0.0 }; if (vtkAbstractPolygonalHandleRepresentation3D *arep = vtkAbstractPolygonalHandleRepresentation3D::SafeDownCast(rep)) { arep->GetProperty()->SetColor( color ); arep->GetProperty()->SetLineWidth(1.0); arep->GetSelectedProperty()->SetColor( selectedColor ); if (label) { arep->SetLabelVisibility(1); arep->SetLabelText(label); } } if (vtkPointHandleRepresentation3D *prep = vtkPointHandleRepresentation3D::SafeDownCast(rep)) { prep->GetProperty()->SetColor( color ); prep->GetProperty()->SetLineWidth(1.0); prep->GetSelectedProperty()->SetColor( selectedColor ); } rep->Delete(); return widget; } int TestPolygonalHandleRepresentations(int argc, char*argv[]) { if (argc < 2) { std::cerr << "Demonstrates various polyonal handle representations in a scene." << std::endl; return EXIT_FAILURE; } // Read height field. char* fname = vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/SainteHelens.dem"); // Read height field. // vtkSmartPointer demReader = vtkSmartPointer::New(); demReader->SetFileName(fname); delete [] fname; vtkSmartPointer resample = vtkSmartPointer::New(); resample->SetInputConnection(demReader->GetOutputPort()); resample->SetDimensionality(2); resample->SetAxisMagnificationFactor(0,1); resample->SetAxisMagnificationFactor(1,1); // Extract geometry vtkSmartPointer surface = vtkSmartPointer::New(); surface->SetInputConnection(resample->GetOutputPort()); // The Dijkistra interpolator will not accept cells that aren't triangles vtkSmartPointer triangleFilter = vtkSmartPointer::New(); triangleFilter->SetInputConnection( surface->GetOutputPort() ); triangleFilter->Update(); vtkSmartPointer warp = vtkSmartPointer::New(); warp->SetInputConnection(triangleFilter->GetOutputPort()); warp->SetScaleFactor(1); warp->UseNormalOn(); warp->SetNormal(0, 0, 1); warp->Update(); // Define a LUT mapping for the height field double lo = demReader->GetOutput()->GetScalarRange()[0]; double hi = demReader->GetOutput()->GetScalarRange()[1]; vtkSmartPointer lut = vtkSmartPointer::New(); lut->SetHueRange(0.6, 0); lut->SetSaturationRange(1.0, 0); lut->SetValueRange(0.5, 1.0); vtkSmartPointer normals = vtkSmartPointer::New(); normals->SetInputConnection(warp->GetOutputPort()); normals->SetFeatureAngle(60); normals->SplittingOff(); // vtkPolygonalSurfacePointPlacer needs cell normals normals->ComputeCellNormalsOn(); normals->Update(); vtkPolyData *pd = normals->GetOutput(); vtkSmartPointer demMapper = vtkSmartPointer::New(); demMapper->SetInputConnection(normals->GetOutputPort()); demMapper->SetScalarRange(lo, hi); demMapper->SetLookupTable(lut); vtkSmartPointer demActor = vtkSmartPointer::New(); demActor->SetMapper(demMapper); // Create the RenderWindow, Renderer and the DEM + path actors. vtkSmartPointer ren1 = vtkSmartPointer::New(); vtkSmartPointer renWin = vtkSmartPointer::New(); renWin->AddRenderer(ren1); vtkSmartPointer iren = vtkSmartPointer::New(); iren->SetRenderWindow(renWin); // Add the actors to the renderer, set the background and size ren1->AddActor(demActor); ren1->GetActiveCamera()->SetViewUp(0, 0, 1); ren1->GetActiveCamera()->SetPosition(-99900, -21354, 131801); ren1->GetActiveCamera()->SetFocalPoint(41461, 41461, 2815); ren1->ResetCamera(); ren1->ResetCameraClippingRange(); // Here comes the surface constrained handle widget stuff..... vtkSmartPointer< vtkHandleWidget > widget[14]; widget[0] = CreateWidget( iren, VTK_VERTEX_GLYPH, 561909, 5.11921e+06, 4381.48, true, "Vertex" ); widget[1] = CreateWidget( iren, VTK_DASH_GLYPH, 559400, 5.11064e+06, 2323.25, true, "Dash" ); widget[2] = CreateWidget( iren, VTK_CROSS_GLYPH, 563531, 5.11924e+06, 5202.51, true, "cross" ); widget[3] = CreateWidget( iren, VTK_THICKCROSS_GLYPH, 563300, 5.11729e+06, 4865.47, true, "Thick Cross" ); widget[4] = CreateWidget( iren, VTK_TRIANGLE_GLYPH, 564392, 5.11248e+06, 3936.91, true, "triangle" ); widget[5] = CreateWidget( iren, VTK_SQUARE_GLYPH, 563715, 5.11484e+06, 4345.68, true, "square" ); widget[6] = CreateWidget( iren, VTK_CIRCLE_GLYPH, 564705, 5.10849e+06, 2335.16, true, "circle" ); widget[7] = CreateWidget( iren, VTK_DIAMOND_GLYPH, 560823, 5.1202e+06 ,3783.94, true, "diamond" ); widget[8] = CreateWidget( iren, VTK_ARROW_GLYPH, 559637, 5.12068e+06, 2718.66, true, "arrow" ); widget[9] = CreateWidget( iren, VTK_THICKARROW_GLYPH, 560597, 5.10817e+06, 3582.44, true, "thickArrow" ); widget[10] = CreateWidget( iren, VTK_HOOKEDARROW_GLYPH, 558266, 5.12137e+06, 2559.14, true, "hookedArrow" ); widget[11] = CreateWidget( iren, VTK_EDGEARROW_GLYPH, 568869, 5.11028e+06, 2026.57, true, "EdgeArrow" ); widget[12] = CreateWidget( iren, 12, 561753, 5.11577e+06, 3183, false, "Sphere contrained to surface", demActor, pd, true, 100.0 ); widget[13] = CreateWidget( iren, 13, 562692, 5.11521e+06, 3355.65, false, "Crosshair" ); renWin->SetSize(600,600); renWin->Render(); iren->Initialize(); for (unsigned int i = 0; i < 14; i++) { widget[i]->EnabledOn(); } renWin->Render(); iren->Start(); return EXIT_SUCCESS; }