ClusterLabelVisual.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  * ClusterLabelVisual.cpp
41  *
42  *
43  * authors:
44  *
45  * Kristin Schmidt <krschmidt@uni-osnabrueck.de>
46  */
47 
48 #include <ClusterLabelVisual.hpp>
49 
50 #include <rviz/display_context.h>
51 
52 #include <OGRE/OgreEntity.h>
53 #include <OGRE/OgreMaterialManager.h>
54 #include <OGRE/OgreMesh.h>
55 #include <OGRE/OgreMeshManager.h>
56 #include <OGRE/OgreSceneManager.h>
57 #include <OGRE/OgreSceneNode.h>
58 #include <OGRE/OgreSubMesh.h>
59 
60 namespace rviz_map_plugin
61 {
63  : m_displayContext(context), m_labelId(labelId)
64 {
65 }
66 
68  std::shared_ptr<Geometry> geometry)
69  : m_displayContext(context), m_labelId(labelId), m_geometry(geometry)
70 {
71  // Get or create scene node
72  Ogre::SceneManager* sceneManager = m_displayContext->getSceneManager();
73  Ogre::SceneNode* rootNode = sceneManager->getRootSceneNode();
74 
75  std::stringstream strstream;
76  strstream << "ClusterLabelScene";
77  std::string sceneId = strstream.str();
78 
79  if (sceneManager->hasSceneNode(sceneId))
80  {
81  m_sceneNode = (Ogre::SceneNode*)(rootNode->getChild(sceneId));
82  }
83  else
84  {
85  m_sceneNode = rootNode->createChildSceneNode(sceneId);
86  }
87 
88  // Retrieve or create the mesh and attach it to the scene node
89  m_mesh = Ogre::MeshManager::getSingleton().getByName("ClusterLabelMesh", "General");
90  if (m_mesh.isNull() && geometry)
91  {
92  m_mesh = Ogre::MeshManager::getSingleton().createManual("ClusterLabelMesh", "General");
93 
94  // Create the vertex data structure
95  m_mesh->sharedVertexData = new Ogre::VertexData;
96  m_mesh->sharedVertexData->vertexCount = geometry->vertices.size();
97 
98  // Declare how the vertices will be represented
99  Ogre::VertexDeclaration* decl = m_mesh->sharedVertexData->vertexDeclaration;
100  size_t offset = 0;
101 
102  // The first three floats of each vertex represent the position
103  decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
104  offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
105 
106  // Create the vertex buffer
107  Ogre::HardwareVertexBufferSharedPtr vertexBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
108  offset, m_mesh->sharedVertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC);
109 
110  // Lock the buffer so we can get exclusive access to its data
111  float* vertices = static_cast<float*>(vertexBuffer->lock(Ogre::HardwareBuffer::HBL_NORMAL));
112 
113  // Write the mesh data into the buffer
114  for (int i = 0; i < m_mesh->sharedVertexData->vertexCount; i++)
115  {
116  vertices[(i * 3) + 0] = geometry->vertices[i].x;
117  vertices[(i * 3) + 1] = geometry->vertices[i].y;
118  vertices[(i * 3) + 2] = geometry->vertices[i].z;
119  }
120 
121  // Unlock the buffer
122  vertexBuffer->unlock();
123 
124  // Attach the vertex buffer to the mesh
125  m_mesh->sharedVertexData->vertexBufferBinding->setBinding(0, vertexBuffer);
126 
127  // Set the bounds of the mesh
128  // TODO: Calculate the correct bounding box
129  m_mesh->_setBounds(Ogre::AxisAlignedBox::EXTENT_INFINITE);
130 
131  // Notify the mesh that we're all ready
132  m_mesh->load();
133 
134  // Create an entity of the mesh and add it to the scene
135  Ogre::Entity* entity = sceneManager->createEntity("ClusterLabelEntity", "ClusterLabelMesh", "General");
136  entity->setMaterialName("CustomMaterial", "General");
137  m_sceneNode->attachObject(entity);
138  }
139 
140  // Create a submesh and a custom material for it
141  if (!m_mesh.isNull())
142  {
143  m_subMesh = m_mesh->createSubMesh(m_labelId);
144  m_subMesh->useSharedVertices = true;
145  std::stringstream sstm;
146  sstm << "ClusterLabel_Material_" << m_labelId;
147  m_material = Ogre::MaterialManager::getSingleton().create(
148  sstm.str(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true);
149 
150  m_subMesh->setMaterialName(m_material->getName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
151  m_material->getTechnique(0)->removeAllPasses();
152  m_material->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
153  m_material->setSceneBlending(Ogre::SBT_ADD);
154  m_material->setDepthWriteEnabled(false);
155 
156  initMaterial();
157  }
158 }
159 
161 {
162  reset();
163 
164  if (!m_mesh.isNull())
165  {
166  ROS_DEBUG("ClusterLabelVisual::~ClusterLabelVisual: Destroying SubMesh: %s", m_labelId.c_str());
167 
168  try
169  {
170  m_mesh->destroySubMesh(m_labelId);
171  }
172  catch (...)
173  {
174  ROS_ERROR("Exception in Visual destructor");
175  }
176  }
177 
178  if (m_sceneNode->numAttachedObjects() == 0)
179  {
180  ROS_INFO("ClusterLabelVisual::~ClusterLabelVisual: Delete scene node");
181  m_displayContext->getSceneManager()->destroySceneNode(m_sceneNode);
182  }
183 }
184 
186 {
187  if (!m_material.isNull())
188  {
189  Ogre::MaterialManager::getSingleton().unload(m_material->getName());
190  Ogre::MaterialManager::getSingleton().remove(m_material->getName());
191  }
192 }
193 
194 void ClusterLabelVisual::setGeometry(std::shared_ptr<Geometry> geometry)
195 {
196 }
197 
198 void ClusterLabelVisual::setFacesInCluster(const std::vector<uint32_t>& faces)
199 {
200  m_faces = faces;
201 
202  if (!m_geometry)
203  {
204  ROS_WARN("ClusterLabelVisual::setFacesInCluster: MeshGeometry not set!");
205  return;
206  }
207 
208  // don't draw the cluster if there are no faces in it
209  if (faces.empty())
210  {
211  m_subMesh->indexData->indexBuffer.setNull();
212  m_subMesh->indexData->indexCount = 0;
213  m_subMesh->indexData->indexStart = 0;
214  m_material->getTechnique(0)->removeAllPasses();
215  ROS_DEBUG("ClusterLabelVisual::setFacesInCluster: faces empty!");
216  return;
217  }
218 
219  // if there are faces and there are no passes, create a pass to draw the cluster
220  if (m_material->getTechnique(0)->getNumPasses() == 0)
221  {
222  m_material->getTechnique(0)->createPass();
223  m_material->setDiffuse(m_color);
224  m_material->setSelfIllumination(m_color);
225 
226  initMaterial();
227  }
228 
229  size_t indexCount = faces.size() * 3;
230 
231  // Create the index buffer
232  Ogre::HardwareIndexBufferSharedPtr indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
233  Ogre::HardwareIndexBuffer::IT_32BIT, indexCount, Ogre::HardwareBuffer::HBU_WRITE_ONLY);
234 
235  // Lock the buffer so we can get exclusive access to its data
236  uint32_t* indices = static_cast<uint32_t*>(indexBuffer->lock(Ogre::HardwareBuffer::HBL_WRITE_ONLY));
237 
238  // Define the triangles
239  for (int i = 0; i < faces.size(); i++)
240  {
241  uint32_t faceId = faces[i];
242  indices[i * 3 + 0] = m_geometry->faces[faceId].vertexIndices[0];
243  indices[i * 3 + 1] = m_geometry->faces[faceId].vertexIndices[1];
244  indices[i * 3 + 2] = m_geometry->faces[faceId].vertexIndices[2];
245  }
246 
247  // Unlock the buffer
248  indexBuffer->unlock();
249 
250  // Attach the index buffer to the submesh
251  m_subMesh->indexData->indexBuffer = indexBuffer;
252  m_subMesh->indexData->indexCount = indexCount;
253  m_subMesh->indexData->indexStart = 0;
254 }
255 
256 void ClusterLabelVisual::setColor(Ogre::ColourValue facesColor, float alpha)
257 {
258  if (!m_material.isNull())
259  {
260  facesColor.a = alpha;
261  m_material->setDiffuse(facesColor);
262  m_material->setSelfIllumination(facesColor);
263  m_color = facesColor;
264  }
265 }
266 
268 {
269  m_material->setCullingMode(Ogre::CULL_NONE);
270  m_material->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
271  m_material->setDepthWriteEnabled(false);
272 }
273 
274 } // End namespace rviz_map_plugin
rviz_map_plugin::ClusterLabelVisual::setColor
void setColor(Ogre::ColourValue facesColor, float alpha=1.0f)
Sets the color.
Definition: ClusterLabelVisual.cpp:256
rviz_map_plugin::ClusterLabelVisual::m_material
Ogre::MaterialPtr m_material
Definition: ClusterLabelVisual.hpp:167
rviz_map_plugin::ClusterLabelVisual::m_labelId
std::string m_labelId
Definition: ClusterLabelVisual.hpp:163
rviz_map_plugin::ClusterLabelVisual::m_faces
std::vector< uint32_t > m_faces
Definition: ClusterLabelVisual.hpp:172
rviz_map_plugin::ClusterLabelVisual::m_geometry
std::shared_ptr< Geometry > m_geometry
Definition: ClusterLabelVisual.hpp:171
rviz::DisplayContext::getSceneManager
virtual Ogre::SceneManager * getSceneManager() const=0
ClusterLabelVisual.hpp
ROS_DEBUG
#define ROS_DEBUG(...)
rviz_map_plugin::ClusterLabelVisual::initMaterial
void initMaterial()
Definition: ClusterLabelVisual.cpp:267
ROS_WARN
#define ROS_WARN(...)
rviz::DisplayContext
rviz_map_plugin::ClusterLabelVisual::m_color
Ogre::ColourValue m_color
Definition: ClusterLabelVisual.hpp:169
rviz_map_plugin::ClusterLabelVisual::setFacesInCluster
void setFacesInCluster(const std::vector< uint32_t > &faces)
Sets the faces, that are in the shown cluster.
Definition: ClusterLabelVisual.cpp:198
rviz_map_plugin::ClusterLabelVisual::m_subMesh
Ogre::SubMesh * m_subMesh
Definition: ClusterLabelVisual.hpp:166
rviz_map_plugin::ClusterLabelVisual::setGeometry
void setGeometry(std::shared_ptr< Geometry > geometry)
Sets the geometry.
Definition: ClusterLabelVisual.cpp:194
rviz_map_plugin::ClusterLabelVisual::m_displayContext
rviz::DisplayContext * m_displayContext
Definition: ClusterLabelVisual.hpp:161
rviz_map_plugin::ClusterLabelVisual::~ClusterLabelVisual
~ClusterLabelVisual()
Destructor.
Definition: ClusterLabelVisual.cpp:160
rviz_map_plugin::ClusterLabelVisual::reset
void reset()
Deletes the material.
Definition: ClusterLabelVisual.cpp:185
ROS_ERROR
#define ROS_ERROR(...)
rviz_map_plugin::ClusterLabelVisual::ClusterLabelVisual
ClusterLabelVisual(rviz::DisplayContext *context, std::string labelId)
Constructor.
Definition: ClusterLabelVisual.cpp:62
rviz_map_plugin
Definition: ClusterLabelDisplay.hpp:120
ROS_INFO
#define ROS_INFO(...)
rviz_map_plugin::ClusterLabelVisual::m_mesh
Ogre::MeshPtr m_mesh
Definition: ClusterLabelVisual.hpp:165
rviz_map_plugin::ClusterLabelVisual::m_sceneNode
Ogre::SceneNode * m_sceneNode
Definition: ClusterLabelVisual.hpp:162
display_context.h


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