mesh_pose_tool.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  * mesh_pose_tool.cpp
41  *
42  * authors: Sebastian Pütz <spuetz@uos.de>
43  *
44  */
45 
46 
47 #include <OgrePlane.h>
48 #include <OgreRay.h>
49 #include <OgreSceneNode.h>
50 #include <OgreViewport.h>
51 
52 
53 #include <rviz/geometry.h>
56 #include <rviz/load_resource.h>
57 #include <rviz/render_panel.h>
58 #include <rviz/display_context.h>
59 
60 #include "mesh_pose_tool.h"
61 
62 namespace rviz_mesh_plugin
63 {
64 
66  : rviz::Tool(),
67  arrow_( NULL )
68  {
69  }
70 
72  {
73  delete arrow_;
74  }
75 
77  {
78  arrow_ = new rviz::Arrow( scene_manager_, NULL, 2.0f, 0.2f, 0.5f, 0.35f );
79  arrow_->setColor( 0.0f, 1.0f, 0.0f, 1.0f );
80  arrow_->getSceneNode()->setVisible( false );
81  }
82 
84  {
85  setStatus( "Click and on a mesh_msgs::TriangleMesh to set the position and drag the mouse for the orientation." );
86  state_ = Position;
87  }
88 
90  {
91  arrow_->getSceneNode()->setVisible( false );
92  }
93 
95  {
96  int flags = 0;
97 
98  if( event.leftDown() )
99  {
100  ROS_ASSERT( state_ == Position );
101 
102  Ogre::Vector3 pos, ori;
103  if(selectTriangle(event, pos, ori)){
104  pos_ = pos;
105  ori_ = ori;
106  arrow_->setPosition( pos_ );
108  flags |= Render;
109  }
110  }
111  else if( event.type == QEvent::MouseMove && event.left() )
112  {
113  if( state_ == Orientation )
114  {
115  Ogre::Vector3 cur_pos;
116  Ogre::Plane plane( ori_, pos_ );
118  plane, event.x, event.y, cur_pos ))
119  {
120  // right hand coordinate system
121  // x to the right, y to the top, and -z into the scene
122  // arrow foreward negative z
123  Ogre::Vector3 z_axis = - (cur_pos - pos_);
124  Ogre::Vector3 y_axis = ori_;
125  Ogre::Vector3 x_axis = y_axis.crossProduct( z_axis );
126 
127  x_axis.normalise();
128  y_axis.normalise();
129  z_axis.normalise();
130 
131  arrow_->getSceneNode()->setVisible( true );
132  arrow_->setOrientation( Ogre::Quaternion( x_axis, y_axis, z_axis) );
133 
134  flags |= Render;
135  }
136  }
137  }
138  else if( event.leftUp() )
139  {
140  if( state_ == Orientation )
141  {
142  Ogre::Vector3 cur_pos;
143  Ogre::Plane plane( ori_, pos_ );
145  plane, event.x, event.y, cur_pos ))
146  {
147  // arrow foreward negative z
148  Ogre::Vector3 z_axis = - (cur_pos - pos_);
149  Ogre::Vector3 y_axis = ori_;
150  Ogre::Vector3 x_axis = y_axis.crossProduct( z_axis );
151 
152  x_axis.normalise();
153  y_axis.normalise();
154  z_axis.normalise();
155 
156  onPoseSet(pos_, Ogre::Quaternion(x_axis, y_axis, z_axis));
157 
158  flags |= (Finished|Render);
159  }
160  }
161  }
162 
163  return flags;
164  }
165 
166 bool MeshPoseTool::selectTriangle(rviz::ViewportMouseEvent& event, Ogre::Vector3& position, Ogre::Vector3& triangle_normal)
167 {
168  Ogre::Ray ray = event.viewport->getCamera()->getCameraToViewportRay
169  ((float) event.x / event.viewport->getActualWidth(),
170  (float) event.y / event.viewport->getActualHeight());
171 
172  Ogre::RaySceneQuery* query = context_->getSceneManager()->createRayQuery(ray, Ogre::SceneManager::WORLD_GEOMETRY_TYPE_MASK);
173  query->setSortByDistance(true);
174 
175  Ogre::RaySceneQueryResult& result = query->execute();
176 
177  for (size_t i=0; i<result.size(); i++)
178  {
179  if(result[i].movable->getName().find("TriangleMesh") != std::string::npos){
180  Ogre::ManualObject* mesh = static_cast<Ogre::ManualObject*>(result[i].movable);
181  size_t goal_section = -1;
182  size_t goal_index = -1;
183  Ogre::Real dist = -1;
184  if(getPositionAndOrientation(mesh, ray, position, triangle_normal)){
185  return true;
186  }
187  }
188  }
189  return false;
190 }
191 
192 
193 
195  const Ogre::ManualObject* mesh,
196  const Ogre::Ray &ray,
197  Ogre::Vector3& position,
198  Ogre::Vector3& orientation)
199 {
200  Ogre::Real dist = -1.0f;
201  Ogre::Vector3 a, b, c;
202 
203  size_t vertex_count = 0;
204  Ogre::Vector3* vertices;
205  size_t index_count = 0;
206  unsigned long* indices;
207  size_t num_sections = mesh->getNumSections();
208 
209  for (size_t i = 0; i < num_sections; i++)
210  {
211  getRawManualObjectData(mesh, i, vertex_count, vertices, index_count, indices);
212  if(index_count != 0)
213  {
214  for (size_t j = 0; j < index_count; j += 3)
215  {
216  std::pair<bool, Ogre::Real> goal =
217  Ogre::Math::intersects(
218  ray,
219  vertices[indices[j]],
220  vertices[indices[j + 1]],
221  vertices[indices[j + 2]],
222  true,
223  true);
224 
225  if (goal.first)
226  {
227  if ((dist < 0.0f) || (goal.second < dist))
228  {
229  dist = goal.second;
230  a = vertices[indices[j]];
231  b = vertices[indices[j + 1]];
232  c = vertices[indices[j + 2]];
233  }
234  }
235  }
236  }
237  }
238 
239  delete[] vertices;
240  delete[] indices;
241  if(dist != -1){
242  position = ray.getPoint(dist);
243  Ogre::Vector3 ab = b-a;
244  Ogre::Vector3 ac = c-a;
245  orientation = ac.crossProduct(ab).normalisedCopy();
246  return true;
247  }else{
248  return false;
249  }
250 }
251 
253  const Ogre::ManualObject *mesh,
254  const size_t sectionNumber,
255  size_t& vertexCount,
256  Ogre::Vector3*& vertices,
257  size_t& indexCount,
258  unsigned long*& indices
259 ){
260  Ogre::VertexData* vertexData;
261  const Ogre::VertexElement* vertexElement;
262  Ogre::HardwareVertexBufferSharedPtr vertexBuffer;
263  unsigned char* vertexChar;
264  float* vertexFloat;
265 
266  vertexData = mesh->getSection(sectionNumber)->getRenderOperation()->vertexData;
267  vertexElement = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
268  vertexBuffer = vertexData->vertexBufferBinding->getBuffer(vertexElement->getSource());
269  vertexChar = static_cast<unsigned char*>(vertexBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
270 
271  vertexCount = vertexData->vertexCount;
272  vertices = new Ogre::Vector3[vertexCount];
273 
274  for (size_t i = 0; i < vertexCount; i++, vertexChar += vertexBuffer->getVertexSize())
275  {
276  vertexElement->baseVertexPointerToElement(vertexChar, &vertexFloat);
277  vertices[i] = (mesh->getParentNode()->_getDerivedOrientation() *
278  (Ogre::Vector3(vertexFloat[0], vertexFloat[1], vertexFloat[2]) * mesh->getParentNode()->_getDerivedScale())) +
279  mesh->getParentNode()->_getDerivedPosition();
280  }
281 
282  vertexBuffer->unlock();
283 
284  Ogre::IndexData* indexData;
285  Ogre::HardwareIndexBufferSharedPtr indexBuffer;
286  indexData = mesh->getSection(sectionNumber)->getRenderOperation()->indexData;
287  indexCount = indexData->indexCount;
288  indices = new unsigned long[indexCount];
289  indexBuffer = indexData->indexBuffer;
290  unsigned int* pLong = static_cast<unsigned int*>(indexBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
291  unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong);
292 
293  for (size_t i = 0; i < indexCount; i++)
294  {
295  unsigned long index;
296  if (indexBuffer->getType() == Ogre::HardwareIndexBuffer::IT_32BIT)
297  {
298  index = static_cast<unsigned long>(pLong[i]);
299  }
300 
301  else
302  {
303  index = static_cast<unsigned long>(pShort[i]);
304  }
305 
306  indices[i] = index;
307  }
308  indexBuffer->unlock();
309 }
310 
311 } /* rviz_mesh_plugin */
312 
rviz_mesh_plugin::MeshPoseTool::onPoseSet
virtual void onPoseSet(const Ogre::Vector3 &position, const Ogre::Quaternion &orientation)=0
rviz::ViewportMouseEvent::leftDown
bool leftDown()
NULL
#define NULL
rviz_mesh_plugin::MeshPoseTool::activate
virtual void activate()
Definition: mesh_pose_tool.cpp:83
rviz::Arrow
rviz_mesh_plugin::MeshPoseTool::ori_
Ogre::Vector3 ori_
Definition: mesh_pose_tool.h:92
rviz::Arrow::setOrientation
void setOrientation(const Ogre::Quaternion &orientation) override
rviz::Tool::scene_manager_
Ogre::SceneManager * scene_manager_
rviz::ViewportMouseEvent
rviz_mesh_plugin::MeshPoseTool::processMouseEvent
virtual int processMouseEvent(rviz::ViewportMouseEvent &event)
Definition: mesh_pose_tool.cpp:94
rviz::ViewportMouseEvent::x
int x
rviz::Tool::context_
DisplayContext * context_
viewport_mouse_event.h
rviz_mesh_plugin::MeshPoseTool::arrow_
rviz::Arrow * arrow_
Definition: mesh_pose_tool.h:84
rviz_mesh_plugin::MeshPoseTool::onInitialize
virtual void onInitialize()
Definition: mesh_pose_tool.cpp:76
mesh_pose_tool.h
rviz::ViewportMouseEvent::left
bool left()
rviz_mesh_plugin::MeshPoseTool::deactivate
virtual void deactivate()
Definition: mesh_pose_tool.cpp:89
rviz::Tool::setStatus
void setStatus(const QString &message)
rviz::DisplayContext::getSceneManager
virtual Ogre::SceneManager * getSceneManager() const=0
f
f
rviz::getPointOnPlaneFromWindowXY
bool getPointOnPlaneFromWindowXY(Ogre::Viewport *viewport, Ogre::Plane &plane, int window_x, int window_y, Ogre::Vector3 &intersection_out)
rviz::ViewportMouseEvent::viewport
Ogre::Viewport * viewport
rviz_mesh_plugin::MeshPoseTool::MeshPoseTool
MeshPoseTool()
Definition: mesh_pose_tool.cpp:65
render_panel.h
rviz
rviz::Tool::Render
Render
rviz_mesh_plugin::MeshPoseTool::Orientation
@ Orientation
Definition: mesh_pose_tool.h:88
rviz::ViewportMouseEvent::y
int y
load_resource.h
rviz::ViewportMouseEvent::type
QEvent::Type type
arrow.h
rviz_mesh_plugin::MeshPoseTool::~MeshPoseTool
virtual ~MeshPoseTool()
Definition: mesh_pose_tool.cpp:71
rviz_mesh_plugin
Definition: face_selection_tool.h:117
geometry.h
rviz::ViewportMouseEvent::leftUp
bool leftUp()
rviz_mesh_plugin::MeshPoseTool::Position
@ Position
Definition: mesh_pose_tool.h:87
rviz_mesh_plugin::MeshPoseTool::pos_
Ogre::Vector3 pos_
Definition: mesh_pose_tool.h:91
rviz_mesh_plugin::MeshPoseTool::state_
State state_
Definition: mesh_pose_tool.h:90
rviz_mesh_plugin::MeshPoseTool::getRawManualObjectData
void getRawManualObjectData(const Ogre::ManualObject *mesh, const size_t sectionNumber, size_t &vertexCount, Ogre::Vector3 *&vertices, size_t &indexCount, unsigned long *&indices)
Definition: mesh_pose_tool.cpp:252
rviz::Arrow::setPosition
void setPosition(const Ogre::Vector3 &position) override
rviz::Arrow::getSceneNode
Ogre::SceneNode * getSceneNode()
ROS_ASSERT
#define ROS_ASSERT(cond)
rviz_mesh_plugin::MeshPoseTool::selectTriangle
bool selectTriangle(rviz::ViewportMouseEvent &event, Ogre::Vector3 &position, Ogre::Vector3 &orientation)
Definition: mesh_pose_tool.cpp:166
rviz_mesh_plugin::MeshPoseTool::getPositionAndOrientation
bool getPositionAndOrientation(const Ogre::ManualObject *mesh, const Ogre::Ray &ray, Ogre::Vector3 &position, Ogre::Vector3 &orientation)
Definition: mesh_pose_tool.cpp:194
rviz::Tool::Finished
Finished
rviz::Arrow::setColor
void setColor(const Ogre::ColourValue &color)
display_context.h


rviz_mesh_plugin
Author(s): Sebastian Pütz , Henning Deeken , Marcel Mrozinski , Kristin Schmidt , Jan Philipp Vogtherr
autogenerated on Fri Feb 12 2021 04:03:57