00001
00002
00003
00004
00005
00006
00007 #include <pcl/point_types.h>
00008 #include <pcl/apps/render_views_tesselated_sphere.h>
00009 #include <vtkCellData.h>
00010 #include <vtkWorldPointPicker.h>
00011 #include <vtkPropPicker.h>
00012 #include <vtkPlatonicSolidSource.h>
00013 #include <vtkLoopSubdivisionFilter.h>
00014 #include <vtkTriangle.h>
00015 #include <vtkTransform.h>
00016 #include <vtkVisibleCellSelector.h>
00017 #include <vtkSelection.h>
00018 #include <vtkCellArray.h>
00019 #include <vtkTransformFilter.h>
00020 #include <vtkCamera.h>
00021 #include <vtkActor.h>
00022 #include <vtkRenderWindow.h>
00023 #include <vtkRenderer.h>
00024 #include <vtkPolyDataMapper.h>
00025
00026
00027
00028 #include <vtkPointPicker.h>
00029
00030 void pcl::apps::RenderViewsTesselatedSphere::generateViews() {
00031
00032 double CoM[3];
00033 vtkIdType npts_com = 0, *ptIds_com = NULL;
00034 vtkSmartPointer<vtkCellArray> cells_com = polydata_->GetPolys ();
00035
00036 double center[3], p1_com[3], p2_com[3], p3_com[3], area_com, totalArea_com = 0;
00037 double comx = 0, comy = 0, comz = 0;
00038 for (cells_com->InitTraversal (); cells_com->GetNextCell (npts_com, ptIds_com);)
00039 {
00040 polydata_->GetPoint (ptIds_com[0], p1_com);
00041 polydata_->GetPoint (ptIds_com[1], p2_com);
00042 polydata_->GetPoint (ptIds_com[2], p3_com);
00043 vtkTriangle::TriangleCenter (p1_com, p2_com, p3_com, center);
00044 area_com = vtkTriangle::TriangleArea (p1_com, p2_com, p3_com);
00045 comx += center[0] * area_com;
00046 comy += center[1] * area_com;
00047 comz += center[2] * area_com;
00048 totalArea_com += area_com;
00049 }
00050
00051 CoM[0] = comx / totalArea_com;
00052 CoM[1] = comy / totalArea_com;
00053 CoM[2] = comz / totalArea_com;
00054
00055 vtkSmartPointer<vtkTransform> trans_center = vtkSmartPointer<vtkTransform>::New ();
00056 trans_center->Translate (-CoM[0], -CoM[1], -CoM[2]);
00057 vtkSmartPointer<vtkMatrix4x4> matrixCenter = trans_center->GetMatrix ();
00058
00059 vtkSmartPointer<vtkTransformFilter> trans_filter_center = vtkSmartPointer<vtkTransformFilter>::New ();
00060 trans_filter_center->SetTransform (trans_center);
00061 trans_filter_center->SetInput (polydata_);
00062 trans_filter_center->Update ();
00063
00064 vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New ();
00065 mapper->SetInputConnection (trans_filter_center->GetOutputPort ());
00066 mapper->Update ();
00067
00068
00069 double bb[6];
00070 mapper->GetBounds (bb);
00071 double ms = (std::max) ((std::fabs) (bb[0] - bb[1]),
00072 (std::max) ((std::fabs) (bb[2] - bb[3]), (std::fabs) (bb[4] - bb[5])));
00073 double max_side = radius_sphere_ / 2.0;
00074 double scale_factor = max_side / ms;
00075
00076 vtkSmartPointer<vtkTransform> trans_scale = vtkSmartPointer<vtkTransform>::New ();
00077 trans_scale->Scale (scale_factor, scale_factor, scale_factor);
00078 vtkSmartPointer<vtkMatrix4x4> matrixScale = trans_scale->GetMatrix ();
00079
00080 vtkSmartPointer<vtkTransformFilter> trans_filter_scale = vtkSmartPointer<vtkTransformFilter>::New ();
00081 trans_filter_scale->SetTransform (trans_scale);
00082 trans_filter_scale->SetInputConnection (trans_filter_center->GetOutputPort ());
00083 trans_filter_scale->Update ();
00084
00085 mapper->SetInputConnection (trans_filter_scale->GetOutputPort ());
00086 mapper->Update ();
00087
00089
00091 vtkSmartPointer<vtkCellArray> cells = mapper->GetInput ()->GetPolys ();
00092 vtkIdType npts = 0, *ptIds = NULL;
00093
00094 double p1[3], p2[3], p3[3], area, totalArea = 0;
00095 for (cells->InitTraversal (); cells->GetNextCell (npts, ptIds);)
00096 {
00097 polydata_->GetPoint (ptIds[0], p1);
00098 polydata_->GetPoint (ptIds[1], p2);
00099 polydata_->GetPoint (ptIds[2], p3);
00100 area = vtkTriangle::TriangleArea (p1, p2, p3);
00101 totalArea += area;
00102 }
00103
00104
00105 vtkSmartPointer<vtkPlatonicSolidSource> ico = vtkSmartPointer<vtkPlatonicSolidSource>::New ();
00106 ico->SetSolidTypeToIcosahedron ();
00107 ico->Update ();
00108
00109
00110 vtkSmartPointer<vtkLoopSubdivisionFilter> subdivide = vtkSmartPointer<vtkLoopSubdivisionFilter>::New ();
00111 subdivide->SetNumberOfSubdivisions (tesselation_level_);
00112 subdivide->SetInputConnection (ico->GetOutputPort ());
00113
00114
00115 vtkPolyData *sphere = subdivide->GetOutput ();
00116 sphere->Update ();
00117
00118 std::vector<Eigen::Vector3f> cam_positions;
00119 if (!use_vertices_)
00120 {
00121 vtkSmartPointer<vtkCellArray> cells_sphere = sphere->GetPolys ();
00122 cam_positions.resize (sphere->GetNumberOfPolys ());
00123
00124 size_t i=0;
00125 for (cells_sphere->InitTraversal (); cells_sphere->GetNextCell (npts_com, ptIds_com);)
00126 {
00127 sphere->GetPoint (ptIds_com[0], p1_com);
00128 sphere->GetPoint (ptIds_com[1], p2_com);
00129 sphere->GetPoint (ptIds_com[2], p3_com);
00130 vtkTriangle::TriangleCenter (p1_com, p2_com, p3_com, center);
00131 cam_positions[i] = Eigen::Vector3f (float (center[0]), float (center[1]), float (center[2]));
00132 i++;
00133 }
00134
00135 }
00136 else
00137 {
00138 cam_positions.resize (sphere->GetNumberOfPoints ());
00139 for (int i = 0; i < sphere->GetNumberOfPoints (); i++)
00140 {
00141 double cam_pos[3];
00142 sphere->GetPoint (i, cam_pos);
00143 cam_positions[i] = Eigen::Vector3f (float (cam_pos[0]), float (cam_pos[1]), float (cam_pos[2]));
00144 }
00145 }
00146
00147 double camera_radius = radius_sphere_;
00148 double cam_pos[3];
00149 double first_cam_pos[3];
00150
00151 first_cam_pos[0] = cam_positions[0][0] * radius_sphere_;
00152 first_cam_pos[1] = cam_positions[0][1] * radius_sphere_;
00153 first_cam_pos[2] = cam_positions[0][2] * radius_sphere_;
00154
00155
00156 vtkSmartPointer<vtkRenderWindow> render_win = vtkSmartPointer<vtkRenderWindow>::New ();
00157 vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New ();
00158 render_win->AddRenderer (renderer);
00159 render_win->SetSize (resolution_, resolution_);
00160 renderer->SetBackground (1.0, 0, 0);
00161
00162
00163 vtkSmartPointer<vtkWorldPointPicker> worldPicker = vtkSmartPointer<vtkWorldPointPicker>::New ();
00164
00165 vtkSmartPointer<vtkCamera> cam = vtkSmartPointer<vtkCamera>::New ();
00166 cam->SetFocalPoint (0, 0, 0);
00167
00168 Eigen::Vector3f cam_pos_3f = cam_positions[0];
00169 Eigen::Vector3f perp = cam_pos_3f.cross (Eigen::Vector3f::UnitY ());
00170 cam->SetViewUp (perp[0], perp[1], perp[2]);
00171
00172 cam->SetPosition (first_cam_pos);
00173 cam->SetViewAngle (view_angle_);
00174 cam->Modified ();
00175
00176
00177 for (size_t i = 0; i < cam_positions.size (); i++)
00178 {
00179 cam_pos[0] = cam_positions[i][0];
00180 cam_pos[1] = cam_positions[i][1];
00181 cam_pos[2] = cam_positions[i][2];
00182
00183
00184 vtkSmartPointer<vtkCamera> cam_tmp = vtkSmartPointer<vtkCamera>::New ();
00185 cam_tmp->SetViewAngle (view_angle_);
00186
00187 Eigen::Vector3f cam_pos_3f (static_cast<float> (cam_pos[0]), static_cast<float> (cam_pos[1]), static_cast<float> (cam_pos[2]));
00188 cam_pos_3f = cam_pos_3f.normalized ();
00189 Eigen::Vector3f test = Eigen::Vector3f::UnitY ();
00190
00191
00192
00193
00194 if (fabs (cam_pos_3f.dot (test)) == 1)
00195 {
00196
00197 test = cam_pos_3f.cross (Eigen::Vector3f::UnitX ());
00198 }
00199
00200 cam_tmp->SetViewUp (test[0], test[1], test[2]);
00201
00202 for (int k = 0; k < 3; k++)
00203 {
00204 cam_pos[k] = cam_pos[k] * camera_radius;
00205 }
00206
00207 cam_tmp->SetPosition (cam_pos);
00208 cam_tmp->SetFocalPoint (0, 0, 0);
00209 cam_tmp->Modified ();
00210
00211
00212 vtkSmartPointer<vtkMatrix4x4> view_trans_inverted = vtkSmartPointer<vtkMatrix4x4>::New ();
00213 vtkMatrix4x4::Invert (cam->GetViewTransformMatrix (), view_trans_inverted);
00214 vtkSmartPointer<vtkTransform> trans_rot_pose = vtkSmartPointer<vtkTransform>::New ();
00215 trans_rot_pose->Identity ();
00216 trans_rot_pose->Concatenate (view_trans_inverted);
00217 trans_rot_pose->Concatenate (cam_tmp->GetViewTransformMatrix ());
00218 vtkSmartPointer<vtkTransformFilter> trans_rot_pose_filter = vtkSmartPointer<vtkTransformFilter>::New ();
00219 trans_rot_pose_filter->SetTransform (trans_rot_pose);
00220 trans_rot_pose_filter->SetInputConnection (trans_filter_scale->GetOutputPort ());
00221
00222
00223 vtkSmartPointer<vtkTransform> translation = vtkSmartPointer<vtkTransform>::New ();
00224 translation->Translate (first_cam_pos[0] * -1, first_cam_pos[1] * -1, first_cam_pos[2] * -1);
00225 vtkSmartPointer<vtkTransformFilter> translation_filter = vtkSmartPointer<vtkTransformFilter>::New ();
00226 translation_filter->SetTransform (translation);
00227 translation_filter->SetInputConnection (trans_rot_pose_filter->GetOutputPort ());
00228
00229
00230 cam_tmp->SetPosition (0, 0, 0);
00231 cam_tmp->SetFocalPoint (first_cam_pos[0] * -1, first_cam_pos[1] * -1, first_cam_pos[2] * -1);
00232 cam_tmp->Modified ();
00233
00234
00235 vtkSmartPointer<vtkMatrix4x4> matrixRotModel = trans_rot_pose->GetMatrix ();
00236 vtkSmartPointer<vtkMatrix4x4> matrixTranslation = translation->GetMatrix ();
00237
00238 mapper->SetInputConnection (translation_filter->GetOutputPort ());
00239 mapper->Update ();
00240
00241
00242 vtkSmartPointer<vtkActor> actor_view = vtkSmartPointer<vtkActor>::New ();
00243 actor_view->SetMapper (mapper);
00244 renderer->SetActiveCamera (cam_tmp);
00245 renderer->AddActor (actor_view);
00246 renderer->Modified ();
00247
00248 render_win->Render ();
00249
00250
00251 vtkSmartPointer<vtkTransform> backToRealScale = vtkSmartPointer<vtkTransform>::New ();
00252 backToRealScale->PostMultiply ();
00253 backToRealScale->Identity ();
00254 backToRealScale->Concatenate (matrixScale);
00255 backToRealScale->Concatenate (matrixTranslation);
00256 backToRealScale->Inverse ();
00257 backToRealScale->Modified ();
00258 backToRealScale->Concatenate (matrixTranslation);
00259 backToRealScale->Modified ();
00260
00261 Eigen::Matrix4f backToRealScale_eigen;
00262 backToRealScale_eigen.setIdentity ();
00263
00264 for (int x = 0; x < 4; x++)
00265 for (int y = 0; y < 4; y++)
00266 backToRealScale_eigen (x, y) = float (backToRealScale->GetMatrix ()->GetElement (x, y));
00267
00268 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
00269
00270 cloud->points.resize (resolution_ * resolution_);
00271 cloud->width = resolution_ * resolution_;
00272 cloud->height = 1;
00273
00274 double coords[3];
00275 float * depth = new float[resolution_ * resolution_];
00276 render_win->GetZbufferData (0, 0, resolution_ - 1, resolution_ - 1, &(depth[0]));
00277
00278 int count_valid_depth_pixels = 0;
00279 for (int x = 0; x < resolution_; x++)
00280 {
00281 for (int y = 0; y < resolution_; y++)
00282 {
00283 float value = depth[y * resolution_ + x];
00284 if (value == 1.0)
00285 continue;
00286
00287 worldPicker->Pick (x, y, value, renderer);
00288 worldPicker->GetPickPosition (coords);
00289
00290
00291
00292 cloud->points[count_valid_depth_pixels].x = static_cast<float> (coords[0]);
00293 cloud->points[count_valid_depth_pixels].y = static_cast<float> (coords[1]);
00294 cloud->points[count_valid_depth_pixels].z = static_cast<float> (coords[2]);
00295 cloud->points[count_valid_depth_pixels].getVector4fMap () = backToRealScale_eigen
00296 * cloud->points[count_valid_depth_pixels].getVector4fMap ();
00297 count_valid_depth_pixels++;
00298 }
00299 }
00300
00301 delete[] depth;
00302
00303 if(compute_entropy_) {
00305
00307
00308 vtkSmartPointer<vtkPolyData> polydata = mapper->GetInput ();
00309 polydata->BuildCells ();
00310
00311 vtkSmartPointer<vtkCellArray> cells = polydata->GetPolys ();
00312 vtkIdType npts = 0, *ptIds = NULL;
00313
00314 double p1[3], p2[3], p3[3], area, totalArea = 0;
00315 for (cells->InitTraversal (); cells->GetNextCell (npts, ptIds);)
00316 {
00317 polydata->GetPoint (ptIds[0], p1);
00318 polydata->GetPoint (ptIds[1], p2);
00319 polydata->GetPoint (ptIds[2], p3);
00320 area = vtkTriangle::TriangleArea (p1, p2, p3);
00321 totalArea += area;
00322 }
00323
00325
00327 vtkSmartPointer<vtkVisibleCellSelector> selector = vtkSmartPointer<vtkVisibleCellSelector>::New ();
00328 vtkSmartPointer<vtkIdTypeArray> selection = vtkSmartPointer<vtkIdTypeArray>::New ();
00329
00330 selector->SetRenderer (renderer);
00331 selector->SetArea (0, 0, resolution_ - 1, resolution_ - 1);
00332 selector->Select ();
00333 selector->GetSelectedIds (selection);
00334
00335 double visible_area = 0;
00336 for (int sel_id = 3; sel_id < (selection->GetNumberOfTuples () * selection->GetNumberOfComponents ()); sel_id
00337 += selection->GetNumberOfComponents ())
00338 {
00339 int id_mesh = int (selection->GetValue (sel_id));
00340
00341 if (id_mesh >= polydata->GetNumberOfCells ())
00342 continue;
00343
00344 vtkCell * cell = polydata->GetCell (id_mesh);
00345 vtkTriangle* triangle = dynamic_cast<vtkTriangle*> (cell);
00346 double p0[3];
00347 double p1[3];
00348 double p2[3];
00349 triangle->GetPoints ()->GetPoint (0, p0);
00350 triangle->GetPoints ()->GetPoint (1, p1);
00351 triangle->GetPoints ()->GetPoint (2, p2);
00352 visible_area += vtkTriangle::TriangleArea (p0, p1, p2);
00353 }
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 entropies_.push_back (float (visible_area / totalArea));
00382 }
00383
00384 cloud->points.resize (count_valid_depth_pixels);
00385 cloud->width = count_valid_depth_pixels;
00386
00387
00388 vtkSmartPointer<vtkMatrix4x4> view_transform = cam_tmp->GetViewTransformMatrix ();
00389 Eigen::Matrix4f trans_view;
00390 trans_view.setIdentity ();
00391
00392 for (int x = 0; x < 4; x++)
00393 for (int y = 0; y < 4; y++)
00394 trans_view (x, y) = float (view_transform->GetElement (x, y));
00395
00396
00397
00398 for (size_t i = 0; i < cloud->points.size (); i++)
00399 {
00400 cloud->points[i].getVector4fMap () = trans_view * cloud->points[i].getVector4fMap ();
00401 cloud->points[i].y *= -1.0f;
00402 cloud->points[i].z *= -1.0f;
00403 }
00404
00405 renderer->RemoveActor (actor_view);
00406
00407 generated_views_.push_back (cloud);
00408
00409
00410 vtkSmartPointer<vtkTransform> transOCtoCC = vtkSmartPointer<vtkTransform>::New ();
00411 transOCtoCC->PostMultiply ();
00412 transOCtoCC->Identity ();
00413 transOCtoCC->Concatenate (matrixCenter);
00414 transOCtoCC->Concatenate (matrixRotModel);
00415 transOCtoCC->Concatenate (matrixTranslation);
00416 transOCtoCC->Concatenate (cam_tmp->GetViewTransformMatrix ());
00417
00418
00419
00420 vtkSmartPointer<vtkMatrix4x4> cameraSTD = vtkSmartPointer<vtkMatrix4x4>::New ();
00421 cameraSTD->Identity ();
00422 cameraSTD->SetElement (0, 0, 1);
00423 cameraSTD->SetElement (1, 1, -1);
00424 cameraSTD->SetElement (2, 2, -1);
00425
00426 transOCtoCC->Concatenate (cameraSTD);
00427 transOCtoCC->Modified ();
00428
00429 Eigen::Matrix4f pose_view;
00430 pose_view.setIdentity ();
00431
00432 for (int x = 0; x < 4; x++)
00433 for (int y = 0; y < 4; y++)
00434 pose_view (x, y) = float (transOCtoCC->GetMatrix ()->GetElement (x, y));
00435
00436 poses_.push_back (pose_view);
00437
00438 }
00439 }