ClusterLabelTool.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Robot Operating System code by the University of Osnabrück
5  * Copyright (c) 2015, University of Osnabrück
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above
13  * copyright notice, this list of conditions and the following
14  * disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above
17  * copyright notice, this list of conditions and the following
18  * disclaimer in the documentation and/or other materials provided
19  * with the distribution.
20  *
21  * 3. Neither the name of the copyright holder nor the names of its
22  * contributors may be used to endorse or promote products derived
23  * from this software without specific prior written permission.
24  *
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
30  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
33  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
34  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
35  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
36  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37  *
38  *
39  *
40  * ClusterLabelTool.cpp
41  *
42  * authors:
43  * Kristin Schmidt <krschmidt@uos.de>
44  * Jan Philipp Vogtherr <jvogtherr@uos.de>
45  *
46  */
47 
48 #include <ClusterLabelTool.hpp>
49 #include <ClusterLabelVisual.hpp>
50 #include <ClusterLabelDisplay.hpp>
51 #include <CLUtil.hpp>
52 
53 #include <fstream>
54 #include <sstream>
55 #include <iostream>
56 #include <limits>
57 
58 #include <chrono>
59 
61 
62 #include <OGRE/OgreColourValue.h>
63 
66 
67 using std::ifstream;
68 using std::stringstream;
69 
70 namespace rviz_map_plugin
71 {
72 #define CL_RAY_CAST_KERNEL_FILE "/include/kernels/cast_rays.cl"
73 
74 ClusterLabelTool::ClusterLabelTool() : m_displayInitialized(false)
75 {
76  shortcut_key_ = 'l';
77 
79  m_labelPublisher = n.advertise<mesh_msgs::MeshFaceClusterStamped>("/cluster_label", 1, true);
80 }
81 
83 {
84  m_selectedFaces.clear();
85  context_->getSceneManager()->destroyManualObject(m_selectionBox->getName());
86  context_->getSceneManager()->destroyManualObject(m_selectionBoxMaterial->getName());
87  context_->getSceneManager()->destroySceneNode(m_sceneNode);
88 }
89 
90 // onInitialize() is called by the superclass after scene_manager_ and
91 // context_ are set. It should be called only once per instantiation.
93 {
94  ROS_DEBUG("ClusterLabelTool: Call Init");
95  m_sceneNode = context_->getSceneManager()->getRootSceneNode()->createChildSceneNode();
96 
97  m_selectionBox = context_->getSceneManager()->createManualObject("ClusterLabelTool_SelectionBox");
98  m_selectionBox->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY);
99  m_selectionBox->setUseIdentityProjection(true);
100  m_selectionBox->setUseIdentityView(true);
101  m_selectionBox->setQueryFlags(0);
102  m_sceneNode->attachObject(m_selectionBox);
103 
104  m_selectionBoxMaterial = Ogre::MaterialManager::getSingleton().create(
105  "ClusterLabelTool_SelectionBoxMaterial", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true);
106 
107  m_selectionBoxMaterial->setAmbient(Ogre::ColourValue(0, 0, 255, 0.5));
108  m_selectionBoxMaterial->setDiffuse(0, 0, 0, 0.5);
109  m_selectionBoxMaterial->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
110  m_selectionBoxMaterial->setDepthWriteEnabled(false);
111  m_selectionBoxMaterial->getTechnique(0)->getPass(0)->setPolygonMode(Ogre::PM_SOLID);
112  m_selectionBoxMaterial->setCullingMode(Ogre::CULL_NONE);
113 
114  // try-catch block to check for OpenCL errors
115  try
116  {
117  // Initialize OpenCL
118  ROS_DEBUG("Get platforms");
119  vector<cl::Platform> platforms;
120  cl::Platform::get(&platforms);
121  for (auto const& platform : platforms)
122  {
123  ROS_DEBUG("Found platform: %s", platform.getInfo<CL_PLATFORM_NAME>().c_str());
124  ROS_DEBUG("platform version: %s", platform.getInfo<CL_PLATFORM_VERSION>().c_str());
125  }
126  ROS_DEBUG(" ");
127 
128  vector<cl::Device> consideredDevices;
129  for (auto const& platform : platforms)
130  {
131  ROS_DEBUG("Get devices of %s: ", platform.getInfo<CL_PLATFORM_NAME>().c_str());
132  cl_context_properties properties[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)(platform)(), 0 };
133  m_clContext = cl::Context(CL_DEVICE_TYPE_ALL, properties);
134  vector<cl::Device> devices = m_clContext.getInfo<CL_CONTEXT_DEVICES>();
135  for (auto const& device : devices)
136  {
137  ROS_DEBUG("Found device: %s", device.getInfo<CL_DEVICE_NAME>().c_str());
138  ROS_DEBUG("Device work units: %d", device.getInfo<CL_DEVICE_MAX_COMPUTE_UNITS>());
139  ROS_DEBUG("Device work group size: %lu", device.getInfo<CL_DEVICE_MAX_WORK_GROUP_SIZE>());
140 
141  std::string device_info = device.getInfo<CL_DEVICE_VERSION>();
142  // getVersion extracts the version number with major in the upper 16 bits and minor in the lower 16 bits
143 
144  unsigned int version = cl::detail::getVersion(std::vector<char>(device_info.begin(), device_info.end()));
145 
146  // shift 16 to the right to get the number in the upper 16 bits
147  cl_uint majorVersion = version >> 16;
148  // use bitwise AND to extract the number in the lower 16 bits
149  cl_uint minorVersion = version & 0x0000FFFF;
150 
151  ROS_INFO("Found a device with OpenCL version: %u.%u", majorVersion, minorVersion);
152 
153  // find all devices that support at least OpenCL version 1.2
154  if (majorVersion >= 1 && minorVersion >= 2)
155  ;
156  {
157  consideredDevices.push_back(device);
158  }
159  }
160  }
161  ROS_DEBUG(" ");
162 
163  cl::Platform platform;
164  // Preferably choose the first compatible device of type GPU
165  bool deviceFound = false;
166  for (auto const& device : consideredDevices)
167  {
168  if (device.getInfo<CL_DEVICE_TYPE>() == CL_DEVICE_TYPE_GPU)
169  {
170  m_clDevice = device;
171  platform = device.getInfo<CL_DEVICE_PLATFORM>();
172  deviceFound = true;
173  break;
174  }
175  }
176  if (!deviceFound && consideredDevices.size() > 0)
177  {
178  // If no device of type GPU was found, choose the first compatible device
179  m_clDevice = consideredDevices[0];
180  platform = m_clDevice.getInfo<CL_DEVICE_PLATFORM>();
181  deviceFound = true;
182  }
183  if (!deviceFound)
184  {
185  // Panic if no compatible device was found
186  ROS_ERROR("No device with compatible OpenCL version found (minimum 2.0)");
188  }
189 
190  cl_context_properties properties[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)(platform)(), 0 };
191  m_clContext = cl::Context(CL_DEVICE_TYPE_ALL, properties);
192 
193  ROS_INFO("Using device %s of platform %s", m_clDevice.getInfo<CL_DEVICE_NAME>().c_str(),
194  platform.getInfo<CL_PLATFORM_NAME>().c_str());
195  ROS_DEBUG(" ");
196 
197  // Read kernel file
198  ifstream in(ros::package::getPath("rviz_map_plugin") + CL_RAY_CAST_KERNEL_FILE);
199  std::string cast_rays_kernel(static_cast<stringstream const&>(stringstream() << in.rdbuf()).str());
200 
201  ROS_DEBUG("Got kernel: %s%s", ros::package::getPath("rviz_map_plugin").c_str(), CL_RAY_CAST_KERNEL_FILE);
202 
203  m_clProgramSources = cl::Program::Sources(1, { cast_rays_kernel.c_str(), cast_rays_kernel.length() });
204 
206  try
207  {
208  m_clProgram.build({ m_clDevice });
209  ROS_INFO("Successfully built program.");
210  }
211  catch (cl::Error& err)
212  {
213  ROS_ERROR("Error building: %s", m_clProgram.getBuildInfo<CL_PROGRAM_BUILD_LOG>(m_clDevice).c_str());
214 
215  ros::shutdown();
216  exit(1);
217  }
218 
219  // Create queue to which we will push commands for the device.
220  m_clQueue = cl::CommandQueue(m_clContext, m_clDevice, 0);
221  }
222  catch (cl::Error err)
223  {
224  ROS_ERROR_STREAM(err.what() << ": " << CLUtil::getErrorString(err.err()));
225  ROS_WARN_STREAM("(" << CLUtil::getErrorDescription(err.err()) << ")");
227  exit(1);
228  }
229 }
230 
231 void ClusterLabelTool::setVisual(std::shared_ptr<ClusterLabelVisual> visual)
232 {
233  // set new visual
234  m_visual = visual;
235  m_selectedFaces = visual->getFaces();
236  m_faceSelectedArray.clear();
237  for (auto faceId : m_selectedFaces)
238  {
239  if (m_faceSelectedArray.size() <= faceId)
240  {
241  m_faceSelectedArray.resize(faceId + 1);
242  }
243  m_faceSelectedArray[faceId] = true;
244  }
245 }
246 
248 {
249  m_clKernelSphere.setArg(3, size);
250  m_sphereSize = size;
251 }
252 
254 {
255 }
256 
258 {
259 }
260 
262 {
263  m_display = display;
265  m_faceSelectedArray.reserve(m_meshGeometry->faces.size());
266  m_displayInitialized = true;
267 
268  m_vertexData.reserve(m_meshGeometry->faces.size() * 3 * 3);
269 
270  for (uint32_t faceId = 0; faceId < m_meshGeometry->faces.size(); faceId++)
271  {
272  for (uint32_t i = 0; i < 3; i++)
273  {
274  uint32_t vertexId = m_meshGeometry->faces[faceId].vertexIndices[i];
275  Ogre::Vector3 vertexPos(m_meshGeometry->vertices[vertexId].x, m_meshGeometry->vertices[vertexId].y,
276  m_meshGeometry->vertices[vertexId].z);
277  m_vertexPositions.push_back(vertexPos);
278 
279  m_vertexData.push_back(m_meshGeometry->vertices[vertexId].x);
280  m_vertexData.push_back(m_meshGeometry->vertices[vertexId].y);
281  m_vertexData.push_back(m_meshGeometry->vertices[vertexId].z);
282  }
283  }
284 
285  // try-catch block to check for OpenCL errors
286  try
287  {
288  m_clVertexBuffer = cl::Buffer(m_clContext, CL_MEM_READ_ONLY | CL_MEM_HOST_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
289  sizeof(float) * m_vertexData.size(), m_vertexData.data());
290 
291  m_clResultBuffer = cl::Buffer(m_clContext, CL_MEM_WRITE_ONLY | CL_MEM_HOST_READ_ONLY,
292  sizeof(float) * m_meshGeometry->faces.size());
293 
294  m_clRayBuffer = cl::Buffer(m_clContext, CL_MEM_READ_ONLY | CL_MEM_HOST_WRITE_ONLY, sizeof(float) * 6);
295 
296  m_clSphereBuffer = cl::Buffer(m_clContext, CL_MEM_READ_ONLY | CL_MEM_HOST_WRITE_ONLY, sizeof(float) * 4);
297 
298  m_clBoxBuffer = cl::Buffer(m_clContext, CL_MEM_READ_ONLY | CL_MEM_HOST_WRITE_ONLY, sizeof(float) * 4 * 6);
299 
300  m_clStartNormalBuffer = cl::Buffer(m_clContext, CL_MEM_READ_ONLY | CL_MEM_HOST_WRITE_ONLY, sizeof(float) * 3);
301 
302  m_clKernelSingleRay = cl::Kernel(m_clProgram, "cast_rays");
303  m_clKernelSphere = cl::Kernel(m_clProgram, "cast_sphere");
304  m_clKernelBox = cl::Kernel(m_clProgram, "cast_box");
305 
309 
313  m_clKernelSphere.setArg(3, m_sphereSize);
314 
315  m_clKernelBox.setArg(0, m_clVertexBuffer);
316  m_clKernelBox.setArg(1, m_clBoxBuffer);
317  m_clKernelBox.setArg(2, m_clResultBuffer);
318  }
319  catch (cl::Error err)
320  {
321  ROS_ERROR_STREAM(err.what() << ": " << CLUtil::getErrorString(err.err()));
322  ROS_WARN_STREAM("(" << CLUtil::getErrorDescription(err.err()) << ")");
323  ros::shutdown();
324  exit(1);
325  }
326 }
327 
329 {
330  float left, right, top, bottom;
331 
332  left = m_selectionStart.x * 2 - 1;
333  right = m_selectionStop.x * 2 - 1;
334  top = 1 - m_selectionStart.y * 2;
335  bottom = 1 - m_selectionStop.y * 2;
336 
337  m_selectionBox->clear();
338  m_selectionBox->begin(m_selectionBoxMaterial->getName(), Ogre::RenderOperation::OT_TRIANGLE_LIST);
339  m_selectionBox->position(left, top, -1);
340  m_selectionBox->position(right, top, -1);
341  m_selectionBox->position(right, bottom, -1);
342  m_selectionBox->position(left, bottom, -1);
343  m_selectionBox->triangle(0, 1, 2);
344  m_selectionBox->triangle(0, 2, 3);
345  m_selectionBox->end();
346 }
347 
349 {
350  m_selectionStart.x = (float)event.x / event.viewport->getActualWidth();
351  m_selectionStart.y = (float)event.y / event.viewport->getActualHeight();
353  m_selectionBox->clear();
354  m_selectionBox->setVisible(true);
355 }
356 
358 {
359  m_selectionStop.x = (float)event.x / event.viewport->getActualWidth();
360  m_selectionStop.y = (float)event.y / event.viewport->getActualHeight();
362 }
363 
365 {
366  m_selectionBox->setVisible(false);
367 
368  float left = m_selectionStart.x;
369  float right = m_selectionStop.x;
370  float top = m_selectionStart.y;
371  float bottom = m_selectionStop.y;
372 
373  size_t goalSection;
374  size_t goalIndex;
375 
376  if (left > right)
377  {
378  std::swap(left, right);
379  }
380 
381  if (top > bottom)
382  {
383  std::swap(top, bottom);
384  }
385 
386  const float BOX_SIZE_TOLERANCE = 0.0001;
387  if ((right - left) * (bottom - top) < BOX_SIZE_TOLERANCE)
388  {
389  selectSingleFace(event, selectMode);
390  return;
391  }
392 
393  Ogre::PlaneBoundedVolume volume =
394  event.viewport->getCamera()->getCameraToViewportBoxVolume(left, top, right, bottom, true);
395 
396  selectFacesInBoxParallel(volume, selectMode);
397 }
398 
399 void ClusterLabelTool::selectFacesInBoxParallel(Ogre::PlaneBoundedVolume& volume, bool selectMode)
400 {
401  m_boxData.clear();
402  for (Ogre::Plane plane : volume.planes)
403  {
404  m_boxData.push_back(plane.normal.x);
405  m_boxData.push_back(plane.normal.y);
406  m_boxData.push_back(plane.normal.z);
407  m_boxData.push_back(plane.d);
408  }
409 
410  try
411  {
412  m_clQueue.enqueueWriteBuffer(m_clBoxBuffer, CL_TRUE, 0, sizeof(float) * 4 * 6, m_boxData.data());
413 
414  m_clQueue.enqueueNDRangeKernel(m_clKernelBox, cl::NullRange, cl::NDRange(m_meshGeometry->faces.size()),
415  cl::NullRange, nullptr);
416  m_clQueue.finish();
417 
418  m_resultDistances.resize(m_meshGeometry->faces.size());
419  m_clQueue.enqueueReadBuffer(m_clResultBuffer, CL_TRUE, 0, sizeof(float) * m_meshGeometry->faces.size(),
420  m_resultDistances.data());
421  }
422  catch (cl::Error err)
423  {
424  ROS_ERROR_STREAM(err.what() << ": " << CLUtil::getErrorString(err.err()));
425  ROS_WARN_STREAM("(" << CLUtil::getErrorDescription(err.err()) << ")");
426  }
427 
428  for (int faceId = 0; faceId < m_meshGeometry->faces.size(); faceId++)
429  {
430  if (m_resultDistances[faceId] > 0)
431  {
432  if (m_faceSelectedArray.size() <= faceId)
433  {
434  m_faceSelectedArray.resize(faceId + 1);
435  }
436  m_faceSelectedArray[faceId] = selectMode;
437  }
438  }
439 
440  std::vector<uint32_t> tmpFaceList;
441 
442  for (uint32_t faceId = 0; faceId < m_faceSelectedArray.size(); faceId++)
443  {
444  if (m_faceSelectedArray[faceId])
445  {
446  tmpFaceList.push_back(faceId);
447  }
448  }
449 
451  {
452  m_visual->setFacesInCluster(tmpFaceList);
453  // m_visual->setColor(Ogre::ColourValue(0.0f, 0.0f, 1.0f, 1.0f));
454  }
455 }
456 
458 {
459  Ogre::Ray ray = event.viewport->getCamera()->getCameraToViewportRay(
460  (float)event.x / event.viewport->getActualWidth(), (float)event.y / event.viewport->getActualHeight());
461  selectSingleFaceParallel(ray, selectMode);
462 }
463 
464 void ClusterLabelTool::selectSingleFaceParallel(Ogre::Ray& ray, bool selectMode)
465 {
466  m_rayData = { ray.getOrigin().x, ray.getOrigin().y, ray.getOrigin().z,
467  ray.getDirection().x, ray.getDirection().y, ray.getDirection().z };
468 
469  std::vector<std::pair<uint32_t, float>> intersectedFaceList;
470 
471  try
472  {
473  m_clQueue.enqueueWriteBuffer(m_clRayBuffer, CL_TRUE, 0, sizeof(float) * 6, m_rayData.data());
474 
475  m_clQueue.enqueueNDRangeKernel(m_clKernelSingleRay, cl::NullRange, cl::NDRange(m_meshGeometry->faces.size()),
476  cl::NullRange, nullptr);
477  m_clQueue.finish();
478 
479  m_resultDistances.resize(m_meshGeometry->faces.size());
480  m_clQueue.enqueueReadBuffer(m_clResultBuffer, CL_TRUE, 0, sizeof(float) * m_meshGeometry->faces.size(),
481  m_resultDistances.data());
482  }
483  catch (cl::Error err)
484  {
485  ROS_ERROR_STREAM(err.what() << ": " << CLUtil::getErrorString(err.err()));
486  ROS_WARN_STREAM("(" << CLUtil::getErrorDescription(err.err()) << ")");
487  }
488 
489  int closestFaceId = -1;
490  float minDist = std::numeric_limits<float>::max();
491 
492  for (int i = 0; i < m_meshGeometry->faces.size(); i++)
493  {
494  if (m_resultDistances[i] > 0 && m_resultDistances[i] < minDist)
495  {
496  closestFaceId = i;
497  minDist = m_resultDistances[i];
498  }
499  }
500 
501  if (m_displayInitialized && m_visual && closestFaceId != -1)
502  {
503  std::vector<uint32_t> tmpFaceList;
504 
505  if (m_faceSelectedArray.size() <= closestFaceId)
506  {
507  m_faceSelectedArray.resize(closestFaceId + 1);
508  }
509  m_faceSelectedArray[closestFaceId] = selectMode;
510 
511  for (int faceId = 0; faceId < m_faceSelectedArray.size(); faceId++)
512  {
513  if (m_faceSelectedArray[faceId])
514  {
515  tmpFaceList.push_back(faceId);
516  }
517  }
518 
519  m_visual->setFacesInCluster(tmpFaceList);
520 
521  ROS_DEBUG("selectSingleFaceParallel() found face with id %d", closestFaceId);
522  }
523 }
524 
526 {
527  Ogre::Ray ray = event.viewport->getCamera()->getCameraToViewportRay(
528  (float)event.x / event.viewport->getActualWidth(), (float)event.y / event.viewport->getActualHeight());
529  selectSphereFacesParallel(ray, selectMode);
530 }
531 
532 void ClusterLabelTool::selectSphereFacesParallel(Ogre::Ray& ray, bool selectMode)
533 {
534  auto raycastResult = getClosestIntersectedFaceParallel(ray);
535 
536  if (raycastResult)
537  {
538  Ogre::Vector3 sphereCenter = ray.getPoint(raycastResult->second);
539 
540  m_sphereData = { sphereCenter.x, sphereCenter.y, sphereCenter.z, raycastResult->second };
541 
542  try
543  {
544  m_clQueue.enqueueWriteBuffer(m_clSphereBuffer, CL_TRUE, 0, sizeof(float) * 4, m_sphereData.data());
545 
546  m_clQueue.enqueueNDRangeKernel(m_clKernelSphere, cl::NullRange, cl::NDRange(m_meshGeometry->faces.size()),
547  cl::NullRange, nullptr);
548  m_clQueue.finish();
549 
550  m_resultDistances.resize(m_meshGeometry->faces.size());
551  m_clQueue.enqueueReadBuffer(m_clResultBuffer, CL_TRUE, 0, sizeof(float) * m_meshGeometry->faces.size(),
552  m_resultDistances.data());
553  }
554  catch (cl::Error err)
555  {
556  ROS_ERROR_STREAM(err.what() << ": " << CLUtil::getErrorString(err.err()));
557  ROS_WARN_STREAM("(" << CLUtil::getErrorDescription(err.err()) << ")");
558  }
559 
560  for (int faceId = 0; faceId < m_meshGeometry->faces.size(); faceId++)
561  {
562  // if face is inside sphere, select it
563  if (m_resultDistances[faceId] > 0)
564  {
565  if (m_faceSelectedArray.size() <= faceId)
566  {
567  m_faceSelectedArray.resize(faceId + 1);
568  }
569  m_faceSelectedArray[faceId] = selectMode;
570  }
571  }
572 
574  {
575  std::vector<uint32_t> tmpFaceList;
576  for (int faceId = 0; faceId < m_faceSelectedArray.size(); faceId++)
577  {
578  if (m_faceSelectedArray[faceId])
579  {
580  tmpFaceList.push_back(faceId);
581  }
582  }
583 
584  m_visual->setFacesInCluster(tmpFaceList);
585  }
586  }
587 }
588 
589 boost::optional<std::pair<uint32_t, float>> ClusterLabelTool::getClosestIntersectedFaceParallel(Ogre::Ray& ray)
590 {
591  m_rayData = { ray.getOrigin().x, ray.getOrigin().y, ray.getOrigin().z,
592  ray.getDirection().x, ray.getDirection().y, ray.getDirection().z };
593 
594  try
595  {
596  m_clQueue.enqueueWriteBuffer(m_clRayBuffer, CL_TRUE, 0, sizeof(float) * 6, m_rayData.data());
597 
598  m_clQueue.enqueueNDRangeKernel(m_clKernelSingleRay, cl::NullRange, cl::NDRange(m_meshGeometry->faces.size()),
599  cl::NullRange, nullptr);
600  m_clQueue.finish();
601 
602  m_resultDistances.resize(m_meshGeometry->faces.size());
603  m_clQueue.enqueueReadBuffer(m_clResultBuffer, CL_TRUE, 0, sizeof(float) * m_meshGeometry->faces.size(),
604  m_resultDistances.data());
605  }
606  catch (cl::Error err)
607  {
608  ROS_ERROR_STREAM(err.what() << ": " << CLUtil::getErrorString(err.err()));
609  ROS_WARN_STREAM("(" << CLUtil::getErrorDescription(err.err()) << ")");
610  }
611 
612  uint32_t closestFaceId;
613  bool faceFound = false;
614  float minDist = std::numeric_limits<float>::max();
615 
616  for (uint32_t i = 0; i < m_meshGeometry->faces.size(); i++)
617  {
618  if (m_resultDistances[i] > 0 && m_resultDistances[i] < minDist)
619  {
620  closestFaceId = i;
621  faceFound = true;
622  minDist = m_resultDistances[i];
623  }
624  }
625 
626  if (faceFound)
627  {
628  return std::make_pair(closestFaceId, minDist);
629  }
630  else
631  {
632  return {};
633  }
634 }
635 
636 void ClusterLabelTool::publishLabel(std::string label)
637 {
638  ROS_DEBUG_STREAM("Label Tool: Publish label '" << label << "'");
639 
640  vector<uint32_t> faces;
641  for (uint32_t i = 0; i < m_faceSelectedArray.size(); i++)
642  {
643  if (m_faceSelectedArray[i])
644  faces.push_back(i);
645  }
646 
647  m_display->addLabel(label, faces);
648 }
649 
650 // Handling mouse event and mark the clicked faces
652 {
653  if (event.leftDown() && event.control())
654  {
655  m_singleSelect = true;
656  selectSphereFaces(event, true);
657  }
658  else if (event.leftUp() && m_singleSelect)
659  {
660  m_singleSelect = false;
661  selectSphereFaces(event, true);
662  }
663  else if (event.rightDown() && event.control())
664  {
665  m_singleDeselect = true;
666  selectSphereFaces(event, false);
667  }
668  else if (event.rightUp() && m_singleDeselect)
669  {
670  m_singleDeselect = false;
671  selectSphereFaces(event, false);
672  }
673  else if (event.leftDown())
674  {
675  m_multipleSelect = true;
676  selectionBoxStart(event);
677  }
678  else if (event.leftUp() && m_multipleSelect)
679  {
680  m_multipleSelect = false;
681  selectMultipleFaces(event, true);
682  }
683  else if (event.rightDown())
684  {
685  m_multipleSelect = true;
686  selectionBoxStart(event);
687  }
688  else if (event.rightUp() && m_multipleSelect)
689  {
690  m_multipleSelect = false;
691  selectMultipleFaces(event, false);
692  }
693  else if (m_multipleSelect)
694  {
695  selectionBoxMove(event);
696  }
697  else if (m_singleSelect)
698  {
699  selectSphereFaces(event, true);
700  }
701  else if (m_singleDeselect)
702  {
703  selectSphereFaces(event, false);
704  }
705 
706  return Render;
707 }
708 
709 std::vector<uint32_t> ClusterLabelTool::getSelectedFaces()
710 {
711  std::vector<uint32_t> faceList;
712 
713  for (int faceId = 0; faceId < m_faceSelectedArray.size(); faceId++)
714  {
715  if (m_faceSelectedArray[faceId])
716  {
717  faceList.push_back(faceId);
718  }
719  }
720  return faceList;
721 }
722 
724 {
725  m_faceSelectedArray.clear();
726  if (m_visual)
727  {
728  m_visual->setFacesInCluster(std::vector<uint32_t>());
729  }
730 }
731 
733 {
734  m_visual.reset();
735 }
736 
737 } // End namespace rviz_map_plugin
rviz_map_plugin::ClusterLabelTool
Tool for selecting faces.
Definition: ClusterLabelTool.hpp:125
rviz_map_plugin::CLUtil::getErrorString
static const char * getErrorString(cl_int error)
Returns the error string to a given OpenCL error code.
Definition: CLUtil.hpp:67
rviz_map_plugin::ClusterLabelTool::selectionBoxMove
void selectionBoxMove(rviz::ViewportMouseEvent &event)
Definition: ClusterLabelTool.cpp:357
rviz::ViewportMouseEvent::leftDown
bool leftDown()
rviz_map_plugin::ClusterLabelTool::m_faceSelectedArray
std::vector< bool > m_faceSelectedArray
Definition: ClusterLabelTool.hpp:205
rviz_map_plugin::ClusterLabelTool::m_displayInitialized
bool m_displayInitialized
Definition: ClusterLabelTool.hpp:206
rviz::ViewportMouseEvent::rightUp
bool rightUp()
ros::package::getPath
ROSLIB_DECL std::string getPath(const std::string &package_name)
rviz_map_plugin::ClusterLabelTool::selectMultipleFaces
void selectMultipleFaces(rviz::ViewportMouseEvent &event, bool selectMode)
Definition: ClusterLabelTool.cpp:364
rviz::Tool
rviz_map_plugin::ClusterLabelTool::m_display
ClusterLabelDisplay * m_display
Definition: ClusterLabelTool.hpp:207
ROS_ERROR_STREAM
#define ROS_ERROR_STREAM(args)
rviz_map_plugin::ClusterLabelTool::m_selectedFaces
std::vector< uint32_t > m_selectedFaces
Definition: ClusterLabelTool.hpp:204
rviz_map_plugin::ClusterLabelTool::selectSphereFacesParallel
void selectSphereFacesParallel(Ogre::Ray &ray, bool selectMode)
Definition: ClusterLabelTool.cpp:532
rviz::ViewportMouseEvent
rviz::ViewportMouseEvent::x
int x
rviz::Tool::context_
DisplayContext * context_
rviz_map_plugin::ClusterLabelTool::selectSingleFaceParallel
void selectSingleFaceParallel(Ogre::Ray &ray, bool selectMode)
Definition: ClusterLabelTool.cpp:464
rviz_map_plugin::ClusterLabelDisplay::getGeometry
shared_ptr< Geometry > getGeometry()
Getter for the current geometry.
Definition: ClusterLabelDisplay.cpp:123
rviz_map_plugin::ClusterLabelTool::publishLabel
void publishLabel(std::string name)
Publish a label with a given namen.
Definition: ClusterLabelTool.cpp:636
ClusterLabelDisplay.hpp
rviz_map_plugin::ClusterLabelTool::selectionBoxStart
void selectionBoxStart(rviz::ViewportMouseEvent &event)
Definition: ClusterLabelTool.cpp:348
rviz_map_plugin::ClusterLabelTool::m_visual
std::shared_ptr< ClusterLabelVisual > m_visual
Definition: ClusterLabelTool.hpp:208
ros::shutdown
ROSCPP_DECL void shutdown()
rviz_map_plugin::ClusterLabelTool::m_singleSelect
bool m_singleSelect
Definition: ClusterLabelTool.hpp:220
rviz_map_plugin::ClusterLabelTool::m_selectionStart
Ogre::Vector2 m_selectionStart
Definition: ClusterLabelTool.hpp:217
ROS_DEBUG_STREAM
#define ROS_DEBUG_STREAM(args)
ros::requestShutdown
ROSCPP_DECL void requestShutdown()
rviz_map_plugin::ClusterLabelTool::m_boxData
std::vector< float > m_boxData
Definition: ClusterLabelTool.hpp:242
ros::NodeHandle::advertise
Publisher advertise(AdvertiseOptions &ops)
rviz_map_plugin::ClusterLabelTool::m_clKernelSphere
cl::Kernel m_clKernelSphere
Definition: ClusterLabelTool.hpp:258
rviz_map_plugin::ClusterLabelTool::~ClusterLabelTool
~ClusterLabelTool()
Destructor.
Definition: ClusterLabelTool.cpp:82
rviz::DisplayContext::getSceneManager
virtual Ogre::SceneManager * getSceneManager() const=0
rviz_map_plugin::ClusterLabelTool::m_sphereSize
float m_sphereSize
Definition: ClusterLabelTool.hpp:210
rviz_map_plugin::ClusterLabelTool::resetVisual
void resetVisual()
Resets the current visual.
Definition: ClusterLabelTool.cpp:732
rviz_map_plugin::ClusterLabelTool::m_vertexPositions
std::vector< Ogre::Vector3 > m_vertexPositions
Definition: ClusterLabelTool.hpp:223
rviz::ViewportMouseEvent::viewport
Ogre::Viewport * viewport
rviz_map_plugin::ClusterLabelTool::m_clKernelSingleRay
cl::Kernel m_clKernelSingleRay
Definition: ClusterLabelTool.hpp:257
ClusterLabelVisual.hpp
class_list_macros.h
rviz_map_plugin::ClusterLabelTool::m_clVertexBuffer
cl::Buffer m_clVertexBuffer
Definition: ClusterLabelTool.hpp:251
rviz_map_plugin::ClusterLabelDisplay
Display class for the map plugin.
Definition: ClusterLabelDisplay.hpp:136
ROS_WARN_STREAM
#define ROS_WARN_STREAM(args)
rviz_map_plugin::ClusterLabelTool::selectSingleFace
void selectSingleFace(rviz::ViewportMouseEvent &event, bool selectMode)
Definition: ClusterLabelTool.cpp:457
rviz_map_plugin::ClusterLabelTool::selectFacesInBoxParallel
void selectFacesInBoxParallel(Ogre::PlaneBoundedVolume &volume, bool selectMode)
Definition: ClusterLabelTool.cpp:399
rviz_map_plugin::ClusterLabelTool::getSelectedFaces
std::vector< uint32_t > getSelectedFaces()
Returns a list of selected face ID's.
Definition: ClusterLabelTool.cpp:709
rviz_map_plugin::ClusterLabelTool::m_clQueue
cl::CommandQueue m_clQueue
Definition: ClusterLabelTool.hpp:250
rviz_map_plugin::CLUtil::getErrorDescription
static const char * getErrorDescription(cl_int error)
Returns a description to a given OpenCL error code.
Definition: CLUtil.hpp:216
PLUGINLIB_EXPORT_CLASS
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
rviz_map_plugin::ClusterLabelTool::setSphereSize
void setSphereSize(float size)
Adjust the sphere size for the brush tool.
Definition: ClusterLabelTool.cpp:247
rviz_map_plugin::ClusterLabelTool::getClosestIntersectedFaceParallel
boost::optional< std::pair< uint32_t, float > > getClosestIntersectedFaceParallel(Ogre::Ray &ray)
Definition: ClusterLabelTool.cpp:589
rviz_map_plugin::ClusterLabelTool::m_clResultBuffer
cl::Buffer m_clResultBuffer
Definition: ClusterLabelTool.hpp:252
rviz_map_plugin::ClusterLabelTool::m_sceneNode
Ogre::SceneNode * m_sceneNode
Definition: ClusterLabelTool.hpp:214
ROS_DEBUG
#define ROS_DEBUG(...)
rviz_map_plugin::ClusterLabelDisplay::addLabel
void addLabel(string label, vector< uint32_t > faces)
The tool will call this function and emit the signal below to the master display to create the label.
Definition: ClusterLabelDisplay.cpp:345
rviz::Tool::shortcut_key_
char shortcut_key_
rviz_map_plugin::ClusterLabelTool::m_clRayBuffer
cl::Buffer m_clRayBuffer
Definition: ClusterLabelTool.hpp:253
rviz_map_plugin::ClusterLabelTool::resetFaces
void resetFaces()
Resets the list of selected faces.
Definition: ClusterLabelTool.cpp:723
rviz::Tool::Render
Render
rviz::ViewportMouseEvent::y
int y
rviz_map_plugin::ClusterLabelTool::ClusterLabelTool
ClusterLabelTool()
Constructor.
Definition: ClusterLabelTool.cpp:74
rviz_map_plugin::ClusterLabelTool::m_clStartNormalBuffer
cl::Buffer m_clStartNormalBuffer
Definition: ClusterLabelTool.hpp:256
rviz_map_plugin::ClusterLabelTool::m_meshGeometry
std::shared_ptr< Geometry > m_meshGeometry
Definition: ClusterLabelTool.hpp:209
rviz_map_plugin::ClusterLabelTool::deactivate
virtual void deactivate()
Definition: ClusterLabelTool.cpp:257
CL_RAY_CAST_KERNEL_FILE
#define CL_RAY_CAST_KERNEL_FILE
Definition: ClusterLabelTool.cpp:72
rviz_map_plugin::ClusterLabelTool::m_clBoxBuffer
cl::Buffer m_clBoxBuffer
Definition: ClusterLabelTool.hpp:255
rviz_map_plugin::ClusterLabelTool::m_labelPublisher
ros::Publisher m_labelPublisher
Definition: ClusterLabelTool.hpp:236
rviz_map_plugin::ClusterLabelTool::updateSelectionBox
void updateSelectionBox()
Definition: ClusterLabelTool.cpp:328
rviz::ViewportMouseEvent::control
bool control()
rviz_map_plugin::ClusterLabelTool::m_selectionBox
Ogre::ManualObject * m_selectionBox
Definition: ClusterLabelTool.hpp:215
ClusterLabelTool.hpp
rviz_map_plugin::ClusterLabelTool::setDisplay
void setDisplay(ClusterLabelDisplay *display)
Connects this tool with a given display.
Definition: ClusterLabelTool.cpp:261
rviz_map_plugin::ClusterLabelTool::m_vertexData
std::vector< float > m_vertexData
Definition: ClusterLabelTool.hpp:238
rviz::ViewportMouseEvent::leftUp
bool leftUp()
rviz_map_plugin::ClusterLabelTool::m_selectionBoxMaterial
Ogre::MaterialPtr m_selectionBoxMaterial
Definition: ClusterLabelTool.hpp:216
rviz_map_plugin::ClusterLabelTool::m_resultDistances
std::vector< float > m_resultDistances
Definition: ClusterLabelTool.hpp:243
rviz_map_plugin::ClusterLabelTool::setVisual
void setVisual(std::shared_ptr< ClusterLabelVisual > visual)
Connects this tool with a given visual.
Definition: ClusterLabelTool.cpp:231
rviz_map_plugin::ClusterLabelTool::activate
virtual void activate()
RViz callback for activating.
Definition: ClusterLabelTool.cpp:253
rviz_map_plugin::ClusterLabelTool::onInitialize
virtual void onInitialize()
RViz callback on initialize.
Definition: ClusterLabelTool.cpp:92
ROS_ERROR
#define ROS_ERROR(...)
rviz_map_plugin
Definition: ClusterLabelDisplay.hpp:120
rviz_map_plugin::ClusterLabelTool::m_sphereData
std::array< float, 4 > m_sphereData
Definition: ClusterLabelTool.hpp:240
rviz::ViewportMouseEvent::rightDown
bool rightDown()
rviz_map_plugin::ClusterLabelTool::m_multipleSelect
bool m_multipleSelect
Definition: ClusterLabelTool.hpp:219
rviz_map_plugin::ClusterLabelTool::m_rayData
std::array< float, 6 > m_rayData
Definition: ClusterLabelTool.hpp:239
rviz_map_plugin::ClusterLabelTool::m_clProgramSources
cl::Program::Sources m_clProgramSources
Definition: ClusterLabelTool.hpp:248
ROS_INFO
#define ROS_INFO(...)
rviz_map_plugin::ClusterLabelTool::selectSphereFaces
void selectSphereFaces(rviz::ViewportMouseEvent &event, bool selectMode)
Definition: ClusterLabelTool.cpp:525
rviz_map_plugin::ClusterLabelTool::m_clContext
cl::Context m_clContext
Definition: ClusterLabelTool.hpp:247
rviz_map_plugin::ClusterLabelTool::processMouseEvent
virtual int processMouseEvent(rviz::ViewportMouseEvent &event)
RViz callback for mouse events.
Definition: ClusterLabelTool.cpp:651
rviz_map_plugin::ClusterLabelTool::m_clKernelBox
cl::Kernel m_clKernelBox
Definition: ClusterLabelTool.hpp:259
rviz_map_plugin::ClusterLabelTool::m_clProgram
cl::Program m_clProgram
Definition: ClusterLabelTool.hpp:249
rviz_map_plugin::ClusterLabelTool::m_singleDeselect
bool m_singleDeselect
Definition: ClusterLabelTool.hpp:221
color_property.h
ros::NodeHandle
rviz_map_plugin::ClusterLabelTool::m_clSphereBuffer
cl::Buffer m_clSphereBuffer
Definition: ClusterLabelTool.hpp:254
rviz_map_plugin::ClusterLabelTool::m_clDevice
cl::Device m_clDevice
Definition: ClusterLabelTool.hpp:246
rviz_map_plugin::ClusterLabelTool::m_selectionStop
Ogre::Vector2 m_selectionStop
Definition: ClusterLabelTool.hpp:218


rviz_map_plugin
Author(s): Sebastian Pütz , Kristin Schmidt , Jan Philipp Vogtherr , Malte kleine Piening
autogenerated on Sun Jan 21 2024 04:06:25