52 #define ACG_POLYLINET_C 56 #include <OpenMesh/Core/Geometry/VectorT.hh> 63 #include "PolyLineT.hh" 66 #include <ACG/Geometry/Algorithms.hh> 67 #include <ACG/Utils/VSToolsT.hh> 89 template <
class Po
intT>
95 ref_count_vnormals_(0),
96 ref_count_vbinormals_(0),
97 ref_count_vcolors_(0),
98 ref_count_vscalars_(0),
99 ref_count_vselections_(0),
100 ref_count_vvhandles_(0),
101 ref_count_vehandles_(0),
102 ref_count_vfhandles_(0),
103 ref_count_enormals_(0),
104 ref_count_ecolors_(0),
105 ref_count_escalars_(0),
106 ref_count_eselections_(0),
107 ref_count_epreimage_direction_(0)
114 template <
class Po
intT>
124 vnormals_(_line.vnormals_),
125 vbinormals_(_line.vbinormals_),
126 vcolors_(_line.vcolors_),
127 vscalars_(_line.vscalars_),
128 vselections_(_line.vselections_),
129 vvhandles_(_line.vvhandles_),
130 vehandles_(_line.vehandles_),
131 vfhandles_(_line.vfhandles_),
134 enormals_(_line.enormals_),
135 ecolors_(_line.ecolors_),
136 escalars_(_line.escalars_),
137 eselections_(_line.eselections_),
138 epreimage_direction_(_line.epreimage_direction_),
141 ref_count_vnormals_(_line.ref_count_vnormals_),
142 ref_count_vbinormals_(_line.ref_count_vbinormals_),
143 ref_count_vcolors_(_line.ref_count_vcolors_),
144 ref_count_vscalars_(_line.ref_count_vscalars_),
145 ref_count_vselections_(_line.ref_count_vselections_),
146 ref_count_vvhandles_(_line.ref_count_vvhandles_),
147 ref_count_vehandles_(_line.ref_count_vehandles_),
148 ref_count_vfhandles_(_line.ref_count_vfhandles_),
150 ref_count_enormals_(_line.ref_count_enormals_),
151 ref_count_ecolors_(_line.ref_count_ecolors_),
152 ref_count_escalars_(_line.ref_count_escalars_),
153 ref_count_eselections_(_line.ref_count_eselections_),
154 ref_count_epreimage_direction_(_line.ref_count_epreimage_direction_)
159 for (
typename CustomPropertyMap::const_iterator it = _line.custom_properties.begin(); it != _line.custom_properties.end(); ++it) {
164 dst->name = src->name;
165 dst->ref_count = src->ref_count;
166 dst->prop_size = src->prop_size;
167 dst->prop_data = src->prop_data;
169 dst->datatype = src->datatype;
170 dst->shader_binding = src->shader_binding;
172 custom_properties[it->first] = dst;
179 template <
class Po
intT>
191 vselections_.clear();
199 eselections_.clear();
200 epreimage_direction_.clear();
202 for (
typename CustomPropertyMap::iterator it = custom_properties.begin(); it != custom_properties.end(); ++it)
204 custom_properties.clear();
209 template <
class Po
intT>
223 template <
class Po
intT>
234 if( vertex_normals_available() )
235 vnormals_.resize( _n);
236 if( vertex_binormals_available() )
237 vbinormals_.resize( _n);
238 if( vertex_colors_available())
239 vcolors_.resize( _n);
240 if( vertex_scalars_available())
241 vscalars_.resize( _n);
242 if( vertex_selections_available())
243 vselections_.resize( _n);
244 if( vertex_vhandles_available())
245 vvhandles_.resize( _n);
246 if( vertex_ehandles_available())
247 vehandles_.resize( _n);
248 if( vertex_fhandles_available())
249 vfhandles_.resize( _n);
251 if( edge_normals_available())
252 enormals_.resize( _n);
253 if( edge_colors_available())
254 ecolors_.resize( _n);
255 if( edge_scalars_available())
256 escalars_.resize( _n);
257 if( edge_preimage_directions_available())
258 epreimage_direction_.resize( _n);
261 for (
typename CustomPropertyMap::iterator it = custom_properties.begin(); it != custom_properties.end(); ++it) {
265 p->prop_data.resize(p->prop_size * _n);
280 template <
class Po
intT>
289 if( vertex_normals_available() )
290 vnormals_.push_back( Point(0,0,0));
292 if( vertex_binormals_available() )
293 vbinormals_.push_back( Point(0,0,0));
295 if( vertex_colors_available())
296 vcolors_.push_back( Point(1,0,1));
298 if( vertex_scalars_available())
299 vscalars_.push_back( 0.0 );
301 if( vertex_selections_available())
302 vselections_.push_back(
false);
304 if( vertex_vhandles_available())
305 vvhandles_.push_back(-1);
307 if( vertex_ehandles_available())
308 vehandles_.push_back(-1);
310 if( vertex_fhandles_available())
311 vfhandles_.push_back(-1);
313 if( edge_normals_available())
314 enormals_.push_back( Point(0,0,0));
316 if( edge_colors_available())
317 ecolors_.push_back( Point(1,0,1));
319 if( edge_scalars_available())
320 escalars_.push_back( 0.0);
322 if( edge_selections_available())
323 eselections_.push_back(
false);
325 if( edge_preimage_directions_available())
326 epreimage_direction_.push_back(Point(0,0,0));
329 for (
typename CustomPropertyMap::iterator it = custom_properties.begin(); it != custom_properties.end(); ++it) {
333 size_t cur_size = p->prop_data.size();
335 p->prop_data.resize(cur_size + p->prop_size);
338 memset(p->buffer() + cur_size, 0, p->prop_size);
344 template <
class Po
intT>
355 if( vertex_normals_available() )
356 vnormals_.insert(vnormals_.begin()+_idx, Point(0,0,0));
358 if( vertex_binormals_available() )
359 vbinormals_.insert(vbinormals_.begin()+_idx, Point(0,0,0));
361 if( vertex_colors_available())
362 vcolors_.insert(vcolors_.begin()+_idx, Point(1,0,1));
364 if( vertex_scalars_available())
365 vscalars_.insert(vscalars_.begin()+_idx, 0.0 );
367 if( vertex_selections_available())
368 vselections_.insert(vselections_.begin()+_idx,
false);
370 if( vertex_vhandles_available())
371 vvhandles_.insert(vvhandles_.begin()+_idx, -1);
373 if( vertex_ehandles_available())
374 vehandles_.insert(vehandles_.begin()+_idx, -1);
376 if( vertex_fhandles_available())
377 vfhandles_.insert(vfhandles_.begin()+_idx, -1);
379 if( edge_normals_available())
380 enormals_.insert(enormals_.begin()+_idx, Point(0,0,0));
382 if( edge_colors_available())
383 ecolors_.insert(ecolors_.begin()+_idx, Point(1,0,1));
385 if( edge_scalars_available())
386 escalars_.insert(escalars_.begin()+_idx, 0.0);
388 if( edge_selections_available())
389 eselections_.insert(eselections_.begin()+_idx,
false);
391 if( edge_preimage_directions_available())
392 epreimage_direction_.insert(epreimage_direction_.begin()+_idx, Point(0,0,0));
395 for (
typename CustomPropertyMap::iterator it = custom_properties.begin(); it != custom_properties.end(); ++it) {
398 unsigned int offset = p->prop_size * _idx;
400 for (
unsigned int i = 0; i < p->prop_size; ++i)
401 p->prop_data.insert(p->prop_data.begin() + offset, 0);
409 template <
class Po
intT>
421 if( vertex_normals_available() )
422 vnormals_.erase(vnormals_.begin()+_idx);
424 if( vertex_binormals_available() )
425 vbinormals_.erase(vbinormals_.begin()+_idx);
427 if( vertex_colors_available())
428 vcolors_.erase(vcolors_.begin()+_idx);
430 if( vertex_scalars_available())
431 vscalars_.erase(vscalars_.begin()+_idx);
433 if( vertex_selections_available())
434 vselections_.erase(vselections_.begin()+_idx);
436 if( vertex_vhandles_available())
437 vvhandles_.erase(vvhandles_.begin()+_idx);
439 if( vertex_ehandles_available())
440 vehandles_.erase(vehandles_.begin()+_idx);
442 if( vertex_fhandles_available())
443 vfhandles_.erase(vfhandles_.begin()+_idx);
445 if( edge_normals_available())
446 enormals_.erase(enormals_.begin()+_idx);
448 if( edge_colors_available())
449 ecolors_.erase(ecolors_.begin()+_idx);
451 if( edge_scalars_available())
452 escalars_.erase(escalars_.begin()+_idx);
454 if( edge_selections_available())
455 eselections_.erase(eselections_.begin()+_idx);
457 if( edge_preimage_directions_available())
458 epreimage_direction_.erase(epreimage_direction_.begin()+_idx);
462 for (
typename CustomPropertyMap::iterator it = custom_properties.begin(); it != custom_properties.end(); ++it) {
465 unsigned int offset = p->prop_size * _idx;
467 for (
unsigned int i = 0; i < p->prop_size; ++i)
468 p->prop_data.erase(p->prop_data.begin() + offset);
476 template <
class Po
intT>
477 typename PolyLineT<PointT>::Scalar
483 unsigned int n =
points_.size();
487 for(
unsigned int i=0; i<n-1; ++i)
494 for(
unsigned int i=0; i<n; ++i)
507 template <
class Po
intT>
508 typename PolyLineT<PointT>::Point
512 assert(_t >=0.0 && _t<=1.0);
520 template <
class Po
intT>
521 typename PolyLineT<PointT>::Point
529 return this->
front();
532 std::cerr <<
"Warning: called position_arclength on emptu PolyLine!!!" << std::endl;
539 return this->
front();
542 unsigned int ne = this->
n_edges();
546 for(
unsigned int i=0; i<ne; ++i)
550 if(l <= _t && _t <= (l+dl))
552 Scalar tl = (_t-l)/dl;
553 if(!std::isfinite(tl))
565 return this->
front();
572 template <
class Po
intT>
577 unsigned int n = std::max((
unsigned int)(2),_n);
578 Scalar l = this->
length();
584 new_pl.copy_vertex_complete(*
this, 0, 0);
588 Scalar s = l/Scalar(n-1);
589 for(
unsigned int i=1; i<n-1; ++i)
594 Scalar s = l/Scalar(n);
595 for(
unsigned int i=1; i<n; ++i)
601 new_pl.copy_vertex_complete(*
this, std::max(
int(0),
int(this->
n_vertices())-1), std::max(
int(0),
int(new_pl.
n_vertices())-1));
611 template <
class Po
intT>
620 unsigned int n_subdivisions = 1;
622 while (n_subdivisions != 0) {
629 new_pl.copy_vertex_complete(*
this, 0, 0);
632 Scalar l2 = _largest * _largest;
634 for (
unsigned int i = 1; i <
points_.size(); ++i) {
644 new_pl.copy_vertex_complete(*
this, i, new_pl.
n_vertices() - 1);
664 template <
class Po
intT>
672 unsigned int n_collapses = 1;
674 unsigned int n_iter = 0;
676 while( n_collapses != 0 && n_iter < 5)
684 new_pl.copy_vertex_complete( *
this, 0, 0);
687 Scalar l2 = _smallest*_smallest;
689 for(
unsigned int i=1; i<
points_.size(); ++i)
692 bool vertex_selected =
false;
693 if( vertex_selections_available() && vertex_selection(i))
694 vertex_selected =
true;
702 new_pl.copy_vertex_complete( *
this, i, new_pl.
n_vertices()-1);
711 bool vertex_selected =
false;
712 if( vertex_selections_available() && vertex_selection(
points_.size()-1))
713 vertex_selected =
true;
730 template <
class Po
intT>
736 std::vector<Point> points_old(
points_ );
749 if( vertex_selections_available())
752 #pragma omp parallel for 754 for(
int i=is; i<ie; ++i)
757 if( !vertex_selection(i))
759 points_[i] = (points_old[ (i-1+n)%n ] +
760 points_old[ (i+n )%n ]*2.0 +
761 points_old[ (i+1 )%n ] )*0.25;
768 #pragma omp parallel for 770 for(
int i=is; i<ie; ++i)
773 points_[i] = (points_old[ (i-1+n)%n ] +
774 points_old[ (i+n )%n ] * 2.0 +
775 points_old[ (i+1 )%n ] )*0.25;
784 template <
class Po
intT>
790 std::vector<Point> points_old(
points_ );
803 if( vertex_selections_available())
806 #pragma omp parallel for 808 for(
int i=is; i<ie; ++i)
811 if( !vertex_selection(i))
813 points_[i] -= (points_old[ (i-2+2*n)%n ] +
814 points_old[ (i-1+2*n)%n ]*-4.0 +
815 points_old[ (i )%n ]* 6.0 +
816 points_old[ (i+1 )%n ]*-4.0 +
817 points_old[ (i+2 )%n ] )/(16.0*2.0);
823 #pragma omp parallel for 825 for(
int i=is; i<ie; ++i)
828 points_[i] -= (points_old[ (i-2+2*n)%n ] +
829 points_old[ (i-1+2*n)%n ]*-4.0 +
830 points_old[ (i )%n ]* 6.0 +
831 points_old[ (i+1 )%n ]*-4.0 +
832 points_old[ (i+2 )%n ] )/(16.0*2.0);
841 template <
class Po
intT>
847 std::vector<Point> points_old(
points_ );
860 if( vertex_selections_available())
863 #pragma omp parallel for 865 for(
int i=is; i<ie; ++i)
868 if( !vertex_selection(i))
870 points_[i] = (points_old[ (i-3+3*n)%n ] +
871 points_old[ (i-2+3*n)%n ]*(-6.0) +
872 points_old[ (i-1+3*n)%n ]*15.0 +
873 points_old[ (i ) ]*(44.0) +
874 points_old[ (i+1 )%n ]*15.0 +
875 points_old[ (i+2 )%n ]*(-6.0) +
876 points_old[ (i+3 )%n ] )/64.0;
883 #pragma omp parallel for 885 for(
int i=is; i<ie; ++i)
888 points_[i] = (points_old[ (i-3+3*n)%n ] +
889 points_old[ (i-2+3*n)%n ]*(-6.0) +
890 points_old[ (i-1+3*n)%n ]*15.0 +
891 points_old[ (i ) ]*(44.0) +
892 points_old[ (i+1 )%n ]*15.0 +
893 points_old[ (i+2 )%n ]*(-6.0) +
894 points_old[ (i+3 )%n ] )/64.0;
903 template <
class Po
intT>
906 set_to_circle(
const PointT _center,
const PointT _normal,
double _radius,
unsigned int _n_samples)
912 PointT n = _normal; n.normalize();
916 for(
unsigned int i=0; i<_n_samples; ++i)
918 double alpha = double(i)*2.0*M_PI/double(_n_samples);
920 this->
add_point(_center + u*cos(alpha) + v*sin(alpha));
928 template <
class Po
intT>
929 template <
class MeshT,
class SpatialSearchT>
934 typename MeshT::FaceHandle fh;
937 #pragma omp parallel for 939 for(
unsigned int i=0; i<
points_.size(); ++i)
949 template <
class Po
intT>
950 template <
class MeshT,
class SpatialSearchT>
954 std::vector<SpatialSearchT*>* _ssearch)
956 typename MeshT::FaceHandle fh;
959 #pragma omp parallel for 961 for(
int i=0; i< (int)
points_.size(); ++i)
964 typename MeshT::Scalar d_best = -1;
970 for(
unsigned int j=0; j<_mesh.size(); ++j)
981 if( d_new < d_best || d_best == -1)
997 template <
class Po
intT>
998 template <
class MeshT,
class SpatialSearchT>
999 typename PolyLineT<PointT>::Point
1002 const Point& _point,
1003 typename MeshT::FaceHandle& _fh,
1004 SpatialSearchT * _ssearch,
1007 typename MeshT::Point p0 = (
typename MeshT::Point) _point;
1009 typename MeshT::Point p_best = _mesh.point(_mesh.vertex_handle(0));
1010 typename MeshT::Scalar d_best = (p0 - p_best).sqrnorm();
1012 typename MeshT::FaceHandle fh_best;
1014 if (_ssearch == 0) {
1016 typename MeshT::ConstFaceIter cf_it = _mesh.faces_begin();
1017 typename MeshT::ConstFaceIter cf_end = _mesh.faces_end();
1019 for (; cf_it != cf_end; ++cf_it) {
1020 typename MeshT::ConstFaceVertexIter cfv_it = _mesh.cfv_iter(*cf_it);
1022 const typename MeshT::Point& pt0 = _mesh.point(*cfv_it);
1023 const typename MeshT::Point& pt1 = _mesh.point(*(++cfv_it));
1024 const typename MeshT::Point& pt2 = _mesh.point(*(++cfv_it));
1026 typename MeshT::Point ptn;
1028 typename MeshT::Scalar d = Geometry::distPointTriangleSquared(p0, pt0, pt1, pt2, ptn);
1043 *_dbest = sqrt(d_best);
1045 return (Point) p_best;
1047 typename MeshT::FaceHandle fh = _ssearch->nearest(p0).handle;
1048 typename MeshT::CFVIter fv_it = _mesh.cfv_iter(fh);
1050 const typename MeshT::Point& pt0 = _mesh.point(*fv_it);
1051 const typename MeshT::Point& pt1 = _mesh.point(*(++fv_it));
1052 const typename MeshT::Point& pt2 = _mesh.point(*(++fv_it));
1055 d_best = Geometry::distPointTriangleSquared(p0, pt0, pt1, pt2, p_best);
1062 *_dbest = sqrt(d_best);
1064 return (Point) p_best;
1071 template <
class Po
intT>
1072 template <
class LineNodeT>
1077 typedef typename LineNodeT::value_type Vec3fL;
1083 _line_node =
new LineNodeT(LineNodeT::LineSegmentsMode, 0,
"PolyLine");
1084 _line_node->set_line_width(5.0);
1086 _line_node->set_base_color(
1087 OpenMesh::Vec4f(0.2 +
double(rand()) /
double(RAND_MAX) * 0.8, 0.2 +
double(rand()) /
double(RAND_MAX) * 0.8,
1088 0.2 +
double(rand()) /
double(RAND_MAX) * 0.8, 1.0));
1093 for (
unsigned int i = 0; i < this->
points().size() - 1; ++i) {
1094 _line_node->add_line((Vec3fL) this->
points()[i], (Vec3fL) this->
points()[i + 1]);
1099 if (!this->
points().empty()) {
1100 _line_node->add_point((Vec3fL) this->
points()[0]);
1106 _line_node =
new LineNodeT(LineNodeT::PolygonMode, 0,
"PolyLine");
1107 _line_node->set_line_width(5.0);
1109 _line_node->set_base_color(
1110 OpenMesh::Vec4f(0.2 +
double(rand()) /
double(RAND_MAX) * 0.8, 0.2 +
double(rand()) /
double(RAND_MAX) * 0.8,
1111 0.2 +
double(rand()) /
double(RAND_MAX) * 0.8, 1.0));
1116 for (
unsigned int i = 0; i < this->
points().size(); ++i) {
1117 _line_node->add_point((Vec3fL) this->
points()[i]);
1122 if (!this->
points().empty()) {
1123 _line_node->add_point((Vec3fL) this->
points()[0]);
1134 template <
class Po
intT>
1135 template <
class LineNodeT>
1148 const typename LineNodeT::PointVector& ln_points = _line_node->points();
1150 for (
unsigned int i = 0; i < ln_points.size();) {
1151 if (i != ln_points.size() - 1)
1155 if ((ln_points[ln_points.size() - 1] - ln_points[0]).sqrnorm() == 0) {
1173 const typename LineNodeT::PointVector& ln_points(_line_node->points());
1175 for (
unsigned int i = 0; i < ln_points.size(); ++i) {
1185 template <
class Po
intT>
1190 std::cerr <<
"****** PolyInfo ******\n";
1191 std::cerr <<
"closed : " <<
closed_ << std::endl;
1192 std::cerr <<
"#points: " <<
points_.size() << std::endl;
1193 for(
unsigned int i=0; i<
points_.size(); ++i)
1194 std::cerr <<
points_[i] << std::endl;
1201 template <
class Po
intT>
1202 template <
class PropT>
1220 template <
class Po
intT>
1221 template <
class PropT>
1226 if( _ref_count <= 1)
1238 template <
class Po
intT>
1246 std::cerr <<
"Warning: invalid range in PolyLine::copy_vertex_complete ( " 1247 << _i <<
" " << _j <<
" ) " << std::endl;
1257 if( _pl.vertex_normals_available())
1258 if( vertex_normals_available())
1259 vertex_normal(_j) = _pl.vertex_normal(_i);
1261 if( _pl.vertex_binormals_available())
1262 if( vertex_binormals_available())
1263 vertex_binormal(_j) = _pl.vertex_binormal(_i);
1266 if( _pl.vertex_colors_available())
1267 if( vertex_colors_available())
1268 vertex_color(_j) = _pl.vertex_color(_i);
1271 if( _pl.vertex_scalars_available())
1272 if( vertex_scalars_available())
1273 vertex_scalar(_j) = _pl.vertex_scalar(_i);
1276 if( _pl.vertex_selections_available())
1277 if( vertex_selections_available())
1278 vertex_selection(_j) = _pl.vertex_selection(_i);
1281 if( _pl.vertex_vhandles_available())
1282 if( vertex_vhandles_available())
1283 vertex_vhandle(_j) = _pl.vertex_vhandle(_i);
1286 if( _pl.vertex_ehandles_available())
1287 if( vertex_ehandles_available())
1288 vertex_ehandle(_j) = _pl.vertex_ehandle(_i);
1291 if( _pl.vertex_ehandles_available())
1292 if( vertex_ehandles_available())
1293 vertex_ehandle(_j) = _pl.vertex_ehandle(_i);
1300 template <
class Po
intT>
1308 std::cerr <<
"Warning: invalid range in PolyLine::copy_edge_complete ( " 1309 << _i <<
" " << _j <<
" ) " << std::endl;
1314 if( _pl.edge_selections_available())
1315 if( edge_selections_available())
1316 edge_selection(_j) = _pl.edge_selection(_i);
1320 if( _pl.edge_normals_available())
1321 if( edge_normals_available())
1322 edge_normal(_j) = _pl.edge_normal(_i);
1325 if( _pl.edge_colors_available())
1326 if( edge_colors_available())
1327 edge_color(_j) = _pl.edge_color(_i);
1330 if( _pl.edge_scalars_available())
1331 if( edge_scalars_available())
1332 edge_scalar(_j) = _pl.edge_scalar(_i);
1335 if( _pl.edge_selections_available())
1336 if( edge_selections_available())
1337 edge_selection(_j) = _pl.edge_selection(_i);
1340 if( _pl.edge_selections_available())
1341 if( edge_selections_available())
1342 edge_selection(_j) = _pl.edge_selection(_i);
1349 template <
class Po
intT>
1357 std::cerr <<
"Warning: inversion for closed polylines is not supported!!!\n";
1365 pl_temp.copy_vertex_complete( *
this, n_vertices()-1-i, i);
1368 for(
unsigned int i=0; i<
n_edges(); ++i)
1369 pl_temp.copy_edge_complete( *
this, n_edges()-1-i, i);
1379 template <
class Po
intT>
1388 std::cerr <<
"Warning: appending not supported for closed polylines!!!\n";
1393 unsigned int old_ne =
n_edges();
1397 for(
unsigned int i=0; i<_pl.
n_vertices(); ++i)
1398 copy_vertex_complete( _pl, i, i+old_nv);
1400 for(
unsigned int i=0; i<_pl.
n_edges(); ++i)
1401 copy_edge_complete( _pl, i, i+old_ne+1);
1408 template <
class Po
intT>
1423 template <
class Po
intT>
1430 std::cerr <<
"Warning: split_closed was called for open polyline!\n";
1442 pl_temp.copy_vertex_complete( *
this, (i+_split_idx)%
n_vertices(),i);
1444 for(
unsigned int i=0; i<
n_edges(); ++i)
1445 pl_temp.copy_edge_complete( *
this, (i+_split_idx)%n_edges(),i);
1455 template <
class Po
intT>
1469 for(
unsigned int i=_split_idx; i<
n_vertices(); ++i)
1470 _new_pl.copy_vertex_complete(*
this, i, i-_split_idx);
1472 for(
unsigned int i=_split_idx; i<
n_edges(); ++i)
1473 _new_pl.copy_edge_complete(*
this, i, i-_split_idx);
1484 template <
class Po
intT>
1485 template <
class IPo
int>
1489 const IPoint& _n_plane,
1494 double a = (_n_plane | (_p_plane - _p0));
1495 double b = (_n_plane | (_p1 - _p0));
1497 if (fabs(b) > 1e-9) {
1500 if (s >= 0.0 && s <= 1.0) {
1501 _p_int = _p0 + (_p1 - _p0) * s;
1504 if (fabs((_n_plane | (_p_int - _p_plane))) > 1e-9)
1505 std::cerr <<
"WARNING: wrong intersection point!!!\n";
1518 template <
class Po
intT>
1519 template<
class MeshT>
1525 const typename MeshT::FaceHandle& _fh0,
1526 const typename MeshT::FaceHandle& _fh1,
1527 std::vector<Point> & _points,
1528 std::vector<typename MeshT::EdgeHandle>& _ehandles )
1534 Point p_start = _p0;
1537 typename MeshT::FaceHandle fh_start = _fh0;
1538 typename MeshT::FaceHandle fh_end = _fh1;
1540 if( fh_start == fh_end)
1544 std::vector<Point> new_points0, new_points1;
1547 std::vector<typename MeshT::EdgeHandle> new_eh0, new_eh1;
1555 typename MeshT::HalfedgeHandle heh = _mesh.halfedge_handle(fh_start);
1556 Point p0 = (Point)_mesh.point(_mesh.to_vertex_handle( heh ));
1557 Point p1 = (Point)_mesh.point(_mesh.to_vertex_handle( heh = _mesh.next_halfedge_handle(heh) ));
1558 Point p2 = (Point)_mesh.point(_mesh.to_vertex_handle( heh = _mesh.next_halfedge_handle(heh) ));
1559 Point n_start = ((p1-p0)%(p2-p0)).normalize();
1562 heh = _mesh.halfedge_handle(fh_end);
1563 p0 = _mesh.point(_mesh.to_vertex_handle( heh ));
1564 p1 = _mesh.point(_mesh.to_vertex_handle( heh = _mesh.next_halfedge_handle(heh) ));
1565 p2 = _mesh.point(_mesh.to_vertex_handle( heh = _mesh.next_halfedge_handle(heh) ));
1566 Point n_end = ((p1-p0)%(p2-p0)).normalize();
1569 Point n_avg = n_start + n_end;
1570 if( n_avg.sqrnorm() < 1e-7) n_avg = n_start - n_end;
1574 Point n_plane = n_avg % (p_start-p_end).normalize();
1575 if( n_plane.sqrnorm() > 1e-9) n_plane.normalize();
1576 else std::cerr <<
"WARNING: Edge Resampling -> not possible to construct stable cut plane!!!\n";
1577 Point p_plane = (p_start + p_end)*0.5;
1580 std::vector<typename MeshT::HalfedgeHandle > start_hehs;
1581 std::vector<Point> start_ps;
1582 heh = _mesh.halfedge_handle(fh_start);
1584 for(
unsigned int i=0; i<3; ++i)
1587 p0 = (Point) _mesh.point(_mesh.from_vertex_handle(heh));
1588 p1 = (Point) _mesh.point(_mesh.to_vertex_handle (heh));
1593 start_hehs.push_back( heh );
1594 start_ps.push_back(p_int);
1597 heh = _mesh.next_halfedge_handle(heh);
1602 std::vector<typename MeshT::HalfedgeHandle > end_hehs;
1603 std::vector<Point> end_ps;
1604 heh = _mesh.halfedge_handle(fh_end);
1605 for(
unsigned int i=0; i<3; ++i)
1608 p0 = (Point) _mesh.point(_mesh.from_vertex_handle(heh));
1609 p1 = (Point) _mesh.point(_mesh.to_vertex_handle (heh));
1614 end_hehs.push_back( heh );
1615 end_ps.push_back(p_int);
1618 heh = _mesh.next_halfedge_handle(heh);
1623 if( start_hehs.size() != 2 || end_hehs.size() != 2)
1625 std::cerr <<
"PolyLineResampling ERROR: wrong number of intersections... ";
1626 std::cerr << start_hehs.size() <<
" ";
1627 std::cerr << end_hehs.size() << std::endl;
1633 if( start_hehs.size() == 2 && end_hehs.size() == 2)
1636 typename MeshT::HalfedgeHandle cur_heh0 = start_hehs[0];
1637 typename MeshT::HalfedgeHandle cur_heh1 = start_hehs[1];
1640 new_points0.push_back( start_ps[0]);
1641 new_eh0.push_back( _mesh.edge_handle( cur_heh0));
1643 new_points1.push_back( start_ps[1]);
1644 new_eh1.push_back( _mesh.edge_handle( cur_heh1));
1646 unsigned int count = 0;
1648 while( _mesh.face_handle(_mesh.opposite_halfedge_handle(cur_heh0)) != fh_end &&
1649 _mesh.face_handle(_mesh.opposite_halfedge_handle(cur_heh1)) != fh_end &&
1655 cur_heh0 = _mesh.opposite_halfedge_handle( cur_heh0);
1658 if( _mesh.is_boundary(cur_heh0))
1660 std::cerr <<
"ERROR: found boundary in traversal!!!\n";
1661 cur_heh0 = _mesh.opposite_halfedge_handle( cur_heh0);
1664 unsigned int old_size = new_points0.size();
1666 for(
unsigned int i=0; i<2; ++i)
1669 cur_heh0 = _mesh.next_halfedge_handle(cur_heh0);
1672 p0 = (Point) _mesh.point(_mesh.from_vertex_handle(cur_heh0));
1673 p1 = (Point) _mesh.point(_mesh.to_vertex_handle (cur_heh0));
1678 new_points0.push_back(p_int);
1679 new_eh0.push_back( _mesh.edge_handle( cur_heh0));
1685 if( new_points0.size() != old_size + 1)
1686 std::cerr <<
"WARNING: could not find new point!!!\n";
1690 cur_heh1 = _mesh.opposite_halfedge_handle( cur_heh1);
1693 if( _mesh.is_boundary(cur_heh1))
1695 std::cerr <<
"ERROR: found boundary in traversal!!!\n";
1696 cur_heh1 = _mesh.opposite_halfedge_handle( cur_heh1);
1699 unsigned int old_size = new_points1.size();
1701 for(
unsigned int i=0; i<2; ++i)
1704 cur_heh1 = _mesh.next_halfedge_handle(cur_heh1);
1707 p0 = (Point) _mesh.point(_mesh.from_vertex_handle(cur_heh1));
1708 p1 = (Point) _mesh.point(_mesh.to_vertex_handle (cur_heh1));
1713 new_points1.push_back(p_int);
1714 new_eh1.push_back( _mesh.edge_handle( cur_heh1));
1720 if( new_points1.size() != old_size + 1)
1721 std::cerr <<
"WARNING: could not find new point!!!\n";
1731 if(_mesh.face_handle(_mesh.opposite_halfedge_handle(cur_heh0)) == fh_end )
1734 _points = new_points0;
1735 _ehandles = new_eh0;
1738 if (_mesh.face_handle(_mesh.opposite_halfedge_handle(cur_heh1)) == fh_end)
1741 _points = new_points1;
1742 _ehandles = new_eh1;
1751 template <
class Po
intT>
1762 if( (
point(i) -
point(i_next)).norm() < _epsilon)
1764 if( vertex_ehandles_available())
1766 if( !_keep_edge_vertices || vertex_ehandle(i_next) == -1)
1772 if( vertex_ehandle(i) == -1)
1792 if( (
point(i) -
point(i_next)).norm() < _epsilon)
1794 if( vertex_ehandles_available())
1796 if( !_keep_edge_vertices || vertex_ehandle(i_next) == -1)
1806 if( vertex_ehandle(i) == -1)
1833 template <
class Po
intT>
1834 typename PolyLineT<PointT>::Scalar
1841 if (!edge_normals_available() || !
is_closed()) {
1842 std::cerr <<
"Warning: PolyLineT::total_gaussian_curvature requires a closed loop and edge normals!!!\n";
1846 for (
unsigned int i = 0; i <
n_edges(); ++i) {
1849 Point n0 = edge_normal(i);
1851 Point n1 = edge_normal((i + 1) %
n_edges());
1854 if (e0.norm() > 1e-8)
1857 std::cerr <<
"Warning: e0 is undefined...\n";
1860 if (e1.norm() > 1e-8)
1863 std::cerr <<
"Warning: e1 is undefined...\n";
1868 if (n0.norm() > 1e-4)
1871 std::cerr <<
"Warning: n0 is undefined...\n";
1874 if (n1.norm() > 1e-4)
1877 std::cerr <<
"Warning: n1 is undefined...\n";
1886 if (b0.norm() > 1e-8)
1889 std::cerr <<
"Warning: b0 is undefined...\n";
1901 if (d.norm() < 1e-3)
1907 double dp = (-e0 | d);
1908 dp = std::max(-1.0, dp);
1909 dp = std::min(1.0, dp);
1912 double boundary_angle = acos(dp);
1915 dp = std::max(-1.0, dp);
1916 dp = std::min(1.0, dp);
1919 boundary_angle += acos(dp);
1921 gcurv += M_PI - boundary_angle;
1925 return (2.0 * M_PI - gcurv);
1928 template <
class Po
intT>
1929 template <
class MeshT>
1933 MeshT> &component) {
1935 const MeshT &mesh = component.getMesh();
1937 for (
typename MeshT::ConstFaceIter
1938 f_it = mesh.faces_begin(), f_end = mesh.faces_end();
1939 f_it != f_end; ++f_it) {
1940 component[*f_it] = 0;
1943 unsigned int current_component = 0;
1944 for (
typename MeshT::ConstFaceIter f_it = mesh.faces_begin(),
1945 f_end = mesh.faces_end(); f_it != f_end; ++f_it) {
1947 if (component[*f_it] != 0)
1950 ++current_component;
1955 std::stack<typename MeshT::FaceHandle> dfs;
1958 while (!dfs.empty()) {
1959 const typename MeshT::FaceHandle fh = dfs.top(); dfs.pop();
1961 component[fh] = current_component;
1967 for (
typename MeshT::CFFIter ff_it = mesh.cff_begin(fh),
1968 ff_end = mesh.cff_end(fh); ff_it != ff_end; ++ff_it) {
1970 if (component[*ff_it] == 0)
1975 std::cout <<
"\x1b[33mmark_components: Mesh has " << current_component
1976 <<
" components.\x1b[0m" << std::endl;
1980 template <
class Po
intT>
1981 template<
class MeshT,
class SpatialSearchT>
1987 SpatialSearchT &_ssearch) {
1989 typename MeshT::FaceHandle fh;
1994 return component[fh];
1997 template <
class Po
intT>
1998 template <
class MeshT,
class SpatialSearchT>
2001 SpatialSearchT &_ssearch) {
2003 if (
points_.empty())
return false;
2007 "component.on_multiple_components.objecttypes.polyline" 2008 ".i8.informatik.rwth-aachen.de");
2013 const unsigned int first_component =
2016 for (
typename std::vector<PointT>::iterator pt_it = ++
points_.begin(),
2017 pt_end =
points_.end(); pt_it != pt_end; ++pt_it) {
2019 if (first_component !=
component_of(component, *pt_it, _ssearch))
2026 template <
class Po
intT>
2027 template <
class MeshT,
class SpatialSearchT>
2030 SpatialSearchT &_ssearch,
2031 std::vector<PolyLineT> &out_polylines) {
2033 if (
points_.size() < 2)
return;
2037 "component.split_into_one_per_component.objecttypes.polyline" 2038 ".i8.informatik.rwth-aachen.de");
2044 unsigned int current_component =
2047 for (
typename std::vector<PointT>::iterator pt_it = ++
points_.begin(),
2048 pt_end =
points_.end(); pt_it != pt_end; ++pt_it) {
2054 const unsigned int next_comp =
component_of(component, *pt_it, _ssearch);
2055 if (next_comp == current_component) {
2065 PointT p0 = current_polyLine.
back();
2066 const PointT p1 = *pt_it;
2067 unsigned int comp = next_comp;
2070 const double dist = (p0 - p1).norm();
2072 double firstOut = 1;
2077 static const double EPSILON = 1e-12;
2078 while ((firstOut - lastIn) * dist > EPSILON) {
2079 const double new_pos = .5 * (lastIn + firstOut);
2080 const PointT new_pt = p0 * (1.0 - new_pos) + p1 * new_pos;
2081 const unsigned int new_comp =
2084 if (new_comp == current_component) {
2093 current_polyLine.
add_point(p0 * (1.0 - lastIn) + p1 * lastIn);
2095 out_polylines.push_back(current_polyLine);
2096 current_polyLine.
clear();
2097 current_polyLine.
add_point(p0 * (1.0 - firstOut) + p1 * firstOut);
2098 current_component = comp;
2101 p0 = p0 * (1.0 - firstOut) + p1 * firstOut;
2102 }
while (comp != next_comp);
2104 if (current_polyLine.
back() != *pt_it)
2109 out_polylines.push_back(current_polyLine);
2112 if(out_polylines.size() <= 1)
2114 out_polylines.clear();
2115 out_polylines.push_back(*
this);
2119 template <
class Po
intT>
2121 size_t n = cprop_enum.size();
2122 for (
int i = 0; i < n; ++i)
2123 if (cprop_enum[i] == _prop)
2128 template <
class Po
intT>
2130 return (_handle >= 0 && _handle <
int(get_num_custom_properties()) ? cprop_enum[_handle] : NULL);
2133 template <
class Po
intT>
2135 return (_handle >= 0 && _handle <
int(get_num_custom_properties()) ? cprop_enum[_handle] : NULL);
2138 template <
class Po
intT>
2141 unsigned int _prop_size) {
2143 CustomPropertyHandle h = get_custom_property_handle(_name);
2151 pcontainer->name = _name;
2152 pcontainer->ref_count = 1;
2153 pcontainer->prop_size = _prop_size;
2155 pcontainer->datatype = 0;
2157 pcontainer->prop_data.resize(
n_vertices() * _prop_size, 0);
2159 custom_properties[_name] = pcontainer;
2161 cprop_enum.push_back(pcontainer);
2164 if (++pcontainer->ref_count < 1)
2165 pcontainer->ref_count = 1;
2168 return custom_prop_handle(pcontainer);
2171 template <
class Po
intT>
2177 if (p && --(p->ref_count) <= 0)
2178 p->prop_data.clear();
2181 template <
class Po
intT>
2185 CustomPropertyHandle h = get_custom_property_handle(_name);
2186 release_custom_property(h);
2189 template <
class Po
intT>
2193 typename CustomPropertyMap::const_iterator it = custom_properties.find(_name);
2195 if (it == custom_properties.end())
2198 return custom_prop_handle(it->second);
2201 template <
class Po
intT>
2210 std::cerr <<
"PolyLineT::get_custom_property_name - invalid handle" << std::endl;
2216 template <
class Po
intT>
2220 const void* _data) {
2223 std::cerr <<
"PolyLineT::set_custom_property - invalid data" << std::endl;
2230 unsigned int offset = p->prop_size * _i;
2233 if (offset + p->prop_size > p->prop_data.size()) {
2234 std::cerr <<
"PolyLineT::set_custom_property - out of range access" << std::endl;
2240 memcpy(p->buffer() + offset, _data, p->prop_size);
2243 std::cerr <<
"PolyLineT::set_custom_property - invalid handle" << std::endl;
2246 template <
class Po
intT>
2250 const void* _data) {
2252 CustomPropertyHandle h = get_custom_property_handle(_name);
2253 set_custom_property(h, _i, _data);
2256 template <
class Po
intT>
2263 std::cerr <<
"PolyLineT::get_custom_property - invalid destination address" << std::endl;
2271 unsigned int offset = p->prop_size * _i;
2274 if (offset + p->prop_size > p->prop_data.size()) {
2275 std::cerr <<
"PolyLineT::get_custom_property - out of range access" << std::endl;
2280 memcpy(_dst, p->buffer() + offset, p->prop_size);
2283 std::cerr <<
"PolyLineT::get_custom_property - invalid handle" << std::endl;
2286 template <
class Po
intT>
2290 void* _data)
const {
2292 CustomPropertyHandle h = get_custom_property_handle(_name);
2293 get_custom_property(h, _i, _data);
2297 template <
class Po
intT>
2304 return p->ref_count > 0;
2310 template <
class Po
intT>
2314 CustomPropertyHandle h = get_custom_property_handle(_name);
2315 return custom_property_available(h);
2319 template <
class Po
intT>
2327 p->datatype = _datatype;
2328 p->shader_binding = _shader_input_name;
2331 std::cerr <<
"PolyLineT::bind_custom_property_to_shader - invalid handle" << std::endl;
2335 template <
class Po
intT>
2344 *_propsize = p->prop_size;
2347 *_input_name = p->shader_binding.c_str();
2350 *_datatype = p->datatype;
2352 return !p->shader_binding.empty() && p->datatype;
2355 std::cerr <<
"PolyLineT::get_custom_property_shader_binding - invalid handle" << std::endl;
2360 template <
class Po
intT>
2369 std::cerr <<
"PolyLineT::get_custom_property_buffer - invalid handle" << std::endl;
2374 template <
class Po
intT>
2377 return custom_properties.size();
2380 template <
class Po
intT>
2384 if (_i < get_num_custom_properties())
2385 return CustomPropertyHandle(_i);
std::vector< Point > points_
List of points in the polyline.
void split_closed(unsigned int _split_idx)
Split closed polyline at vertex with index _split_idx.
void print() const
Print information string to cerr.
Point & back()
Get last point of the polyline ( no range check!!!)
void collapse(Scalar _smallest)
Collapse polyline.
void resize(unsigned int _n)
Resize current polyline.
void smooth_uniform_laplace()
Laplacian smoothing.
std::vector< Point > & points()
Get all points of the polyline.
Namespace providing different geometric functions concerning angles.
void add_point(const Point &_p)
Append a point to the polyline.
void resample_arclength_uniform(const unsigned int _n)
Perform an uniform arclength resampling while maintaining the start and end point.
void append(const PolyLineT< PointT > &_pl)
Append second polyline _pl to this one.
void split(unsigned int _split_idx, PolyLineT< PointT > &_new_pl)
Split closed polyline at vertex with index _split_idx.
Point find_nearest_point(const MeshT &_mesh, const Point &_point, typename MeshT::FaceHandle &_fh, SpatialSearchT *_ssearch=0, double *_dbest=0)
void smooth_uniform_laplace2()
Squared laplacian smoothing.
void smooth_uniform_laplace3()
Cubic laplacian smoothing.
PolyLineT(bool _closed=false)
Constructor.
Scalar length() const
Compute the length of the polyline (in future cached method)
bool on_multiple_components(MeshT &_mesh, SpatialSearchT &_ssearch)
Point edge_vector(unsigned int _i) const
get the i-th oriented edge vector
void subdivide(Scalar _largest)
Subdivide polyline.
bool plane_line_intersection(const IPoint &_p_plane, const IPoint &_n_plane, const IPoint &_p0, const IPoint &_p1, IPoint &_p_int)
void insert_point(int _idx, const Point &_p)
insert _p at _idx into polyline
void set_to_circle(const PointT _center, const PointT _normal, double _radius, unsigned int _n_samples=100)
creating a circle with center _center and radius _radius lying in tangent plane specified by _normal ...
Point position_arclength(const Scalar _t) const
Same as position but with an arclength parameterization in [0,length()].
void bind_custom_property_to_shader(CustomPropertyHandle _property_handle, const std::string &_shader_input_name, unsigned int _datatype)
Binding to vertex shader (optional)
Point & front()
Get first point of the polyline ( no range check!!!)
Point & point(unsigned int _i)
Get a point of the polyline.
Point position(const Scalar _t) const
Provide linear paremterization of the polyline in [0,1].
void split_into_one_per_component(MeshT &_mesh, SpatialSearchT &_ssearch, std::vector< PolyLineT > &out_polylines)
void delete_point(int _idx)
Delete point at _idx.
void invert()
Invert polyline that first vertex becomes last.
bool get_custom_property_shader_binding(CustomPropertyHandle _property_handle, unsigned int *_propsize, const char **_input_name, unsigned int *_datatype) const
Get shader binding information.
size_t n_vertices() const
Get number of vertices.
void set_line_node(LineNodeT *&_line_node, int _mode=0)
Takes a line node and sets the points of this polyline to the points of the node. ...
bool closed_
Connect first and last point?
void set_closed(const bool _c)
Set if the polyline should be closed and therefore forms a loop.
void mark_components(OpenMesh::PropertyManager< OpenMesh::FPropHandleT< unsigned int >, MeshT > &component)
void clear()
Clear the current polyline.
bool is_closed() const
Check if the polyline is marked as closed.
size_t n_edges() const
Get number of edges.
void project_to_mesh(const MeshT &_mesh, SpatialSearchT *_ssearch=0)
Project polyline points to nearest surface points (use spatial search!!!)
void remove_subsequent_identical_points(const bool _keep_edge_vertices=false, const double _epsilon=1e-6)
remove points which are subsequent and lie at the same position
void prepend(const PolyLineT< PointT > &_pl)
Prepend second polyline _pl to polyline.
Scalar total_gaussian_curvature()
compute total gaussian curvature of enclosed surface (via Gauss-Bonnet)
LineNodeT * get_line_node(LineNodeT *&_line_node, int _mode=0)
Conversion PolyLine <-> LineNode.
VectorT< Scalar, 3 > perpendicular(const VectorT< Scalar, 3 > &v)
find a vector that's perpendicular to _v
unsigned int component_of(const OpenMesh::PropertyManager< OpenMesh::FPropHandleT< unsigned int >, MeshT > &component, const PointT &pt, SpatialSearchT &_ssearch)