58 #include <vtkLightCollection.h>
61 #include <vtkCameraOrientationRepresentation.h>
62 #include <vtkCameraOrientationWidget.h>
63 #include <vtkCubeAxesActor.h>
64 #include <vtkLightKit.h>
75 #include <vtkAreaPicker.h>
77 #include <vtkAxesActor.h>
78 #include <vtkBMPReader.h>
79 #include <vtkCamera.h>
80 #include <vtkCaptionActor2D.h>
81 #include <vtkCaptionRepresentation.h>
82 #include <vtkFieldData.h>
83 #include <vtkJPEGReader.h>
84 #include <vtkLookupTable.h>
85 #include <vtkOpenGLRenderWindow.h>
86 #include <vtkOrientationMarkerWidget.h>
87 #include <vtkPNGReader.h>
88 #include <vtkPNMReader.h>
89 #include <vtkPointPicker.h>
90 #include <vtkPolyDataNormals.h>
91 #include <vtkPropAssembly.h>
92 #include <vtkPropPicker.h>
93 #include <vtkProperty.h>
94 #include <vtkQImageToImageSource.h>
95 #include <vtkRenderWindow.h>
96 #include <vtkRenderWindowInteractor.h>
97 #include <vtkRenderer.h>
98 #include <vtkRendererCollection.h>
99 #include <vtkStringArray.h>
100 #include <vtkTIFFReader.h>
101 #include <vtkTextActor.h>
102 #include <vtkTextProperty.h>
103 #include <vtkTexture.h>
104 #include <vtkTransform.h>
105 #include <vtkTubeFilter.h>
106 #include <vtkUnsignedCharArray.h>
107 #include <vtkWidgetEvent.h>
108 #include <vtkWidgetEventTranslator.h>
109 #include <vtkWindowToImageFilter.h>
112 #include <pcl/common/transforms.h>
113 #include <pcl/visualization/common/actor_map.h>
114 #include <pcl/visualization/point_cloud_color_handlers.h>
115 #include <pcl/visualization/point_cloud_geometry_handlers.h>
118 #ifdef vtkGenericDataArray_h
119 #define SetTupleValue SetTypedTuple
120 #define InsertNextTupleValue InsertNextTypedTuple
121 #define GetTupleValue GetTypedTuple
124 #define ORIENT_MODE 0
125 #define SELECT_MODE 1
134 const std::string& viewerName ,
138 :
pcl::visualization::PCLVisualizer(
139 argc, argv, viewerName, interactor_style, initIterator),
143 m_pointPickingEnabled(true),
144 m_areaPickingEnabled(false),
145 m_actorPickingEnabled(false),
146 m_autoUpdateCameraPos(false),
147 texture_render_manager_(
148 std::make_unique<renders::TextureRenderManager>()),
149 m_lightIntensity(1.0) {
151 getRenderWindow()->GlobalWarningDisplayOff();
164 const std::string& viewerName,
168 :
pcl::visualization::PCLVisualizer(argc,
178 m_pointPickingEnabled(true),
179 m_areaPickingEnabled(false),
180 m_actorPickingEnabled(false),
181 m_autoUpdateCameraPos(false),
182 texture_render_manager_(
183 std::make_unique<renders::TextureRenderManager>()),
184 m_lightIntensity(1.0) {
186 getRenderWindow()->GlobalWarningDisplayOff();
219 renderer->RemoveActor(pair.second);
250 registerInteractorStyle(
false);
257 registerPointPicking();
258 registerAreaPicking();
267 if (ren ==
nullptr || rwi ==
nullptr) {
271 vtkTransform* transform = vtkTransform::New();
272 vtkCamera* camera = ren->GetActiveCamera();
274 double scale = vtkMath::Norm(camera->GetPosition());
276 scale = vtkMath::Norm(camera->GetFocalPoint());
281 double* temp = camera->GetFocalPoint();
282 camera->SetFocalPoint(temp[0] / scale, temp[1] / scale, temp[2] / scale);
283 temp = camera->GetPosition();
284 camera->SetPosition(temp[0] / scale, temp[1] / scale, temp[2] / scale);
287 transform->Identity();
291 if (!currentRotateManipulator) {
296 currentRotateManipulator->GetCenter(center);
297 double rotationFactor = currentRotateManipulator->GetRotationFactor();
298 transform->Translate(center[0] / scale, center[1] / scale,
301 camera->OrthogonalizeViewUp();
303 transform->RotateWXYZ(angle, axis[0], axis[1], axis[2]);
306 transform->Translate(-center[0] / scale, -center[1] / scale,
309 camera->ApplyTransform(transform);
310 camera->OrthogonalizeViewUp();
313 temp = camera->GetFocalPoint();
314 camera->SetFocalPoint(temp[0] * scale, temp[1] * scale, temp[2] * scale);
315 temp = camera->GetPosition();
316 camera->SetPosition(temp[0] * scale, temp[1] * scale, temp[2] * scale);
318 rwi->SetLastEventPosition(pos.
x, pos.
y);
341 double pt[8][4] = {{bounds[0], bounds[2], bounds[5], 1.0},
342 {bounds[1], bounds[2], bounds[5], 1.0},
343 {bounds[1], bounds[2], bounds[4], 1.0},
344 {bounds[0], bounds[2], bounds[4], 1.0},
345 {bounds[0], bounds[3], bounds[5], 1.0},
346 {bounds[1], bounds[3], bounds[5], 1.0},
347 {bounds[1], bounds[3], bounds[4], 1.0},
348 {bounds[0], bounds[3], bounds[4], 1.0}};
352 for (
int i = 0; i < 8; ++i) {
353 matrix->MultiplyPoint(pt[i], pt[i]);
357 double min[4], max[4];
358 for (
int i = 0; i < 4; ++i) {
363 for (
int i = 1; i < 8; ++i) {
364 for (
int j = 0; j < 3; ++j) {
365 if (min[j] > pt[i][j]) min[j] = pt[i][j];
366 if (max[j] < pt[i][j]) max[j] = pt[i][j];
384 bbox.GetCenter(center);
430 const int manipulators[9]) {
436 enum { NONE = 0, SHIFT = 1, CTRL = 2 };
447 for (
int manip = NONE; manip <= CTRL; manip++) {
448 for (
int button = 0; button < 3; button++) {
449 int manipType = manipulators[3 * manip + button];
476 if (cameraManipulator) {
477 cameraManipulator->SetButton(button +
479 cameraManipulator->SetControl(manip == CTRL ? 1 : 0);
480 cameraManipulator->SetShift(manip == SHIFT ? 1 : 0);
509 bbox.GetLengths(widths);
512 double diameterOverTen =
513 bbox.GetMaxLength() > 0 ? bbox.GetMaxLength() / 10.0 : 1.0;
514 widths[0] = widths[0] < diameterOverTen ? diameterOverTen : widths[0];
515 widths[1] = widths[1] < diameterOverTen ? diameterOverTen : widths[1];
516 widths[2] = widths[2] < diameterOverTen ? diameterOverTen : widths[2];
538 getRendererCollection()->InitTraversal();
539 vtkRenderer* renderer =
nullptr;
541 while ((renderer = getRendererCollection()->GetNextItem())) {
543 if (viewport == 0 || viewport == i) {
544 double prop_bounds[6];
581 double z_buffer = displayCoord[2];
591 assert(focal_distance >= 0);
594 cam->SetDistance(focal_distance);
600 assert(zoomFactor >= 0);
603 cam->Zoom(zoomFactor);
611 proj = Eigen::Matrix4d(pMat->GetData());
612 proj.transposeInPlace();
616 vtkMatrix4x4* vMat =
getVtkCamera()->GetModelViewTransformMatrix();
617 view = Eigen::Matrix4d(vMat->GetData());
618 view.transposeInPlace();
632 double originBounds[6];
656 getRendererCollection()->InitTraversal();
657 vtkRenderer* renderer =
nullptr;
658 while ((renderer = getRendererCollection()->GetNextItem()) !=
nullptr) {
659 renderer->ResetCamera(xMin, xMax, yMin, yMax, zMin, zMax);
675 if (!vtkMath::AreBoundsInitialized(bounds)) {
680 CVLog::Warning(
"Trying to reset clipping range of non-existent camera");
684 double expandedBounds[6] = {bounds[0], bounds[1], bounds[2],
685 bounds[3], bounds[4], bounds[5]};
704 range[0] =
a * expandedBounds[0] + b * expandedBounds[2] +
705 c * expandedBounds[4] + d;
709 for (k = 0; k < 2; k++) {
710 for (j = 0; j < 2; j++) {
711 for (i = 0; i < 2; i++) {
712 dist =
a * expandedBounds[i] + b * expandedBounds[2 + j] +
713 c * expandedBounds[4 + k] + d;
714 range[0] = (dist < range[0]) ? (dist) : (range[0]);
715 range[1] = (dist > range[1]) ? (dist) : (range[1]);
727 vtkMath::RadiansFromDegrees(
getVtkCamera()->GetViewAngle());
728 minGap = 0.2 * tan(angle / 2.0) * range[1];
730 if (range[1] - range[0] < minGap) {
731 minGap = minGap - range[1] + range[0];
732 range[1] += minGap / 2.0;
733 range[0] -= minGap / 2.0;
737 if (range[0] < 0.0) {
742 range[0] = 0.99 * range[0] -
743 (range[1] - range[0]) *
745 range[1] = 1.01 * range[1] +
746 (range[1] - range[0]) *
750 range[0] = (range[0] >= range[1]) ? (0.01 * range[1]) : (range[0]);
757 if (this->getRenderWindow()) {
758 int ZBufferDepth = this->getRenderWindow()->GetDepthBufferSize();
759 if (ZBufferDepth > 16) {
788 double pt[8][4] = {{bounds[0], bounds[2], bounds[5], 1.0},
789 {bounds[1], bounds[2], bounds[5], 1.0},
790 {bounds[1], bounds[2], bounds[4], 1.0},
791 {bounds[0], bounds[2], bounds[4], 1.0},
792 {bounds[0], bounds[3], bounds[5], 1.0},
793 {bounds[1], bounds[3], bounds[5], 1.0},
794 {bounds[1], bounds[3], bounds[4], 1.0},
795 {bounds[0], bounds[3], bounds[4], 1.0}};
799 for (
int i = 0; i < 8; ++i) {
800 matrix->MultiplyPoint(pt[i], pt[i]);
804 double min[4], max[4];
805 for (
int i = 0; i < 4; ++i) {
810 for (
int i = 1; i < 8; ++i) {
811 for (
int j = 0; j < 3; ++j) {
812 if (min[j] > pt[i][j]) min[j] = pt[i][j];
813 if (max[j] < pt[i][j]) max[j] = pt[i][j];
828 getRendererCollection()->InitTraversal();
829 vtkRenderer* renderer =
nullptr;
831 while ((renderer = getRendererCollection()->GetNextItem())) {
833 if (viewport == 0 || viewport == i) {
835 cam->SetViewAngle(viewAngle);
836 renderer->ResetCameraClippingRange();
847 const PCLCloud::Ptr& smCloud) {
848 if (!smCloud || smCloud->fields.empty()) {
853 int viewport =
context.defaultViewPort;
860 if (!updatePointCloud(cloud_rgb, viewID)) {
861 addPointCloud(cloud_rgb, viewID, viewport);
869 pcl::visualization::PointCloudColorHandlerCustom<PointT>
870 single_color(cloud_xyz, col.
r, col.
g, col.
b);
871 if (!updatePointCloud<PointT>(cloud_xyz, single_color, viewID)) {
872 addPointCloud<PointT>(cloud_xyz, single_color, viewID,
891 int viewport =
context.defaultViewPort;
893 if (contains(viewID)) {
894 removeMesh(viewID, viewport);
896 addPolygonMesh(*pclMesh, viewID, viewport);
898 if (!updatePolygonMesh(*pclMesh, viewID)) {
899 addPolygonMesh(*pclMesh, viewID, viewport);
908 const PCLTextureMesh::Ptr& textureMesh) {
910 int viewport =
context.defaultViewPort;
911 if (contains(viewID)) {
912 removeMesh(viewID, viewport);
918 const PCLPolygon::Ptr& pclPolygon,
921 int viewport =
context.defaultViewPort;
922 Eigen::Vector3d polygonColor =
928 addPolygon<PointT>(*pclPolygon, polygonColor.x(), polygonColor.y(),
929 polygonColor.z(), viewID, viewport);
931 addPolyline(pclPolygon, polygonColor.x(), polygonColor.y(),
932 polygonColor.z(),
context.defaultLineWidth, viewID,
941 int viewport =
context.defaultViewPort;
942 float lineWidth =
static_cast<float>(
context.currentLineWidth);
943 if (contains(viewID)) {
944 removeShapes(viewID, viewport);
963 CVLog::Error(
"[PCLVis::draw] unsupported sensor type!");
968 CVLog::Error(
"[PCLVis::draw] CreateCameraSensor failed!");
978 linesActor->GetProperty()->SetRepresentationToSurface();
979 linesActor->GetProperty()->SetLineWidth(lineWidth);
983 (*getShapeActorMap())[viewID] = linesActor;
988 if (!lineset)
return;
991 int viewport =
context.defaultViewPort;
992 float lineWidth =
static_cast<float>(
context.currentLineWidth);
993 if (contains(viewID)) {
994 removeShapes(viewID, viewport);
1003 linesActor->GetProperty()->SetRepresentationToSurface();
1004 linesActor->GetProperty()->SetLineWidth(lineWidth);
1008 (*getShapeActorMap())[viewID] = linesActor;
1012 if (
context.transformInfo.isApplyTransform()) {
1016 if (
context.transformInfo.isPositionChanged) {
1022 double*
origin = actor->GetOrigin();
1025 actor->SetUserTransform(trans);
1034 std::string bboxId =
1036 removeShapes(bboxId,
context.defaultViewPort);
1051 trans->RotateZ(transInfo.
eulerZYX[0]);
1052 trans->RotateY(transInfo.
eulerZYX[1]);
1053 trans->RotateX(transInfo.
eulerZYX[2]);
1069 trans->Translate(
origin.data());
1075 const PCLCloud::Ptr& smCloud) {
1077 int viewport =
context.defaultViewPort;
1079 if (
context.drawParam.showNorms) {
1080 const std::string normalID = viewID +
"-normal";
1081 pcl::PointCloud<pcl::PointNormal>::Ptr cloud_normals(
1082 new pcl::PointCloud<pcl::PointNormal>);
1088 if (contains(normalID)) {
1089 removePointClouds(normalID, viewport);
1091 addPointCloudNormals<pcl::PointNormal>(cloud_normals, normalDensity,
1095 const std::string normalID = viewID +
"-normal";
1096 if (contains(normalID)) {
1097 removePointClouds(normalID, viewport);
1102 if (!smCloud || smCloud->fields.empty()) {
1114 int viewport =
context.defaultViewPort;
1117 auto polydata = vtkPolyData::SafeDownCast(actor->GetMapper()->GetInput());
1118 if (!polydata)
return;
1125 bool has_normal =
false;
1126 if (!smCloud.fields.empty()) {
1127 has_normal = (pcl::getFieldIndex(smCloud,
"normal_x") != -1) &&
1128 (pcl::getFieldIndex(smCloud,
"normal_y") != -1) &&
1129 (pcl::getFieldIndex(smCloud,
"normal_z") != -1);
1135 vtkDataArray* existingNormals =
1136 polydata->GetPointData()->GetNormals();
1137 bool needUpdate =
context.forceRedraw || !existingNormals ||
1138 existingNormals->GetNumberOfTuples() !=
1139 static_cast<vtkIdType
>(
1140 polydata->GetNumberOfPoints());
1146 if (cloud.points.empty()) {
1147 CVLog::Error(
"[PCLVis::updateShadingMode] Cloud is empty!");
1150 normals->SetNumberOfComponents(3);
1152 for (std::size_t i = 0; i < cloud.points.size(); ++i) {
1153 const NormalT& N = cloud.points[i];
1154 const float normal[3] = {N.normal_x, N.normal_y,
1158 polydata->GetPointData()->SetNormals(
normals);
1173 bool has_color =
false;
1174 if (!smCloud.fields.empty()) {
1175 has_color = (pcl::getFieldIndex(smCloud,
"rgba") != -1) ||
1176 (pcl::getFieldIndex(smCloud,
"rgb") != -1);
1179 vtkDataArray* existingColors =
1180 polydata->GetPointData()->GetArray(
"RGB");
1181 bool needSync =
context.forceRedraw || !existingColors ||
1182 existingColors->GetNumberOfTuples() !=
1183 static_cast<vtkIdType
>(
1184 polydata->GetNumberOfPoints());
1190 colors->SetNumberOfComponents(3);
1194 if (!cloud.points.empty()) {
1195 colors->SetNumberOfTuples(
1196 static_cast<vtkIdType
>(cloud.points.size()));
1197 for (std::size_t i = 0; i < cloud.points.size(); ++i) {
1198 const pcl::PointXYZRGB& p = cloud.points[i];
1199 unsigned char color[3] = {p.r, p.g, p.b};
1200 colors->SetTypedTuple(
static_cast<vtkIdType
>(i),
color);
1205 polydata->GetPointData()->AddArray(
colors);
1208 vtkFieldData* fieldData = polydata->GetFieldData();
1212 hasRGB->SetName(
"HasSourceRGB");
1213 hasRGB->SetNumberOfTuples(1);
1214 hasRGB->SetValue(0, 1);
1215 fieldData->AddArray(hasRGB);
1219 "[PCLVis::updateShadingMode] Synced %zu RGB colors "
1220 "to VTK polydata (as 'RGB' array)",
1221 cloud.points.size());
1232 if (
context.drawParam.showNorms && has_normal) {
1237 actor->GetMapper()->Update();
1243 int viewport =
context.defaultViewPort;
1246 this->removeWidgets(viewID, viewport);
1257 "[PCLVis::addScalarBar] The id <%s> already exists! Please "
1258 "choose a different id and retry.",
1266 scalarBarWidget->CreateDefaultRepresentation();
1267 scalarBarWidget->CreateDefaultScalarBarActor();
1268 scalarBarWidget->On();
1271 (*m_widget_map)[viewID].widget = scalarBarWidget;
1284 const std::string& viewID,
1290 if (!widget)
return false;
1293 CustomVtkCaptionWidget::SafeDownCast(widget);
1294 if (!captionWidget)
return false;
1296 vtkCaptionRepresentation* rep = vtkCaptionRepresentation::SafeDownCast(
1297 captionWidget->GetRepresentation());
1302 vtkCaptionActor2D* actor2D = rep->GetCaptionActor2D();
1303 actor2D->SetCaption(text.c_str());
1305 vtkTextProperty* textProperty =
1306 actor2D->GetTextActor()->GetTextProperty();
1307 textProperty->SetColor(r, g, b);
1308 textProperty->SetFontSize(fontSize);
1311 textProperty->SetLineSpacing(1.2);
1326 CustomVtkCaptionWidget::SafeDownCast(widget);
1327 if (!captionWidget) {
1331 vtkCaptionRepresentation* rep = vtkCaptionRepresentation::SafeDownCast(
1332 captionWidget->GetRepresentation());
1339 const double* pos = rep->GetPosition();
1347 posX =
static_cast<float>(pos[0]);
1348 posY =
static_cast<float>(pos[1]);
1361 const std::string& viewID,
1362 bool anchorDragable,
1368 "[PCLVis::addCaption] The id <%s> already exists! Please "
1369 "choose a different id and retry.",
1377 captionRepresentation->SetAnchorPosition(
1379 captionRepresentation->SetPosition(
1380 1.0 * pos2D.
x / getRenderWindow()->GetSize()[0],
1381 1.0 * pos2D.
y / getRenderWindow()->GetSize()[1]);
1384 vtkCaptionActor2D* actor2D = captionRepresentation->GetCaptionActor2D();
1385 actor2D->SetCaption(text.c_str());
1386 actor2D->ThreeDimensionalLeaderOff();
1387 actor2D->BorderOff();
1388 actor2D->LeaderOn();
1389 actor2D->SetLeaderGlyphSize(10.0);
1390 actor2D->SetMaximumLeaderGlyphSize(10.0);
1393 actor2D->GetProperty()->SetColor(actorColor.
r, actorColor.
g, actorColor.
b);
1395 vtkTextProperty* textProperty = actor2D->GetTextActor()->GetTextProperty();
1396 textProperty->SetColor(r, g, b);
1397 textProperty->SetFontSize(fontSize);
1399 textProperty->SetBackgroundColor(col.
r, col.
g, col.
b);
1400 textProperty->SetBackgroundOpacity(
a);
1401 textProperty->FrameOn();
1402 textProperty->SetFrameColor(actorColor.
r, actorColor.
g, actorColor.
b);
1403 textProperty->SetFrameWidth(2);
1404 textProperty->BoldOff();
1405 textProperty->ItalicOff();
1406 textProperty->SetFontFamilyToArial();
1407 textProperty->SetJustificationToLeft();
1408 textProperty->SetVerticalJustificationToCentered();
1411 textProperty->SetLineSpacing(1.2);
1415 captionWidget->SetHandleEnabled(anchorDragable);
1422 captionWidget->SetInteractor(interactor);
1423 captionWidget->SetRepresentation(captionRepresentation);
1424 captionWidget->On();
1431 QString viewIDStr = QString::fromStdString(viewID);
1436 if (!node)
return nullptr;
1443 if (found)
return found;
1447 associatedLabel = findByViewID(sceneRoot);
1451 if (associatedLabel) {
1452 captionWidget->SetAssociatedLabel(associatedLabel);
1456 (*m_widget_map)[viewID].widget = captionWidget;
1466 const std::string&
id,
1469 poly_points->SetNumberOfPoints(pclPolygon->getContour().size());
1471 for (i = 0; i < pclPolygon->getContour().
size(); ++i) {
1472 poly_points->SetPoint(i, pclPolygon->getContour()[i].x,
1473 pclPolygon->getContour()[i].y,
1474 pclPolygon->getContour()[i].z);
1479 pcl::visualization::ShapeActorMap::iterator am_it =
1480 getShapeActorMap()->find(
id);
1481 if (am_it != getShapeActorMap()->end()) {
1483 "[addPolyline] A shape with id <%s> already exists! Please "
1484 "choose a different id and retry.",
1489 if (poly_points->GetNumberOfPoints() < 2) {
1499 actor->GetProperty()->SetRepresentationToSurface();
1500 actor->GetProperty()->SetLineWidth(
width);
1501 actor->GetProperty()->SetColor(r, g, b);
1505 (*getShapeActorMap())[
id] = actor;
1511 if (textParam.
text.isEmpty()) {
1517 const std::string& viewID = text;
1519 int viewport =
context.defaultViewPort;
1520 int xPos =
static_cast<int>(textParam.
textPos.
x);
1521 int yPos =
static_cast<int>(textParam.
textPos.
y);
1528 if (contains(viewID)) {
1529 removeShapes(viewID, viewport);
1533 textColor.
b, viewID, viewport);
1535 if (!updateText(text, xPos, yPos, viewID)) {
1536 addText(text, xPos, yPos, textParam.
font.pointSize(), textColor.
r,
1537 textColor.
g, textColor.
b, viewID, viewport);
1546 materials ? materials->size() : 0);
1549 if (!contains(viewID))
return false;
1551 if (!actor)
return false;
1553 if (!materials || materials->empty()) {
1559 vtkPolyData* polydata =
nullptr;
1560 vtkPolyDataMapper* mapper =
1561 vtkPolyDataMapper::SafeDownCast(actor->GetMapper());
1563 polydata = vtkPolyData::SafeDownCast(mapper->GetInput());
1570 bool success = texture_render_manager_->Update(actor, materials, polydata,
1579 const std::string&
id,
1582 id.c_str(), mesh.tex_materials.size());
1584 pcl::visualization::CloudActorMap::iterator am_it =
1585 getCloudActorMap()->find(
id);
1586 if (am_it != getCloudActorMap()->end()) {
1588 "[PCLVis::addTextureMesh] A shape with id <%s> already exists!"
1589 " Please choose a different id and retry.",
1594 if (mesh.tex_materials.empty()) {
1595 CVLog::Error(
"[PCLVis::addTextureMesh] No textures found!");
1599 if (mesh.tex_materials.size() != mesh.tex_polygons.size()) {
1601 "[PCLVis::addTextureMesh] Materials number %lu differs from "
1602 "polygons number %lu!",
1603 mesh.tex_materials.size(), mesh.tex_polygons.size());
1607 if (mesh.tex_materials.size() != mesh.tex_coordinates.size()) {
1609 "[PCLVis::addTextureMesh] Coordinates number %lu differs from "
1610 "materials number %lu!",
1611 mesh.tex_coordinates.size(), mesh.tex_materials.size());
1615 std::size_t nb_vertices = 0;
1616 for (
const auto& tex_polygon : mesh.tex_polygons)
1617 nb_vertices += tex_polygon.size();
1619 if (nb_vertices == 0) {
1620 CVLog::Error(
"[PCLVis::addTextureMesh] No vertices found!");
1628 bool has_color =
false;
1631 bool has_normal =
false;
1635 has_color = (pcl::getFieldIndex(mesh.cloud,
"rgba") != -1) ||
1636 (pcl::getFieldIndex(mesh.cloud,
"rgb") != -1);
1637 has_normal = (pcl::getFieldIndex(mesh.cloud,
"normal_x") != -1) &&
1638 (pcl::getFieldIndex(mesh.cloud,
"normal_y") != -1) &&
1639 (pcl::getFieldIndex(mesh.cloud,
"normal_z") != -1);
1641 if (has_color && !has_normal) {
1644 if (cloud.points.empty()) {
1645 CVLog::Error(
"[PCLVis::addTextureMesh] Cloud is empty!");
1648 convertToVtkMatrix(cloud.sensor_origin_, cloud.sensor_orientation_,
1650 colors->SetNumberOfComponents(3);
1652 poly_points->SetNumberOfPoints(cloud.size());
1653 for (std::size_t i = 0; i < cloud.points.size(); ++i) {
1654 const pcl::PointXYZRGB& p = cloud.points[i];
1655 poly_points->InsertPoint((vtkIdType)i, p.x, p.y, p.z);
1656 const unsigned char color[3] = {p.r, p.g, p.b};
1659 }
else if (!has_color && has_normal) {
1662 if (cloud.points.empty()) {
1663 CVLog::Error(
"[PCLVis::addTextureMesh] Cloud is empty!");
1666 convertToVtkMatrix(cloud.sensor_origin_, cloud.sensor_orientation_,
1668 normals->SetNumberOfComponents(3);
1670 poly_points->SetNumberOfPoints(cloud.size());
1671 for (std::size_t i = 0; i < cloud.points.size(); ++i) {
1672 const PointNT& p = cloud.points[i];
1673 poly_points->InsertPoint(i, p.x, p.y, p.z);
1674 const float normal[3] = {p.normal_x, p.normal_y, p.normal_z};
1677 }
else if (has_color && has_normal) {
1680 if (cloud.points.empty()) {
1681 CVLog::Error(
"[PCLVis::addTextureMesh] Cloud is empty!");
1684 convertToVtkMatrix(cloud.sensor_origin_, cloud.sensor_orientation_,
1686 normals->SetNumberOfComponents(3);
1688 colors->SetNumberOfComponents(3);
1690 poly_points->SetNumberOfPoints(cloud.size());
1691 for (std::size_t i = 0; i < cloud.points.size(); ++i) {
1693 poly_points->InsertPoint(i, p.x, p.y, p.z);
1694 const unsigned char color[3] = {p.r, p.g, p.b};
1696 const float normal[3] = {p.normal_x, p.normal_y, p.normal_z};
1699 }
else if (!has_color && !has_normal) {
1703 if (cloud->points.empty()) {
1704 CVLog::Error(
"[PCLVis::addTextureMesh] Cloud is empty!");
1707 convertToVtkMatrix(cloud->sensor_origin_, cloud->sensor_orientation_,
1709 poly_points->SetNumberOfPoints(cloud->size());
1710 for (std::size_t i = 0; i < cloud->size(); ++i) {
1711 const pcl::PointXYZ& p = (*cloud)[i];
1712 poly_points->InsertPoint(i, p.x, p.y, p.z);
1718 for (
const auto& tex_polygon : mesh.tex_polygons) {
1719 for (
const auto& vertex : tex_polygon) {
1720 polys->InsertNextCell(
static_cast<int>(vertex.vertices.size()));
1721 for (
const auto& point : vertex.vertices)
1722 polys->InsertCellPoint(point);
1727 polydata->SetPolys(polys);
1728 polydata->SetPoints(poly_points);
1729 if (has_color) polydata->GetPointData()->SetScalars(
colors);
1730 if (has_normal) polydata->GetPointData()->SetNormals(
normals);
1734 mapper->SetInputData(polydata);
1739 std::size_t nb_coordinates = 0;
1740 for (
const auto& tex_coordinate : mesh.tex_coordinates)
1741 nb_coordinates += tex_coordinate.size();
1748 bool has_pbr =
false;
1749 if (!mesh.tex_materials.empty()) {
1750 std::string tex_name = mesh.tex_materials[0].tex_name;
1751 has_pbr = (tex_name.find(
"_PBR_MULTITEX") != std::string::npos);
1754 "[PCLVis::addTextureMesh] Detected PBR material encoding "
1755 "(pcl::TextureMesh): %s",
1760 if (nb_coordinates == 0) {
1762 "[PCLVisualizer::addTextureMesh] No textures coordinates "
1770 "[PCLVis::addTextureMesh] Setting up texture coordinates for "
1771 "unified rendering");
1776 for (std::size_t tex_id = 0; tex_id < mesh.tex_coordinates.size();
1780 coordinates->SetNumberOfComponents(2);
1781 std::stringstream ss;
1782 if (mesh.tex_coordinates.size() == 1) {
1785 ss <<
"TCoords" << tex_id;
1787 std::string coords_name = ss.str();
1788 coordinates->SetName(coords_name.c_str());
1791 for (
const auto& tc : mesh.tex_coordinates[tex_id]) {
1792 coordinates->InsertNextTuple2(tc[0], tc[1]);
1795 polydata->GetPointData()->AddArray(coordinates);
1799 polydata->GetPointData()->SetTCoords(coordinates);
1808 actor->SetMapper(mapper);
1813 if (!mesh.tex_materials.empty()) {
1815 "[PCLVis::addTextureMesh] Applying materials using "
1816 "TextureRenderManager");
1822 actor, mesh, polydata, texture_render_manager_.get(), renderer);
1826 (*getCloudActorMap())[
id].actor = actor;
1831 transformation_map_[id] = transformation;
1832 (*getCloudActorMap())[
id].viewpoint_transformation_ = transformation.Get();
1838 const std::string&
id,
1841 "[PCLVis::addTextureMeshFromCCMesh] ENTRY: id=%s, viewport=%d",
1842 id.c_str(), viewport);
1845 CVLog::Error(
"[PCLVis::addTextureMeshFromCCMesh] Mesh is null!");
1852 pcl::visualization::CloudActorMap::iterator am_it =
1853 getCloudActorMap()->find(
id);
1854 if (am_it != getCloudActorMap()->end()) {
1856 "[PCLVis::addTextureMeshFromCCMesh] Actor with id <%s> already "
1857 "exists, removing old actor before adding new one",
1859 vtkActor* oldActor = am_it->second.actor;
1864 transformation_map_.erase(
id);
1865 getCloudActorMap()->erase(am_it);
1869 if (!materials || materials->empty()) {
1871 "[PCLVis::addTextureMeshFromCCMesh] No materials found in "
1881 "[PCLVis::addTextureMeshFromCCMesh] Failed to get point cloud "
1894 std::vector<std::vector<Eigen::Vector2f>> tex_coordinates;
1898 "[PCLVis::addTextureMeshFromCCMesh] Failed to convert mesh to "
1899 "vtkPolyData with textures!");
1906 mapper->SetInputData(polydata);
1909 actor->SetMapper(mapper);
1917 actor, materials, tex_coordinates, polydata,
1918 texture_render_manager_.get(), renderer);
1922 "[PCLVis::addTextureMeshFromCCMesh] Failed to apply textures!");
1927 (*getCloudActorMap())[
id].actor = actor;
1930 transformation_map_[id] = transformation;
1931 (*getCloudActorMap())[
id].viewpoint_transformation_ = transformation.Get();
1934 "[PCLVis::addTextureMeshFromCCMesh] Successfully added mesh "
1935 "with %zu materials",
1947 const std::string&
id,
1951 pcl::visualization::ShapeActorMap::iterator am_it =
1952 getShapeActorMap()->find(
id);
1953 if (am_it != getShapeActorMap()->end()) {
1955 "[PCLVis::addCube] A shape with id <%s> already exists!"
1956 " Please choose a different id and retry.",
1970 actor->GetProperty()->SetRepresentationToSurface();
1971 actor->GetProperty()->SetColor(r, g, b);
1975 (*getShapeActorMap())[
id] = actor;
1981 const Eigen::Quaternionf&
rotation,
1988 const std::string&
id,
1992 pcl::visualization::ShapeActorMap::iterator am_it =
1993 getShapeActorMap()->find(
id);
1994 if (am_it != getShapeActorMap()->end()) {
1996 "[PCLVis::addCube] A shape with id <%s> already exists!"
1997 " Please choose a different id and retry.",
2011 actor->GetProperty()->SetRepresentationToSurface();
2012 actor->GetProperty()->SetColor(r, g, b);
2016 (*getShapeActorMap())[
id] = actor;
2022 const std::string&
id,
2026 pcl::visualization::ShapeActorMap::iterator am_it =
2027 getShapeActorMap()->find(
id);
2028 if (am_it != getShapeActorMap()->end()) {
2030 "[PCLVis::addCube] A shape with id <%s> already exists!"
2031 " Please choose a different id and retry.",
2036 std::shared_ptr<cloudViewer::geometry::LineSet> linePoints =
2047 actor->GetProperty()->SetRepresentationToSurface();
2053 (*getShapeActorMap())[
id] = actor;
2062 const std::string& viewID,
2064 int opacity = visibility ? 1 : 0;
2068 actor->SetVisibility(opacity);
2074 const std::string& viewID,
2080 assert(wa_it->second.widget);
2082 visibility ? wa_it->second.widget->On() : wa_it->second.widget->Off();
2088 bool removeFlag =
false;
2090 int viewport =
context.defaultViewPort;
2091 switch (
context.removeEntityType) {
2093 removePointClouds(removeViewID, viewport);
2098 removeMesh(removeViewID, viewport);
2099 removePointClouds(removeViewID, viewport);
2106 removeShapes(removeViewID, viewport);
2107 removePointClouds(removeViewID, viewport);
2111 removeText3D(removeViewID, viewport);
2116 removeText2D(removeViewID, viewport);
2121 removeWidgets(removeViewID, viewport);
2124 removeALL(viewport);
2135 bool PCLVis::removeWidgets(
const std::string& viewId,
int viewport) {
2137 PclUtils::WidgetActorMap::iterator wa_it =
m_widget_map->find(viewId);
2142 if (wa_it->second.widget) {
2144 wa_it->second.widget->Off();
2151 void PCLVis::removePointClouds(
const std::string& viewId,
int viewport) {
2152 if (contains(viewId)) {
2153 removePointCloud(viewId, viewport);
2157 std::string normalViewId = viewId +
"-normal";
2158 if (contains(normalViewId)) {
2159 removePointCloud(normalViewId, viewport);
2166 void PCLVis::removeShapes(
const std::string& viewId,
int viewport) {
2167 if (contains(viewId)) {
2168 removeShape(viewId, viewport);
2175 void PCLVis::removeMesh(
const std::string& viewId,
int viewport) {
2176 if (contains(viewId)) {
2177 removePolygonMesh(viewId, viewport);
2184 void PCLVis::removeText3D(
const std::string& viewId,
int viewport) {
2185 if (contains(viewId)) {
2186 removeText3D(viewId, viewport);
2190 void PCLVis::removeText2D(
const std::string& viewId,
int viewport) {
2191 if (contains(viewId)) {
2192 removeShapes(viewId, viewport);
2196 void PCLVis::removeALL(
int viewport) {
2197 removeAllPointClouds(viewport);
2198 removeAllShapes(viewport);
2206 double r,
double g,
double b,
const std::string& viewID,
int viewport) {
2207 if (contains(viewID)) {
2208 setPointCloudRenderingProperties(
2209 pcl::visualization::PCL_VISUALIZER_COLOR, r, g, b, viewID,
2217 vtkLODActor* actor = vtkLODActor::SafeDownCast(
getActorById(viewID));
2221 actor->GetMapper()->ScalarVisibilityOn();
2223 actor->GetMapper()->ScalarVisibilityOff();
2230 float r,
float g,
float b,
const std::string& viewID,
int viewport) {
2231 if (contains(viewID)) {
2232 setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, r,
2233 g, b, viewID, viewport);
2238 const std::string& viewID,
2240 unsigned char size = pointSize > 16 ? 16 : pointSize;
2241 size = pointSize < 1 ? 1 : pointSize;
2242 if (contains(viewID)) {
2243 setPointCloudRenderingProperties(
2244 pcl::visualization::PCL_VISUALIZER_POINT_SIZE,
size, viewID,
2251 int scalarFieldIndex,
2253 if (!contains(viewID) || !cloud) {
2262 "[PCLVis::addScalarFieldToVTK] Invalid scalar field index");
2267 std::string scalarFieldName = sfName.toStdString();
2270 pcl::visualization::CloudActorMap::iterator am_it =
2271 getCloudActorMap()->find(viewID);
2272 if (am_it == getCloudActorMap()->end()) {
2276 vtkActor* actor = am_it->second.actor;
2282 vtkMapper* mapper = actor->GetMapper();
2287 vtkPolyData* polyData = vtkPolyData::SafeDownCast(mapper->GetInput());
2292 vtkPointData* pointData = polyData->GetPointData();
2293 vtkDataArray* activeScalars = pointData->GetScalars();
2296 vtkDataArray* existingArray = pointData->GetArray(scalarFieldName.c_str());
2297 if (existingArray && existingArray->GetNumberOfComponents() == 1) {
2300 "'%1' already exists, skipping")
2313 vtkIdType numPoints = polyData->GetNumberOfPoints();
2316 scalarArray->SetName(scalarFieldName.c_str());
2317 scalarArray->SetNumberOfComponents(1);
2318 scalarArray->SetNumberOfTuples(numPoints);
2321 unsigned cloudSize = cloud->
size();
2322 if (
static_cast<vtkIdType
>(cloudSize) != numPoints) {
2323 CVLog::Warning(QString(
"[PCLVis::addScalarFieldToVTK] Size mismatch: "
2324 "ccCloud=%1, VTK=%2")
2330 for (vtkIdType i = 0; i < numPoints; ++i) {
2331 float scalarValue =
static_cast<float>(
2332 scalarField->
getValue(
static_cast<unsigned>(i)));
2333 scalarArray->SetValue(i, scalarValue);
2339 pointData->AddArray(scalarArray);
2344 vtkFieldData* fieldData = polyData->GetFieldData();
2346 vtkStringArray* datasetNameArray = vtkStringArray::SafeDownCast(
2347 fieldData->GetAbstractArray(
"DatasetName"));
2349 if (!datasetNameArray) {
2351 datasetNameArray = vtkStringArray::New();
2352 datasetNameArray->SetName(
"DatasetName");
2353 datasetNameArray->SetNumberOfTuples(1);
2356 QString cloudName = cloud->
getName();
2357 if (cloudName.isEmpty()) {
2358 cloudName = QString::fromStdString(viewID);
2360 datasetNameArray->SetValue(0, cloudName.toStdString());
2361 fieldData->AddArray(datasetNameArray);
2362 datasetNameArray->Delete();
2370 QString(
"[PCLVis::addScalarFieldToVTK] Added scalar array "
2371 "'%1' with %2 values to VTK polydata")
2380 if (!contains(viewID) || !cloud) {
2390 QString(
"[PCLVis::syncAllScalarFieldsToVTK] Syncing %1 scalar "
2391 "fields from ccPointCloud to VTK")
2395 for (
unsigned i = 0; i < sfCount; ++i) {
2405 "object: '%1' (type=%2, viewID='%3')")
2408 .arg(QString::fromStdString(viewID)));
2435 if (!obj)
return nullptr;
2445 if (!obj)
return nullptr;
2448 return static_cast<ccMesh*
>(obj);
2458 const std::string& scalarName,
2460 if (!contains(viewID)) {
2465 pcl::visualization::CloudActorMap::iterator am_it =
2466 getCloudActorMap()->find(viewID);
2467 if (am_it == getCloudActorMap()->end()) {
2471 vtkActor* actor = am_it->second.actor;
2477 vtkMapper* mapper = actor->GetMapper();
2482 vtkPolyData* polyData = vtkPolyData::SafeDownCast(mapper->GetInput());
2487 vtkPointData* pointData = polyData->GetPointData();
2491 vtkDataArray* scalarArray = pointData->GetArray(scalarName.c_str());
2495 pointData->SetActiveScalars(scalarName.c_str());
2497 "scalars to '%1' (%2 components, %3 tuples)")
2498 .arg(QString::fromStdString(scalarName))
2499 .arg(scalarArray->GetNumberOfComponents())
2500 .arg(scalarArray->GetNumberOfTuples()));
2504 vtkDataArray* defaultScalars = pointData->GetScalars();
2505 if (defaultScalars) {
2507 QString(
"[PCLVis::setScalarFieldName] Scalar array '%1' "
2508 "not found, using default scalars")
2509 .arg(QString::fromStdString(scalarName)));
2515 const std::string& viewID,
2517 if (contains(viewID)) {
2519 getPointCloudRenderingProperties(
2520 pcl::visualization::RenderingProperties::PCL_VISUALIZER_OPACITY,
2521 lastOpacity, viewID);
2522 if (opacity != lastOpacity) {
2523 setPointCloudRenderingProperties(
2524 pcl::visualization::RenderingProperties::
2525 PCL_VISUALIZER_OPACITY,
2526 opacity, viewID, viewport);
2532 const std::string& viewID,
2534 if (contains(viewID)) {
2535 setShapeRenderingProperties(
2536 pcl::visualization::RenderingProperties::PCL_VISUALIZER_OPACITY,
2537 opacity, viewID, viewport);
2542 const std::string& viewID,
2545 vtkLODActor* lodActor = vtkLODActor::SafeDownCast(
getActorById(viewID));
2546 vtkActor* actor = lodActor;
2552 CVLog::Warning(
"[PCLVis::setMeshOpacity] Mesh with id <%s> not found",
2558 double currentOpacity = actor->GetProperty()->GetOpacity();
2559 if (std::abs(currentOpacity - opacity) < 0.001) {
2566 actor->GetProperty()->SetOpacity(opacity);
2570 if (opacity < 1.0) {
2573 actor->ForceTranslucentOn();
2574 actor->ForceOpaqueOff();
2578 if (renderer && !renderer->GetUseDepthPeeling()) {
2579 vtkRenderWindow* renderWindow = renderer->GetRenderWindow();
2582 renderWindow->SetAlphaBitPlanes(1);
2588 renderer->SetUseDepthPeeling(1);
2590 renderer->SetMaximumNumberOfPeels(4);
2592 renderer->SetOcclusionRatio(0.0);
2596 actor->ForceTranslucentOff();
2597 actor->ForceOpaqueOn();
2604 opacity, viewID.c_str());
2608 const std::string& viewID,
2610 if (contains(viewID)) {
2611 setShapeRenderingProperties(
2612 pcl::visualization::RenderingProperties::PCL_VISUALIZER_SHADING,
2613 mode, viewID, viewport);
2618 const std::string& viewID,
2623 "[PCLVis::SetMeshRenderingMode] Requested viewID not found, "
2624 "please check again...");
2630 actor->GetProperty()->SetInterpolationToFlat();
2634 if (!actor->GetMapper()->GetInput()->GetPointData()->GetNormals()) {
2636 "[PCLVis::setMeshShadingMode] Normals do not exist in "
2637 "the dataset, but Gouraud shading was requested. "
2638 "Estimating normals...");
2641 normals->SetInputConnection(actor->GetMapper()
2642 ->GetInputAlgorithm()
2644 vtkDataSetMapper::SafeDownCast(actor->GetMapper())
2645 ->SetInputConnection(
normals->GetOutputPort());
2647 actor->GetProperty()->SetInterpolationToGouraud();
2651 if (!actor->GetMapper()->GetInput()->GetPointData()->GetNormals()) {
2653 "[pcl::visualization::PCLVisualizer::"
2654 "setShapeRenderingProperties] Normals do not exist in "
2655 "the dataset, but Phong shading was requested. "
2656 "Estimating normals...");
2659 normals->SetInputConnection(actor->GetMapper()
2660 ->GetInputAlgorithm()
2662 vtkDataSetMapper::SafeDownCast(actor->GetMapper())
2663 ->SetInputConnection(
normals->GetOutputPort());
2665 actor->GetProperty()->SetInterpolationToPhong();
2673 const std::string& viewID,
2678 "[PCLVis::SetMeshRenderingMode] Requested viewID not found, "
2679 "please check again...");
2684 actor->GetProperty()->SetRepresentationToPoints();
2688 actor->GetProperty()->SetRepresentationToWireframe();
2692 actor->GetProperty()->SetRepresentationToSurface();
2703 actor->GetProperty()->SetLighting(
false);
2709 const std::string& viewID,
2713 actor->GetProperty()->SetLineWidth(
float(lineWidth));
2724 pcl::visualization::Camera camera;
2730 vtkInteractorObserver* currentStyle =
2734 pcl::visualization::PCLVisualizerInteractorStyle* pclStyle =
2735 dynamic_cast<pcl::visualization::PCLVisualizerInteractorStyle*
>(
2740 this->getCameraParameters(camera);
2747 double pos[3], focal[3], viewUp[3], clipRange[2];
2748 vtkCam->GetPosition(pos);
2749 vtkCam->GetFocalPoint(focal);
2750 vtkCam->GetViewUp(viewUp);
2751 vtkCam->GetClippingRange(clipRange);
2753 camera.pos[0] = pos[0];
2754 camera.pos[1] = pos[1];
2755 camera.pos[2] = pos[2];
2756 camera.focal[0] = focal[0];
2757 camera.focal[1] = focal[1];
2758 camera.focal[2] = focal[2];
2759 camera.view[0] = viewUp[0];
2760 camera.view[1] = viewUp[1];
2761 camera.view[2] = viewUp[2];
2762 camera.clip[0] = clipRange[0];
2763 camera.clip[1] = clipRange[1];
2764 camera.fovy = vtkCam->GetViewAngle() *
M_PI /
2783 int flag = cam->GetParallelProjection();
2785 cam->SetParallelScale(scale);
2791 return this->
getVtkCamera(viewport)->GetParallelScale();
2796 int flag = cam->GetParallelProjection();
2798 cam->SetParallelProjection(
true);
2806 int flag = cam->GetParallelProjection();
2808 cam->SetParallelProjection(
false);
2815 return !
getVtkCamera(viewport)->GetParallelProjection();
2828 getInteractorStyle()->GetInteractor()->GetPicker());
2831 getInteractorStyle()->GetInteractor()->SetPicker(
m_area_picker);
2837 getInteractorStyle()->GetInteractor()->SetPicker(
m_point_picker);
2841 getRendererCollection()->Render();
2842 getInteractorStyle()->GetInteractor()->Render();
2859 if (!interactor)
return;
2880 "Orientation Widget Axes was already disabled, doing "
2884 "Attempted to delete Orientation Widget Axes which does not "
2890 vtkRenderWindowInteractor* interactor) {
2893 1.5,
"x",
"y",
"z",
"R",
"L",
"A",
"P",
"I",
"S");
2916 "Attempted to delete Orientation Widget Axes which does not "
2925 auto collection = getRendererCollection();
2930 int itemsNumber = collection->GetNumberOfItems();
2931 if (itemsNumber == 0) {
2935 if (viewport == 0 || viewport + 1 > itemsNumber) {
2936 return collection->GetFirstRenderer();
2939 collection->InitTraversal();
2940 vtkRenderer* renderer =
nullptr;
2942 while ((renderer = collection->GetNextItem())) {
2943 if (viewport == i) {
2949 return collection->GetFirstRenderer();
2954 return getInteractorStyle();
2960 pcl::visualization::CloudActorMap::iterator ca_it =
2961 getCloudActorMap()->find(viewId);
2963 pcl::visualization::ShapeActorMap::iterator am_it =
2964 getShapeActorMap()->find(viewId);
2968 if (am_it == getShapeActorMap()->end()) {
2970 if (ca_it == getCloudActorMap()->end()) {
2973 "[getActorById] Could not find any PointCloud or Shape "
2974 "datasets with id <%s>!",
2988 prop = vtkLODActor::SafeDownCast(am_it->second);
2990 prop = vtkActor::SafeDownCast(am_it->second);
2993 prop = vtkPropAssembly::SafeDownCast(am_it->second);
2996 prop = vtkLODActor::SafeDownCast(ca_it->second.actor);
2998 prop = vtkActor::SafeDownCast(ca_it->second.actor);
3004 if (!prop)
return nullptr;
3010 const std::string& viewId) {
3013 collections->InitTraversal();
3016 prop->InitPathTraversal();
3017 prop->GetActors(collections);
3026 pcl::visualization::CloudActorMap::iterator ca_it =
3027 getCloudActorMap()->find(viewId);
3029 pcl::visualization::ShapeActorMap::iterator am_it =
3030 getShapeActorMap()->find(viewId);
3034 if (am_it == getShapeActorMap()->end()) {
3036 if (ca_it == getCloudActorMap()->end()) {
3039 "[getActorById] Could not find any PointCloud or Shape "
3040 "datasets with id <%s>!",
3054 actor = vtkLODActor::SafeDownCast(am_it->second);
3056 actor = vtkActor::SafeDownCast(am_it->second);
3059 actor = vtkLODActor::SafeDownCast(ca_it->second.actor);
3061 actor = vtkActor::SafeDownCast(ca_it->second.actor);
3067 if (!actor)
return nullptr;
3076 return wa_it->second.widget;
3082 pcl::visualization::CloudActorMap::iterator cloudIt =
3083 getCloudActorMap()->begin();
3085 pcl::visualization::ShapeActorMap::iterator shapeIt =
3086 getShapeActorMap()->begin();
3088 for (; cloudIt != getCloudActorMap()->end(); cloudIt++) {
3089 vtkActor* tempActor = vtkLODActor::SafeDownCast(cloudIt->second.actor);
3090 if (tempActor && tempActor == actor) {
3091 return cloudIt->first;
3095 for (; shapeIt != getShapeActorMap()->end(); shapeIt++) {
3096 vtkActor* tempActor = vtkLODActor::SafeDownCast(shapeIt->second);
3097 if (tempActor && tempActor == actor) {
3098 return shapeIt->first;
3102 return std::string(
"");
3107 vtkProp* actor_to_remove = vtkProp::SafeDownCast(actor);
3110 getRendererCollection()->InitTraversal();
3111 vtkRenderer* renderer =
nullptr;
3113 while ((renderer = getRendererCollection()->GetNextItem()) !=
nullptr) {
3115 if (viewport == 0) {
3116 renderer->RemoveActor(actor);
3117 }
else if (viewport ==
3121 vtkPropCollection* actors = renderer->GetViewProps();
3122 actors->InitTraversal();
3123 vtkProp* current_actor =
nullptr;
3124 while ((current_actor = actors->GetNextProp()) !=
nullptr) {
3125 if (current_actor != actor_to_remove)
continue;
3126 renderer->RemoveActor(actor);
3133 if (viewport == 0)
return (
true);
3140 getRendererCollection()->InitTraversal();
3141 vtkRenderer* renderer =
nullptr;
3143 while ((renderer = getRendererCollection()->GetNextItem()) !=
nullptr) {
3145 if (viewport == 0) {
3146 renderer->AddActor(actor);
3147 }
else if (viewport ==
3150 renderer->AddActor(actor);
3159 if (getRenderWindow()) {
3160 getRenderWindow()->Render();
3165 vtkRenderWindow* win) {
3166 this->interactor_ = iren;
3167 pcl::visualization::PCLVisualizer::setupInteractor(iren, win);
3175 void PCLVis::registerKeyboard() {
3177 registerKeyboardCallback(&PCLVis::keyboardEventProcess, *
this);
3179 "[annotation keyboard Event] press Delete to remove annotations");
3183 void PCLVis::registerMouse() {
3185 registerMouseCallback(&PCLVis::mouseEventProcess, *
this);
3187 "[annotation mouse Event] click left button to pick annotation");
3191 void PCLVis::registerPointPicking() {
3193 registerPointPickingCallback(&PCLVis::pointPickingProcess, *
this);
3194 CVLog::Print(
"[global pointPicking] SHIFT + left click to select a point!");
3198 void PCLVis::registerInteractorStyle(
bool useDefault) {
3202 manip->SetButton(1);
3207 manip2->SetButton(3);
3212 manip3->SetButton(2);
3221 manip4->SetButton(1);
3226 manip5->SetButton(3);
3233 int manipulators[9];
3235 manipulators[0] = 4;
3236 manipulators[3] = 1;
3237 manipulators[6] = 3;
3239 manipulators[1] = 1;
3240 manipulators[4] = 4;
3241 manipulators[7] = 3;
3243 manipulators[2] = 2;
3244 manipulators[5] = 1;
3245 manipulators[8] = 6;
3249 manipulators[0] = 1;
3250 manipulators[3] = 2;
3251 manipulators[6] = 3;
3253 manipulators[1] = 3;
3254 manipulators[4] = 2;
3255 manipulators[7] = 1;
3257 manipulators[2] = 2;
3258 manipulators[5] = 6;
3259 manipulators[8] = 4;
3264 void PCLVis::registerAreaPicking() {
3266 registerAreaPickingCallback(&PCLVis::areaPickingEventProcess, *
this);
3267 CVLog::Print(
"[global areaPicking] press A to start or ending picking!");
3271 void PCLVis::pointPickingProcess(
3272 const pcl::visualization::PointPickingEvent&
event,
void* args) {
3275 int idx =
event.getPointIndex();
3276 if (idx == -1)
return;
3281 event.getPoint(picked_pt.
x, picked_pt.
y, picked_pt.
z);
3282 std::string
id =
pickItem(-1, -1, 3.0, 3.0);
3286 void PCLVis::areaPickingEventProcess(
3287 const pcl::visualization::AreaPickingEvent&
event,
void* args) {
3299 void PCLVis::keyboardEventProcess(
3300 const pcl::visualization::KeyboardEvent&
event,
void* args) {
3302 if (
event.keyDown())
3308 void PCLVis::mouseEventProcess(
const pcl::visualization::MouseEvent&
event,
3312 if (
event.getButton() == pcl::visualization::MouseEvent::RightButton &&
3313 event.getType() == pcl::visualization::MouseEvent::MouseButtonPress) {
3328 m_propPicker->Pick(
x,
y, 0, getRendererCollection()->GetFirstRenderer());
3341 m_area_picker->AreaPick(pos[0], pos[1], pos[0] + x1, pos[1] + y1,
3342 getRendererCollection()->GetFirstRenderer());
3347 return std::string(
"-1");
3352 bool renderOverlayItems,
3355 bool coords_changed =
false;
3356 bool lengend_changed =
false;
3359 if (lengend_shown) {
3361 lengend_changed =
true;
3363 if (renderOverlayItems) {
3364 if (!coords_shown) {
3366 coords_changed =
true;
3371 coords_changed =
true;
3377 windowToImageFilter->SetInput(getRenderWindow());
3378 #if VTK_MAJOR_VERSION > 8 || VTK_MAJOR_VERSION == 8 && VTK_MINOR_VERSION >= 1
3379 windowToImageFilter->SetScale(zoomFactor);
3381 windowToImageFilter->SetMagnification(zoomFactor);
3383 windowToImageFilter->SetInputBufferTypeToRGBA();
3385 windowToImageFilter->ReadFrontBufferOff();
3386 windowToImageFilter->Update();
3388 vtkImageData* imageData = windowToImageFilter->GetOutput();
3391 CVLog::Error(
"[PCLVis::renderToImage] invalid vtkImageData!");
3394 int width = imageData->GetDimensions()[0];
3395 int height = imageData->GetDimensions()[1];
3397 QImage outputImage(
width,
height, QImage::Format_RGB32);
3399 reinterpret_cast<QRgb*
>(outputImage.bits()) +
width * (
height - 1);
3400 unsigned char* colorsPtr =
3401 reinterpret_cast<unsigned char*
>(imageData->GetScalarPointer());
3405 "[PCLVis::renderToImage] invalid scalar pointer of "
3411 for (
int row = 0; row <
height; row++) {
3412 for (
int col = 0; col <
width; col++) {
3415 QColor(colorsPtr[0], colorsPtr[1], colorsPtr[2]).rgb();
3416 colorsPtr += imageData->GetNumberOfScalarComponents();
3419 rgbPtr -=
width * 2;
3422 if (outputImage.isNull()) {
3425 "[PCLVis::renderToImage] Direct screen capture failed! "
3426 "(not enough memory?)");
3429 if (lengend_changed) {
3433 if (coords_changed) {
3455 CVLog::Warning(
"[PCLVis] No renderer available for light control");
3460 renderer->RemoveAllLights();
3464 light->SetLightTypeToHeadlight();
3466 light->SetColor(1.0, 1.0, 1.0);
3468 renderer->AddLight(
light);
3471 renderer->LightFollowCameraOn();
3475 vtkActorCollection* actors = renderer->GetActors();
3477 actors->InitTraversal();
3478 vtkActor* actor = actors->GetNextActor();
3480 vtkProperty* prop = actor->GetProperty();
3483 prop->SetLighting(
true);
3488 bool isPointCloud =
false;
3489 vtkMapper* mapper = actor->GetMapper();
3491 vtkPolyData* polydata =
3492 vtkPolyData::SafeDownCast(mapper->GetInput());
3497 vtkIdType numPoints = polydata->GetNumberOfPoints();
3498 vtkIdType numCells = polydata->GetNumberOfCells();
3502 isPointCloud = (numCells == 0) ||
3503 (numCells >= numPoints * 0.9);
3517 double baseAmbient =
3519 double baseDiffuse = 0.3;
3520 double ambient = baseAmbient +
3522 double diffuse = baseDiffuse +
3524 prop->SetAmbient(ambient);
3525 prop->SetDiffuse(diffuse);
3526 prop->SetSpecular(0.1);
3530 prop->SetAmbient(0.3);
3531 prop->SetDiffuse(0.7);
3536 actor = actors->GetNextActor();
3541 vtkRenderWindow* win = getRenderWindow();
3557 CVLog::Warning(
"[PCLVis] No renderer available for Data Axes Grid");
3564 if (!dataAxesGrid) {
3568 dataAxesGrid->SetCamera(renderer->GetActiveCamera());
3573 dataAxesGrid->SetXAxisVisibility(1);
3574 dataAxesGrid->SetYAxisVisibility(1);
3575 dataAxesGrid->SetZAxisVisibility(1);
3578 dataAxesGrid->SetXAxisTickVisibility(1);
3579 dataAxesGrid->SetYAxisTickVisibility(1);
3580 dataAxesGrid->SetZAxisTickVisibility(1);
3583 dataAxesGrid->SetXAxisMinorTickVisibility(1);
3584 dataAxesGrid->SetYAxisMinorTickVisibility(1);
3585 dataAxesGrid->SetZAxisMinorTickVisibility(1);
3588 dataAxesGrid->SetFlyModeToOuterEdges();
3592 for (
int i = 0; i < 3; i++) {
3593 vtkTextProperty* titleProp = dataAxesGrid->GetTitleTextProperty(i);
3595 titleProp->SetColor(1.0, 1.0, 1.0);
3596 titleProp->SetFontFamilyToArial();
3597 titleProp->SetFontSize(18);
3598 titleProp->SetBold(0);
3599 titleProp->SetItalic(0);
3602 vtkTextProperty* labelProp = dataAxesGrid->GetLabelTextProperty(i);
3604 labelProp->SetColor(1.0, 1.0, 1.0);
3605 labelProp->SetFontFamilyToArial();
3606 labelProp->SetFontSize(14);
3607 titleProp->SetBold(0);
3608 titleProp->SetItalic(0);
3613 dataAxesGrid->SetXLabelFormat(
"{:<#6.3g}");
3614 dataAxesGrid->SetYLabelFormat(
"{:<#6.3g}");
3615 dataAxesGrid->SetZLabelFormat(
"{:<#6.3g}");
3618 renderer->AddActor(dataAxesGrid);
3624 dataAxesGrid->SetVisibility(props.
visible ? 1 : 0);
3627 dataAxesGrid->SetXTitle(props.
xTitle.toStdString().c_str());
3628 dataAxesGrid->SetYTitle(props.
yTitle.toStdString().c_str());
3629 dataAxesGrid->SetZTitle(props.
zTitle.toStdString().c_str());
3632 double colorR = props.
color.
x / 255.0;
3633 double colorG = props.
color.
y / 255.0;
3634 double colorB = props.
color.
z / 255.0;
3635 dataAxesGrid->GetXAxesLinesProperty()->SetColor(colorR, colorG, colorB);
3636 dataAxesGrid->GetYAxesLinesProperty()->SetColor(colorR, colorG, colorB);
3637 dataAxesGrid->GetZAxesLinesProperty()->SetColor(colorR, colorG, colorB);
3640 dataAxesGrid->GetXAxesLinesProperty()->SetLineWidth(props.
lineWidth);
3641 dataAxesGrid->GetYAxesLinesProperty()->SetLineWidth(props.
lineWidth);
3642 dataAxesGrid->GetZAxesLinesProperty()->SetLineWidth(props.
lineWidth);
3645 dataAxesGrid->GetXAxesLinesProperty()->SetOpacity(props.
opacity);
3646 dataAxesGrid->GetYAxesLinesProperty()->SetOpacity(props.
opacity);
3647 dataAxesGrid->GetZAxesLinesProperty()->SetOpacity(props.
opacity);
3651 dataAxesGrid->XAxisLabelVisibilityOn();
3652 dataAxesGrid->YAxisLabelVisibilityOn();
3653 dataAxesGrid->ZAxisLabelVisibilityOn();
3655 dataAxesGrid->XAxisLabelVisibilityOff();
3656 dataAxesGrid->YAxisLabelVisibilityOff();
3657 dataAxesGrid->ZAxisLabelVisibilityOff();
3662 dataAxesGrid->DrawXGridlinesOn();
3663 dataAxesGrid->DrawYGridlinesOn();
3664 dataAxesGrid->DrawZGridlinesOn();
3666 dataAxesGrid->DrawXGridlinesOff();
3667 dataAxesGrid->DrawYGridlinesOff();
3668 dataAxesGrid->DrawZGridlinesOff();
3669 dataAxesGrid->DrawXInnerGridlinesOff();
3670 dataAxesGrid->DrawYInnerGridlinesOff();
3671 dataAxesGrid->DrawZInnerGridlinesOff();
3680 xLabelsArray->InsertNextValue(label.second.toStdString().c_str());
3682 dataAxesGrid->SetAxisLabels(0, xLabelsArray);
3684 dataAxesGrid->SetAxisLabels(
3692 yLabelsArray->InsertNextValue(label.second.toStdString().c_str());
3694 dataAxesGrid->SetAxisLabels(1, yLabelsArray);
3696 dataAxesGrid->SetAxisLabels(1,
nullptr);
3703 zLabelsArray->InsertNextValue(label.second.toStdString().c_str());
3705 dataAxesGrid->SetAxisLabels(2, zLabelsArray);
3707 dataAxesGrid->SetAxisLabels(2,
nullptr);
3719 actor->GetBounds(bounds);
3720 if (bounds[1] > bounds[0] && bounds[3] > bounds[2] &&
3721 bounds[5] > bounds[4]) {
3722 dataAxesGrid->SetBounds(bounds);
3725 "[PCLVis] Invalid bounds for Data Axes Grid, axes may "
3726 "not display correctly");
3740 QString viewIDStr = QString::fromStdString(viewID);
3745 if (!node)
return nullptr;
3752 if (found)
return found;
3756 obj = findByViewID(sceneRoot);
3766 double bounds[6] = {minCorner.
x, maxCorner.
x, minCorner.
y,
3767 maxCorner.
y, minCorner.
z, maxCorner.
z};
3768 if (bounds[1] > bounds[0] && bounds[3] > bounds[2] &&
3769 bounds[5] > bounds[4]) {
3770 dataAxesGrid->SetBounds(bounds);
3772 QString(
"[PCLVis] Set axes grid bounds from "
3773 "ccHObject '%1' (viewID: %2): "
3774 "[%.2f, %.2f] x [%.2f, %.2f] x [%.2f, "
3777 .arg(QString::fromStdString(viewID))
3786 "[PCLVis] Invalid bounds calculated from "
3787 "ccHObject for Data Axes Grid");
3791 QString(
"[PCLVis] Invalid bbox for viewID: %1, "
3792 "axes grid bounds not set")
3793 .arg(QString::fromStdString(viewID)));
3797 "found for viewID: %1, axes grid bounds "
3799 .arg(QString::fromStdString(viewID)));
3805 vtkRenderWindow* win = getRenderWindow();
3823 props.
visible = (dataAxesGrid->GetVisibility() != 0);
3827 dataAxesGrid->GetXAxesLinesProperty()->GetColor(
vtkColor);
3829 static_cast<float>(
vtkColor[1] * 255.0),
3830 static_cast<float>(
vtkColor[2] * 255.0));
3832 props.
lineWidth = dataAxesGrid->GetXAxesLinesProperty()->GetLineWidth();
3836 props.
showLabels = (dataAxesGrid->GetXAxisLabelVisibility() != 0);
3837 props.
opacity = dataAxesGrid->GetXAxesLinesProperty()->GetOpacity();
3838 props.
showGrid = (dataAxesGrid->GetDrawXGridlines() != 0);
3841 props.
xTitle = QString::fromUtf8(dataAxesGrid->GetXTitle());
3842 props.
yTitle = QString::fromUtf8(dataAxesGrid->GetYTitle());
3843 props.
zTitle = QString::fromUtf8(dataAxesGrid->GetZTitle());
3854 dataAxesGrid->GetBounds(bounds);
3855 props.
xMin = bounds[0];
3856 props.
xMax = bounds[1];
3857 props.
yMin = bounds[2];
3858 props.
yMax = bounds[3];
3859 props.
zMin = bounds[4];
3860 props.
zMax = bounds[5];
3876 if (!renderer || !interactor) {
3878 "[PCLVis] No renderer or interactor available for Camera "
3879 "Orientation Widget");
3901 vtkRenderer* widgetRenderer =
3903 if (widgetRenderer) {
3905 widgetRenderer->SetViewport(0.8, 0.8, 1.0, 1.0);
3906 widgetRenderer->SetLayer(1);
3907 widgetRenderer->InteractiveOff();
3911 auto* rep = vtkCameraOrientationRepresentation::SafeDownCast(
3915 rep->SetSize(80, 80);
3918 rep->AnchorToUpperRight();
3921 int padding[2] = {10, 10};
3922 rep->SetPadding(padding);
3934 rep->SetVisibility(show);
3943 vtkRenderWindow* win = getRenderWindow();
3949 .arg(show ?
"ON" :
"OFF"));
3958 return rep ? (rep->GetVisibility() != 0) :
false;
3968 if (renderer && it->second) {
3969 renderer->RemoveActor(it->second);
Vector3Tpl< PointCoordinateType > CCVector3
Default 3D Vector.
#define ROTATE(a, i, j, k, l)
pcl::PointCloud< PointRGBNormal > PointCloudRGBNormal
pcl::PointXYZRGBNormal PointRGBNormal
pcl::PointCloud< PointNT > PointCloudNormal
pcl::PointCloud< PointT > PointCloudT
pcl::PCLPointCloud2 PCLCloud
pcl::PointCloud< PointRGB > PointCloudRGB
pcl::TextureMesh PCLTextureMesh
pcl::PointCloud< NormalT > CloudNormal
static bool PrintDebug(const char *format,...)
Same as Print, but works only in Debug mode.
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
static bool Print(const char *format,...)
Prints out a formatted message in console.
static bool PrintVerbose(const char *format,...)
Prints out a verbose formatted message in console.
static bool Error(const char *format,...)
Display an error dialog with formatted message.
bool isActorPickingEnabled()
void setCenterOfRotation(double x, double y, double z)
void resetCenterOfRotation(int viewport=0)
vtkRenderer * getCurrentRenderer(int viewport=0)
vtkBoundingBox GeometryBounds
std::map< std::string, ccHObject * > m_sourceObjectMap
void SetDataAxesGridProperties(const std::string &viewID, const AxesGridProperties &props)
Set Data Axes Grid properties (Unified Interface)
bool isAreaPickingEnabled()
virtual void setCamera3DManipulators(const int manipulators[9])
void hideShowActors(bool visibility, const std::string &viewID, int viewport=0)
void hideShowWidgets(bool visibility, const std::string &viewID, int viewport=0)
vtkSmartPointer< vtkCameraOrientationWidget > m_cameraOrientationWidget
bool m_pointPickingEnabled
WidgetActorMapPtr m_widget_map
Internal list with actor pointers and name IDs for widgets.
void configInteractorStyle(vtkSmartPointer< VTKExtensions::vtkCustomInteractorStyle > interactor_style)
void setParallelScale(double scale, int viewport=0)
ccMesh * getSourceMesh(const std::string &viewID) const
Get the source object as ccMesh.
void setPointCloudUniqueColor(double r, double g, double b, const std::string &viewID, int viewport=0)
bool getCaptionPosition(const std::string &viewID, float &posX, float &posY)
Get caption widget 2D position (normalized coordinates 0.0-1.0)
vtkSmartPointer< vtkPropCollection > getPropCollectionById(const std::string &viewId)
bool addTextureMesh(const PCLTextureMesh &mesh, const std::string &id, int viewport)
Add texture mesh from PCLTextureMesh (deprecated)
void setupInteractor(vtkRenderWindowInteractor *iren, vtkRenderWindow *win)
setupInteractor override to init interactor_
vtkSmartPointer< vtkTransform > getTransformation(const CC_DRAW_CONTEXT &context, const CCVector3d &origin)
void setPerspectiveProjection(int viewport=0)
bool isPointPickingEnabled()
void addScalarFieldToVTK(const std::string &viewID, ccPointCloud *cloud, int scalarFieldIndex, int viewport=0)
Add scalar field data from ccPointCloud to VTK polydata.
vtkSmartPointer< vtkCamera > getVtkCamera(int viewport=0)
void RemoveDataAxesGrid(const std::string &viewID)
Remove Data Axes Grid for a specific object.
virtual void setCamera2DManipulators(const int manipulators[9])
vtkAbstractWidget * getWidgetById(const std::string &viewId)
bool getPerspectiveState(int viewport=0)
void synchronizeGeometryBounds(int viewport=0)
vtkSmartPointer< VTKExtensions::vtkCustomInteractorStyle > ThreeDInteractorStyle
std::map< std::string, vtkSmartPointer< vtkCubeAxesActor > > m_dataAxesGridMap
std::string getIdByActor(vtkProp *actor)
void setLightMode(const std::string &viewID, int viewport=0)
void setPointSize(const unsigned char pointSize, const std::string &viewID, int viewport=0)
void setCurrentSourceObject(ccHObject *obj, const std::string &viewID)
Set the source object for selection operations.
void showOrientationMarkerWidgetAxes(vtkRenderWindowInteractor *interactor)
void setShapeUniqueColor(float r, float g, float b, const std::string &viewID, int viewport=0)
void ToggleCameraOrientationWidget(bool show)
Toggle Camera Orientation Widget visibility (ParaView-style)
bool addTextureMeshFromCCMesh(ccGenericMesh *mesh, const std::string &id, int viewport=0)
Add texture mesh directly from ccGenericMesh (preferred)
bool updateTexture(const CC_DRAW_CONTEXT &context, const ccMaterialSet *materials)
void setRotationFactor(double factor)
vtkSmartPointer< VTKExtensions::vtkPVCenterAxesActor > m_centerAxes
virtual void setCamera2DMouseWheelMotionFactor(double factor)
void hideOrientationMarkerWidgetAxes()
pcl::visualization::Camera getCamera(int viewport=0)
static void ExpandBounds(double bounds[6], vtkMatrix4x4 *matrix)
bool IsCameraOrientationWidgetShown() const
Check if Camera Orientation Widget is shown.
void setLightIntensity(double intensity)
Set global light intensity (ParaView-style)
bool addScalarBar(const CC_DRAW_CONTEXT &context)
void setCameraFocalDistance(double focal_distance, int viewport=0)
vtkSmartPointer< vtkOrientationMarkerWidget > m_axes_widget
vtkSmartPointer< pcl::visualization::PCLVisualizerInteractorStyle > m_interactorStyle
bool m_areaPickingEnabled
void syncAllScalarFieldsToVTK(const std::string &viewID, ccPointCloud *cloud, int viewport=0)
Sync ALL scalar fields from ccPointCloud to VTK polydata.
void setCameraViewAngle(double viewAngle, int viewport=0)
double getCameraFocalDistance(int viewport=0)
void UpdateScreen()
UpdateScreen - Updates/refreshes the render window This method forces a render update after actor cha...
void toggleOrientationMarkerWidgetAxes()
vtkSmartPointer< VTKExtensions::vtkCustomInteractorStyle > get3DInteractorStyle()
PCLVis(vtkSmartPointer< VTKExtensions::vtkCustomInteractorStyle > interactor_style, const std::string &viewerName="", bool initIterator=false, int argc=0, char **argv=nullptr)
Default constructor.
void addActorToRenderer(const vtkSmartPointer< vtkProp > &actor, int viewport=0)
double getGLDepth(int x, int y)
void hidePclMarkerAxes()
Marker Axes.
void expandBounds(double bounds[6], vtkMatrix4x4 *matrix)
ccHObject * getSourceObject(const std::string &viewID) const
Get the source object for a given viewID.
vtkSmartPointer< VTKExtensions::vtkCustomInteractorStyle > TwoDInteractorStyle
virtual void updateCenterAxes()
void setAreaPickingEnabled(bool state)
double getParallelScale(int viewport=0)
void rotateWithAxis(const CCVector2i &pos, const CCVector3d &axis, double angle, int viewport=0)
bool addCaption(const std::string &text, const CCVector2 &pos2D, const CCVector3 &anchorPos, double r, double g, double b, double a, int fontSize=10, const std::string &viewID="caption", bool anchorDragable=false, int viewport=0)
vtkSmartPointer< vtkRenderWindowInteractor > getRenderWindowInteractor()
Get a pointer to the current interactor style used.
void zoomCamera(double zoomFactor, int viewport=0)
void setLineWidth(const unsigned char lineWidth, const std::string &viewID, int viewport=0)
void setPointPickingEnabled(bool state)
virtual void setCamera3DMouseWheelMotionFactor(double factor)
void setShapeOpacity(double opacity, const std::string &viewID, int viewport=0)
void setScalarFieldName(const std::string &viewID, const std::string &scalarName, int viewport=0)
void setAreaPickingMode(bool state)
WidgetActorMapPtr getWidgetActorMap()
Return a pointer to the WidgetActorMap this visualizer uses.
ccPointCloud * getSourceCloud(const std::string &viewID) const
Get the source object as ccPointCloud.
void updateNormals(const CC_DRAW_CONTEXT &context, const PCLCloud::Ptr &smCloud)
QImage renderToImage(int zoomFactor=1, bool renderOverlayItems=false, bool silent=false, int viewport=0)
void setShapeShadingMode(SHADING_MODE mode, const std::string &viewID, int viewport=0)
std::vector< int > m_selected_slice
void setCameraManipulators(VTKExtensions::vtkCustomInteractorStyle *style, const int manipulators[9])
void transformEntities(const CC_DRAW_CONTEXT &context)
bool updateCaption(const std::string &text, const CCVector2 &pos2D, const CCVector3 &anchorPos, double r, double g, double b, double a, int fontSize=10, const std::string &viewID="caption", int viewport=0)
bool addPolyline(const PCLPolygon::ConstPtr pclPolygon, double r, double g, double b, float width=1.0f, const std::string &id="multiline", int viewport=0)
vtkSmartPointer< vtkPropPicker > m_propPicker
vtkSmartPointer< pcl::visualization::PCLVisualizerInteractorStyle > getPCLInteractorStyle()
void setModelViewMatrix(const ccGLMatrixd &viewMat, int viewport=0)
void getReasonableClippingRange(double range[2], int viewport=0)
bool addOrientedCube(const ccGLMatrixd &trans, double width, double height, double depth, double r=1.0, double g=1.0, double b=1.0, const std::string &id="cube", int viewport=0)
void removeSourceObject(const std::string &viewID)
Remove a source object from the map.
bool updateScalarBar(const CC_DRAW_CONTEXT &context)
void showPclMarkerAxes(vtkRenderWindowInteractor *interactor=nullptr)
bool removeEntities(const CC_DRAW_CONTEXT &context)
bool removeActorFromRenderer(const vtkSmartPointer< vtkProp > &actor, int viewport=0)
Internal method. Adds a vtk actor to screen.
void setPointCloudOpacity(double opacity, const std::string &viewID, int viewport=0)
vtkSmartPointer< vtkPointPicker > m_point_picker
bool containWidget(const std::string &id) const
Check if the widgets or props with the given id was already added to this visualizer.
void getModelViewTransformMatrix(Eigen::Matrix4d &view)
void setActorPickingEnabled(bool state)
bool hasSourceObject(const std::string &viewID) const
Check if a source object exists for the given viewID.
double getRotationFactor()
vtkActor * getActorById(const std::string &viewId)
void resetScalarColor(const std::string &viewID, bool flag=true, int viewport=0)
void setOrthoProjection(int viewport=0)
std::string pickItem(double x0=-1, double y0=-1, double x1=5.0, double y1=5.0)
void setMeshShadingMode(SHADING_MODE mode, const std::string &viewID, int viewport=0)
double getLightIntensity() const
Get current global light intensity.
vtkProp * getPropById(const std::string &viewId)
void resetCameraClippingRange(int viewport=0)
void displayText(const CC_DRAW_CONTEXT &context)
void exitCallbackProcess()
bool pclMarkerAxesShown()
void interactorPickedEvent(vtkActor *actor)
void setMeshRenderingMode(MESH_RENDERING_MODE mode, const std::string &viewID, int viewport=0)
bool m_actorPickingEnabled
vtkActor * pickActor(double x, double y)
void setCenterAxesVisibility(bool)
vtkSmartPointer< vtkAreaPicker > m_area_picker
void GetDataAxesGridProperties(const std::string &viewID, AxesGridProperties &props) const
Get Data Axes Grid properties (Unified Interface)
void draw(const CC_DRAW_CONTEXT &context, const PCLCloud::Ptr &smCloud)
void updateShadingMode(const CC_DRAW_CONTEXT &context, PCLCloud &smCloud)
void setMeshOpacity(double opacity, const std::string &viewID, int viewport=0)
Set opacity for mesh (textured or non-textured)
void getCenterOfRotation(double center[3])
void getProjectionTransformMatrix(Eigen::Matrix4d &proj)
static bool ApplyPBRTextures(vtkLODActor *actor, const pcl::TextureMesh &mesh, vtkPolyData *polydata, TextureRenderManager *render_manager, vtkRenderer *renderer)
Apply PBR textures from PCLTextureMesh (deprecated)
static bool ApplyTexturesFromMaterialSet(vtkLODActor *actor, const ccMaterialSet *materials, const std::vector< std::vector< Eigen::Vector2f >> &tex_coordinates, vtkPolyData *polydata, TextureRenderManager *render_manager, vtkRenderer *renderer)
Apply textures from ccMaterialSet with texture coordinates.
vtkCustomInteractorStyle defines an unique, custom VTK based interactory style for PCL Visualizer app...
void AddManipulator(vtkCameraManipulator *m)
void RemoveAllManipulators()
static vtkPVCenterAxesActor * New()
static Vector3Tpl fromArray(const int a[3])
Constructor from an int array.
2D label (typically attached to points)
CC to PCL cloud converter.
bool getVtkPolyDataWithTextures(ccGenericMesh *mesh, vtkSmartPointer< vtkPolyData > &polydata, vtkSmartPointer< vtkMatrix4x4 > &transformation, std::vector< std::vector< Eigen::Vector2f >> &tex_coordinates)
Convert ccGenericMesh to vtkPolyData with texture coordinates Reuses getPclTextureMesh logic to ensur...
Camera (projective) sensor.
Ground-based Laser sensor.
T * data()
Returns a pointer to internal data.
Double version of ccGLMatrixTpl.
virtual const ccMaterialSet * getMaterialSet() const =0
virtual ccGenericPointCloud * getAssociatedCloud() const =0
Returns the vertices cloud.
static cc2DLabel * To2DLabel(ccHObject *obj)
Converts current object to cc2DLabel (if possible)
static ccPointCloud * ToPointCloud(ccHObject *obj, bool *isLockedVertices=nullptr)
Converts current object to 'equivalent' ccPointCloud.
Hierarchical CLOUDVIEWER Object.
QString getViewId() const
unsigned getChildrenNumber() const
Returns the number of children.
virtual ccBBox getDisplayBB_recursive(bool relative)
Returns the bounding-box of this entity and it's children WHEN DISPLAYED.
ccHObject * getChild(unsigned childPos) const
Returns the ith child.
CV_CLASS_ENUM getClassID() const override
Returns class ID.
Mesh (triangle) material.
virtual QString getName() const
Returns object name.
bool isA(CV_CLASS_ENUM type) const
bool isKindOf(CV_CLASS_ENUM type) const
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
Generic sensor interface.
const Vector3Tpl< T > & maxCorner() const
Returns max corner (const)
void getBounds(double bounds[6]) const
const Vector3Tpl< T > & minCorner() const
Returns min corner (const)
bool isValid() const
Returns whether bounding box is valid or not.
const Eigen::Vector3d & GetColor() const
Gets the bounding box color.
ScalarField * getScalarField(int index) const
Returns a pointer to a specific scalar field.
unsigned getNumberOfScalarFields() const
Returns the number of associated (and active) scalar fields.
unsigned size() const override
const char * getScalarFieldName(int index) const
Returns the name of a specific scalar field.
A simple scalar field (to be associated to a point cloud)
ScalarType & getValue(std::size_t index)
LineSet define a sets of lines in 3D. A typical application is to display the point cloud corresponde...
static std::shared_ptr< LineSet > CreateFromOrientedBoundingBox(const ecvOrientedBBox &box)
Factory function to create a LineSet from an OrientedBoundingBox.
static Eigen::Vector3d ToEigen(const Type col[3])
void interactorPointPickedEvent(const CCVector3 &p, int index, const std::string &id)
void interactorAreaPickedEvent(const std::vector< int > &selected_slice)
void interactorKeyboardEvent(const std::string &symKey)
static vtkPVTrackballRotate * New()
static vtkPVTrackballZoom * New()
static vtkTrackballPan * New()
std::unordered_map< std::string, WidgetMap > WidgetActorMap
std::unordered_map< std::string, vtkSmartPointer< vtkProp > > PropActorMap
void vtkColor(const QColor &clr, double *vtkClr)
constexpr Rgb white(MAX, MAX, MAX)
constexpr Rgbaf light(0.66f, 0.66f, 0.66f, 1.00f)
constexpr Rgb red(MAX, 0, 0)
Rgbf FromRgb(const Rgb &color)
Data Axes Grid properties structure Encapsulates all properties for vtkCubeAxesActor configuration.
QList< QPair< double, QString > > xCustomLabels
QList< QPair< double, QString > > yCustomLabels
QList< QPair< double, QString > > zCustomLabels