Developer Documentation
OMPropertyVisualizerVector2T_impl.hh
1 /* ========================================================================= *
2  * *
3  * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40  * ========================================================================= */
41 
42 
43 #define OM_PROPERTY_VISUALIZER_VECTOR2_CC
44 
45 #include "OMPropertyVisualizerVector2.hh"
46 #include <OpenMesh/Core/Utils/Property.hh>
47 #include <ACG/Utils/ColorConversion.hh>
48 
49 template <typename MeshT, typename VectorType>
51  : OMPropertyVisualizer<MeshT>(_mesh, _objectID, _propertyInfo)
52 {
53  if (PropertyVisualizer::widget) delete PropertyVisualizer::widget;
54  VectorWidget* w = new VectorWidget();
55  w->paramVector->setTitle(QString("2D Vector Parameters of ").append(PropertyVisualizer::propertyInfo.propName().c_str()));
56  PropertyVisualizer::widget = w;
57 
58  BaseObjectData *bod;
59  PluginFunctions::getObject(_objectID, bod);
60 
61  lineNode = new ACG::SceneGraph::LineNode( ACG::SceneGraph::LineNode::LineSegmentsMode, bod->baseNode());
62 
63  if (!_propertyInfo.isFaceProp())
64  {
65  w->vectors_edges_rb->hide();
66  }
67  this->connect(w->lineWidth, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
68  [this](double value) {lineNode->set_line_width(value);});
69 }
70 
71 template <typename MeshT, typename VectorType>
73 {
74  lineNode->clear();
76 }
77 
78 template <typename MeshT, typename VectorType>
80 {
81  return OMPropertyVisualizer<MeshT>::template getPropertyText_<VectorType>(index);
82 }
83 
84 
85 namespace {
86 
87 template<typename PROPTYPE, typename VectorType, typename MeshT, typename ENTITY_IT, typename PROPINFO_TYPE>
88 void visualizeVectorAsColorForEntity2(MeshT *mesh, const ENTITY_IT e_begin, const ENTITY_IT e_end,
89  const PROPINFO_TYPE &propinfo) {
90  PROPTYPE prop;
91  if (!mesh->get_property_handle(prop, propinfo.propName()))
92  throw VizException("Getting PropHandle from mesh for selected property failed.");
93  for (ENTITY_IT e_it = e_begin; e_it != e_end; ++e_it) {
94  VectorType v = mesh->property(prop, *e_it).normalized() * .5 + VectorType(0.5);
95  mesh->set_color(*e_it, typename MeshT::Color(v[0], v[1], 0.0, 1.0));
96  }
97 }
98 
99 template<typename PROPTYPE, typename MeshT, typename ENTITY_IT, typename PROPINFO_TYPE>
100 void visualizeVectorLengthAsColorForEntity2(
101  MeshT *mesh, const ENTITY_IT e_begin, const ENTITY_IT e_end,
102  const PROPINFO_TYPE &propinfo) {
103  PROPTYPE prop;
104  if (!mesh->get_property_handle(prop, propinfo.propName()))
105  throw VizException("Getting PropHandle from mesh for selected "
106  "property failed.");
107 
108  double min = std::numeric_limits<double>::infinity();
109  double max = -std::numeric_limits<double>::infinity();
110 
111  for (ENTITY_IT e_it = e_begin; e_it != e_end; ++e_it) {
112  const double val = mesh->property(prop, *e_it).norm();
113  min = std::min(min, val);
114  max = std::max(max, val);
115  }
116 
117  ACG::ColorCoder color_coder(min, max);
118 
119  for (ENTITY_IT e_it = e_begin; e_it != e_end; ++e_it) {
120  mesh->set_color(*e_it, color_coder(mesh->property(prop, *e_it).norm()));
121  }
122 }
123 
124 template <typename VectorType> ACG::Vec3d generateVec3AtLocation(VectorType uv, ACG::Vec3d normal)
125 {
126  ACG::Vec3d tan;
127  if(std::abs(normal[0]) > std::abs(normal[1]))
128  tan = ACG::Vec3d(-normal[2], 0, normal[0]);
129  else tan = ACG::Vec3d(0, normal[2], -normal[1]);
130  ACG::Vec3d bi = normal % tan;
131  return double(uv[0]) * tan.normalize() + double(uv[1]) * bi.normalize();
132 }
133 
134 }
135 
136 template <typename MeshT, typename VectorType>
138 {
139  VectorWidget* const w = (VectorWidget*)PropertyVisualizer::widget;
140  if (w->vectors_edges_rb->isChecked()) {
141  visualizeFacePropOnEdges();
142  } else if (w->vectors_colors_rb->isChecked() ||
143  w->vectors_length_color_rb->isChecked()) {
144  if ( !OMPropertyVisualizer<MeshT>::mesh->has_face_colors() )
145  OMPropertyVisualizer<MeshT>::mesh->request_face_colors();
146 
147  if (w->vectors_colors_rb->isChecked()) {
148  visualizeVectorAsColorForEntity2<OpenMesh::FPropHandleT<VectorType>, VectorType >(
150  OMPropertyVisualizer<MeshT>::mesh->faces_begin(),
151  OMPropertyVisualizer<MeshT>::mesh->faces_end(),
152  PropertyVisualizer::propertyInfo);
153  } else {
154  visualizeVectorLengthAsColorForEntity2<OpenMesh::FPropHandleT<VectorType> >(
156  OMPropertyVisualizer<MeshT>::mesh->faces_begin(),
157  OMPropertyVisualizer<MeshT>::mesh->faces_end(),
158  PropertyVisualizer::propertyInfo);
159  }
160  if (_setDrawMode)
162  }
163  else visualizeFacePropAsStrokes();
164 }
165 
166 template <typename MeshT, typename VectorType>
168 {
169  VectorWidget* const w = (VectorWidget*)PropertyVisualizer::widget;
170  if (w->vectors_colors_rb->isChecked() ||
171  w->vectors_length_color_rb->isChecked()) {
172  if ( !OMPropertyVisualizer<MeshT>::mesh->has_edge_colors() )
173  OMPropertyVisualizer<MeshT>::mesh->request_edge_colors();
174  MeshT* mesh = OMPropertyVisualizer<MeshT>::mesh;
175  if ( !mesh->has_edge_colors() )
176  mesh->request_edge_colors();
177  if (w->vectors_colors_rb->isChecked()) {
178  visualizeVectorAsColorForEntity2<
180  mesh,
181  mesh->edges_begin(),
182  mesh->edges_end(),
183  PropertyVisualizer::propertyInfo);
184  } else {
185  visualizeVectorLengthAsColorForEntity2<
187  mesh,
188  mesh->edges_begin(),
189  mesh->edges_end(),
190  PropertyVisualizer::propertyInfo);
191  }
192  if (_setDrawMode)
194  }
195  else visualizeEdgePropAsStrokes();
196 }
197 
198 template <typename MeshT, typename VectorType>
200 {
201  VectorWidget* const w = (VectorWidget*)PropertyVisualizer::widget;
202  if (w->vectors_colors_rb->isChecked() ||
203  w->vectors_length_color_rb->isChecked()) {
204  if ( !OMPropertyVisualizer<MeshT>::mesh->has_halfedge_colors() )
205  OMPropertyVisualizer<MeshT>::mesh->request_halfedge_colors();
206  MeshT* mesh = OMPropertyVisualizer<MeshT>::mesh;
207  if ( ! mesh->has_halfedge_colors() )
208  mesh->request_halfedge_colors();
209 
210  if (w->vectors_colors_rb->isChecked()) {
211  visualizeVectorAsColorForEntity2<
213  mesh,
214  mesh->halfedges_begin(),
215  mesh->halfedges_end(),
216  PropertyVisualizer::propertyInfo);
217  } else {
218  visualizeVectorLengthAsColorForEntity2<
220  mesh,
221  mesh->halfedges_begin(),
222  mesh->halfedges_end(),
223  PropertyVisualizer::propertyInfo);
224  }
225 
226  if (_setDrawMode)
227  this->setDrawMode(
229  }
230  else visualizeHalfedgePropAsStrokes();
231 }
232 
233 template <typename MeshT, typename VectorType>
235 {
236  VectorWidget* const w = (VectorWidget*)PropertyVisualizer::widget;
237  if (w->vectors_colors_rb->isChecked() ||
238  w->vectors_length_color_rb->isChecked()) {
239  if ( !OMPropertyVisualizer<MeshT>::mesh->has_vertex_colors() )
240  OMPropertyVisualizer<MeshT>::mesh->request_vertex_colors();
241 
242  if (w->vectors_colors_rb->isChecked()) {
243  visualizeVectorAsColorForEntity2<
246  OMPropertyVisualizer<MeshT>::mesh->vertices_begin(),
247  OMPropertyVisualizer<MeshT>::mesh->vertices_end(),
248  PropertyVisualizer::propertyInfo);
249  } else {
250  visualizeVectorLengthAsColorForEntity2<
253  OMPropertyVisualizer<MeshT>::mesh->vertices_begin(),
254  OMPropertyVisualizer<MeshT>::mesh->vertices_end(),
255  PropertyVisualizer::propertyInfo);
256  }
257  if (_setDrawMode)
258  this->setDrawMode(
260  }
261  else visualizeVertexPropAsStrokes();
262 }
263 
264 template <typename MeshT, typename VectorType>
266  VectorWidget* w = (VectorWidget*)PropertyVisualizer::widget;
267  MeshT* _mesh = OMPropertyVisualizer<MeshT>::mesh;
268 
269 
270  const double thresh_1 = w->vectors_edges_alpha->value();
271  const double thresh_2 = std::min(thresh_1, w->vectors_edges_alpha->value());
272 
274  if (!_mesh->get_property_handle(prop, PropertyVisualizer::propertyInfo.propName()))
275  throw VizException("Getting PropHandle from mesh for selected property failed.");
276 
277  if (!_mesh->has_edge_colors())
278  _mesh->request_edge_colors();
279  const ACG::Vec4f cold(0, 0, 0, 1.0), hot(0, 1, 0, 1.0), degen(1, 1, 0, 1.0);
280  for (typename MeshT::EdgeIter e_it = _mesh->edges_begin(), e_end = _mesh->edges_end();
281  e_it != e_end; ++e_it) {
282  VectorType p1 = _mesh->property(prop, _mesh->face_handle(_mesh->halfedge_handle(*e_it, 0)));
283  VectorType p2 = _mesh->property(prop, _mesh->face_handle(_mesh->halfedge_handle(*e_it, 1)));
284 
285  ACG::Vec4f color;
286 
287  const char degenerate = ((p1.sqrnorm() < 1e-6) ? 1 : 0) | ((p2.sqrnorm() < 1e-6) ? 2 : 0);
288  if (degenerate == 3) {
289  color = cold;
290  } else if (degenerate == 0) {
291  p1.normalize(); p2.normalize();
292  const double alpha = std::min(1.0, double(std::abs(p1 | p2)));
293  if (alpha < thresh_1)
294  color = hot;
295  else if (alpha > thresh_2)
296  color = cold;
297  else {
298  const double beta = (alpha - thresh_1) / (thresh_2 - thresh_1);
299  color = cold * beta + hot * (1.0 - beta);
300  }
301  } else {
302  color = degen;
303  }
304  _mesh->set_color(*e_it, color);
305  }
307 }
308 
309 template <typename MeshT, typename VectorType>
311 {
312  VectorWidget* vectorWidget = static_cast<VectorWidget*>(PropertyVisualizer::widget);
313 
314  lineNode->clear();
315 
316  typename MeshT::Color color = ACG::to_Vec4f(vectorWidget->lineColor->color());
317 
319 
320  if ( !OMPropertyVisualizer<MeshT>::mesh->get_property_handle(prop, OMPropertyVisualizer<MeshT>::propertyInfo.propName() ) )
321  return;
322 
323  for (typename MeshT::FaceIter f_it = OMPropertyVisualizer<MeshT>::mesh->faces_begin() ; f_it != OMPropertyVisualizer<MeshT>::mesh->faces_end() ; ++f_it){
324 
325  typename MeshT::Point center(0.0, 0.0, 0.0);
326  int vCount = 0;
327 
328  for (typename MeshT::FaceVertexIter fv_it(*(OMPropertyVisualizer<MeshT>::mesh),*f_it); fv_it.is_valid(); ++fv_it){
329  vCount++;
330  center += OMPropertyVisualizer<MeshT>::mesh->point(*fv_it);
331  }
332 
333  center /= vCount;
334 
335  VectorType v = (OMPropertyVisualizer<MeshT>::mesh->property(prop, *f_it));
336  ACG::Vec3d normal = OMPropertyVisualizer<MeshT>::mesh->normal(*f_it);
337 
338  if (vectorWidget->normalize->isChecked() && v.sqrnorm() > 1e-12)
339  v.normalize();
340 
341  if(vectorWidget->scale->isChecked())
342  v *= vectorWidget->scaleBox->value();
343 
344  lineNode->add_line( center, (center+generateVec3AtLocation<VectorType>(v, normal)) );
345  lineNode->add_color(color);
346  }
347 }
348 
349 template <typename MeshT, typename VectorType>
351 {
352  VectorWidget* vectorWidget = static_cast<VectorWidget*>(PropertyVisualizer::widget);
353 
354  lineNode->clear();
355 
356  typename MeshT::Color color = ACG::to_Vec4f(vectorWidget->lineColor->color());
357 
358  //TODO check if this also works if the property is Vec3f
360 
361  if ( !OMPropertyVisualizer<MeshT>::mesh->get_property_handle(prop, OMPropertyVisualizer<MeshT>::propertyInfo.propName() ) )
362  return;
363 
364  for (typename MeshT::EdgeIter e_it = OMPropertyVisualizer<MeshT>::mesh->edges_begin() ; e_it != OMPropertyVisualizer<MeshT>::mesh->edges_end() ; ++e_it){
365 
366  typename MeshT::HalfedgeHandle hh = OMPropertyVisualizer<MeshT>::mesh->halfedge_handle( *e_it, 0 );
367 
368  typename MeshT::VertexHandle vh0 = OMPropertyVisualizer<MeshT>::mesh->from_vertex_handle( hh );
369  typename MeshT::VertexHandle vh1 = OMPropertyVisualizer<MeshT>::mesh->to_vertex_handle( hh );
370 
371  typename MeshT::Point v1 = OMPropertyVisualizer<MeshT>::mesh->point(vh0) + 0.5 * (OMPropertyVisualizer<MeshT>::mesh->point(vh1) - OMPropertyVisualizer<MeshT>::mesh->point(vh0));
372  VectorType v = OMPropertyVisualizer<MeshT>::mesh->property(prop, *e_it);
373  ACG::Vec3d normal = OMPropertyVisualizer<MeshT>::mesh->normal(OMPropertyVisualizer<MeshT>::mesh->halfedge_handle(*e_it, 0));
374 
375  if (vectorWidget->normalize->isChecked() && v.sqrnorm() > 1e-12)
376  v.normalize();
377 
378  if(vectorWidget->scale->isChecked())
379  v *= vectorWidget->scaleBox->value();
380 
381  lineNode->add_line( v1, (v1+generateVec3AtLocation<VectorType>(v, normal)) );
382  lineNode->add_color(color);
383  }
384 }
385 
386 template <typename MeshT, typename VectorType>
388 {
389  VectorWidget* vectorWidget = static_cast<VectorWidget*>(PropertyVisualizer::widget);
390 
391  lineNode->clear();
392 
393  typename MeshT::Color color = ACG::to_Vec4f(vectorWidget->lineColor->color());
394 
395  //TODO check if this also works if the property is Vec3f
397 
398  if ( !OMPropertyVisualizer<MeshT>::mesh->get_property_handle(prop, OMPropertyVisualizer<MeshT>::propertyInfo.propName() ) )
399  return;
400 
401  for (typename MeshT::HalfedgeIter he_it = OMPropertyVisualizer<MeshT>::mesh->halfedges_begin() ; he_it != OMPropertyVisualizer<MeshT>::mesh->halfedges_end() ; ++he_it){
402 
403  typename MeshT::VertexHandle vh0 = OMPropertyVisualizer<MeshT>::mesh->from_vertex_handle( *he_it );
404  typename MeshT::VertexHandle vh1 = OMPropertyVisualizer<MeshT>::mesh->to_vertex_handle( *he_it );
405 
406  typename MeshT::Point v1 = OMPropertyVisualizer<MeshT>::mesh->point(vh0) + 0.5 * (OMPropertyVisualizer<MeshT>::mesh->point(vh1) - OMPropertyVisualizer<MeshT>::mesh->point(vh0));
407  VectorType v = OMPropertyVisualizer<MeshT>::mesh->property(prop, *he_it);
409 
410  if (vectorWidget->normalize->isChecked() && v.sqrnorm() > 1e-12)
411  v.normalize();
412 
413  if(vectorWidget->scale->isChecked())
414  v *= vectorWidget->scaleBox->value();
415 
416  lineNode->add_line( v1, (v1+generateVec3AtLocation<VectorType>(v, normal)) );
417  lineNode->add_color(color);
418  }
419 }
420 
421 template <typename MeshT, typename VectorType>
423 {
424  VectorWidget* vectorWidget = static_cast<VectorWidget*>(PropertyVisualizer::widget);
425 
426  lineNode->clear();
427 
428  typename MeshT::Color color = ACG::to_Vec4f(vectorWidget->lineColor->color());
429 
430  //TODO check if this also works if the property is Vec3f
432 
433  if ( !OMPropertyVisualizer<MeshT>::mesh->get_property_handle(prop, OMPropertyVisualizer<MeshT>::propertyInfo.propName() ) )
434  return;
435 
436  for (typename MeshT::VertexIter v_it = OMPropertyVisualizer<MeshT>::mesh->vertices_begin() ; v_it != OMPropertyVisualizer<MeshT>::mesh->vertices_end() ; ++v_it){
437 
438  typename MeshT::Point v1 = OMPropertyVisualizer<MeshT>::mesh->point( *v_it );
439  VectorType v = OMPropertyVisualizer<MeshT>::mesh->property(prop, *v_it);
440  ACG::Vec3d normal = OMPropertyVisualizer<MeshT>::mesh->normal(*v_it);
441 
442  if (vectorWidget->normalize->isChecked() && v.sqrnorm() > 1e-12)
443  v.normalize();
444 
445  if(vectorWidget->scale->isChecked())
446  v *= vectorWidget->scaleBox->value();
447 
448  lineNode->add_line( v1, (v1+generateVec3AtLocation<VectorType>(v, normal)) );
449  lineNode->add_color(color);
450  }
451 }
452 
453 template <typename MeshT, typename VectorType>
455 {
457  MeshT* mesh = OMPropertyVisualizer<MeshT>::mesh;
458 
459  if ( !mesh->get_property_handle(prop, PropertyVisualizer::propertyInfo.propName() ) )
460  emit this->log(LOGERR, QObject::tr("Error: No property with name ").append(PropertyVisualizer::propertyInfo.propName().c_str()));
461 
462 
463  typename MeshT::FaceHandle fh = mesh->face_handle(index);
464 
465  mesh->property(prop, fh) = this->strToVec2f(text);
466 }
467 
468 template <typename MeshT, typename VectorType>
470 {
472  MeshT* mesh = OMPropertyVisualizer<MeshT>::mesh;
473 
474  if ( !mesh->get_property_handle(prop, PropertyVisualizer::propertyInfo.propName() ) )
475  emit this->log(LOGERR, QObject::tr("Error: No property with name ").append(PropertyVisualizer::propertyInfo.propName().c_str()));
476 
477 
478  typename MeshT::EdgeHandle eh = mesh->edge_handle(index);
479 
480  mesh->property(prop, eh) = this->strToVec2f(text);
481 }
482 
483 template <typename MeshT, typename VectorType>
485 {
487  MeshT* mesh = OMPropertyVisualizer<MeshT>::mesh;
488 
489  if ( !mesh->get_property_handle(prop, PropertyVisualizer::propertyInfo.propName() ) )
490  emit this->log(LOGERR, QObject::tr("Error: No property with name ").append(PropertyVisualizer::propertyInfo.propName().c_str()));
491 
492 
493  typename MeshT::HalfedgeHandle heh = mesh->halfedge_handle(index);
494 
495  mesh->property(prop, heh) = this->strToVec2f(text);
496 }
497 
498 template <typename MeshT, typename VectorType>
500 {
502  MeshT* mesh = OMPropertyVisualizer<MeshT>::mesh;
503 
504  if ( !mesh->get_property_handle(prop, PropertyVisualizer::propertyInfo.propName() ) )
505  emit this->log(LOGERR, QObject::tr("Error: No property with name ").append(PropertyVisualizer::propertyInfo.propName().c_str()));
506 
507 
508  typename MeshT::VertexHandle vh = mesh->vertex_handle(index);
509 
510  mesh->property(prop, vh) = this->strToVec2f(text);
511 }
512 
513 
514 template <typename MeshT, typename VectorType>
516 {
517  OMPropertyVisualizer<MeshT>::template removeProperty_stage1<VectorType>();
518 }
519 
520 template <typename MeshT, typename VectorType>
522 {
523  OMPropertyVisualizer<MeshT>::template duplicateProperty_stage1<VectorType>();
524 }
525 
QString getPropertyText(unsigned int index) override
Returns the value of a property in text form.
SeparatorNode * baseNode()
void add_line(const Vec3d &_v0, const Vec3d &_v1)
add line (for LineMode == LineSegmentsMode)
Definition: LineNode.cc:151
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
void clear()
clear points/lines and colors
Definition: LineNode.cc:101
Add colors to mesh item (vertices/faces/edges)
Definition: Attributes.hh:83
DrawMode HALFEDGES_COLORED
draw halfedges with colors (without shading)
Definition: DrawModes.cc:103
DrawMode SOLID_POINTS_COLORED
draw colored, but not lighted faces using interpolated vertex colors
Definition: DrawModes.cc:85
Cellection of information about a property.
Definition: Utils.hh:109
virtual void clear()
Clears the property.
DrawMode SOLID_FLAT_SHADED
draw flat shaded faces (requires face normals)
Definition: DrawModes.cc:81
void duplicateProperty() override
Duplicates the property.
DrawMode SOLID_FACES_COLORED
draw colored, but not lighted faces using face colors
Definition: DrawModes.cc:84
void clear() override
Clears the property.
DrawMode EDGES_COLORED
draw edges with colors (without shading)
Definition: DrawModes.cc:77
Class for generating nice colors for doubles.
Definition: ColorCoder.hh:68
void add_color(const ACG::Vec3uc &_c)
add color (only for LineMode == LineSegmentsMode)
Definition: LineNode.cc:162
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
Definition: Vector11T.hh:453
void removeProperty() override
Removes the property.
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:121