58 #define ACG_POLYLINET_C 62 #include <OpenMesh/Core/Geometry/VectorT.hh> 69 #include "PolyLineT.hh" 72 #include <ACG/Geometry/Algorithms.hh> 73 #include <ACG/Utils/VSToolsT.hh> 95 template <
class Po
intT>
101 ref_count_vnormals_(0),
102 ref_count_vbinormals_(0),
103 ref_count_vcolors_(0),
104 ref_count_vscalars_(0),
105 ref_count_vselections_(0),
106 ref_count_vvhandles_(0),
107 ref_count_vehandles_(0),
108 ref_count_vfhandles_(0),
109 ref_count_enormals_(0),
110 ref_count_ecolors_(0),
111 ref_count_escalars_(0),
112 ref_count_eselections_(0),
113 ref_count_epreimage_direction_(0)
120 template <
class Po
intT>
130 vnormals_ = _line.vnormals_;
131 vbinormals_ = _line.vbinormals_;
132 vcolors_ = _line.vcolors_;
133 vscalars_ = _line.vscalars_;
134 vselections_ = _line.vselections_;
135 vvhandles_ = _line.vvhandles_;
136 vehandles_ = _line.vehandles_;
137 vfhandles_ = _line.vfhandles_;
140 enormals_ = _line.enormals_;
141 ecolors_ = _line.ecolors_;
142 escalars_ = _line.escalars_;
143 eselections_ = _line.eselections_;
144 epreimage_direction_ = _line.epreimage_direction_;
147 ref_count_vnormals_ = _line.ref_count_vnormals_;
148 ref_count_vbinormals_ = _line.ref_count_vbinormals_;
149 ref_count_vcolors_ = _line.ref_count_vcolors_;
150 ref_count_vscalars_ = _line.ref_count_vscalars_;
151 ref_count_vselections_ = _line.ref_count_vselections_;
152 ref_count_vvhandles_ = _line.ref_count_vvhandles_;
153 ref_count_vehandles_ = _line.ref_count_vehandles_;
154 ref_count_vfhandles_ = _line.ref_count_vfhandles_;
156 ref_count_enormals_ = _line.ref_count_enormals_;
157 ref_count_ecolors_ = _line.ref_count_ecolors_;
158 ref_count_escalars_ = _line.ref_count_escalars_;
159 ref_count_eselections_ = _line.ref_count_eselections_;
160 ref_count_epreimage_direction_ = _line.ref_count_epreimage_direction_;
164 for (
typename CustomPropertyMap::const_iterator it = _line.custom_properties.begin(); it != _line.custom_properties.end(); ++it) {
169 dst->name = src->name;
170 dst->ref_count = src->ref_count;
171 dst->prop_size = src->prop_size;
172 dst->prop_data = src->prop_data;
174 dst->datatype = src->datatype;
175 dst->shader_binding = src->shader_binding;
177 custom_properties[it->first] = dst;
184 template <
class Po
intT>
196 vselections_.clear();
204 eselections_.clear();
205 epreimage_direction_.clear();
207 for (
typename CustomPropertyMap::iterator it = custom_properties.begin(); it != custom_properties.end(); ++it)
209 custom_properties.clear();
214 template <
class Po
intT>
228 template <
class Po
intT>
239 if( vertex_normals_available() )
240 vnormals_.resize( _n);
241 if( vertex_binormals_available() )
242 vbinormals_.resize( _n);
243 if( vertex_colors_available())
244 vcolors_.resize( _n);
245 if( vertex_scalars_available())
246 vscalars_.resize( _n);
247 if( vertex_selections_available())
248 vselections_.resize( _n);
249 if( vertex_vhandles_available())
250 vvhandles_.resize( _n);
251 if( vertex_ehandles_available())
252 vehandles_.resize( _n);
253 if( vertex_fhandles_available())
254 vfhandles_.resize( _n);
256 if( edge_normals_available())
257 enormals_.resize( _n);
258 if( edge_colors_available())
259 ecolors_.resize( _n);
260 if( edge_scalars_available())
261 escalars_.resize( _n);
262 if( edge_preimage_directions_available())
263 epreimage_direction_.resize( _n);
266 for (
typename CustomPropertyMap::iterator it = custom_properties.begin(); it != custom_properties.end(); ++it) {
270 p->prop_data.resize(p->prop_size * _n);
285 template <
class Po
intT>
294 if( vertex_normals_available() )
295 vnormals_.push_back( Point(0,0,0));
297 if( vertex_binormals_available() )
298 vbinormals_.push_back( Point(0,0,0));
300 if( vertex_colors_available())
301 vcolors_.push_back( Point(1,0,1));
303 if( vertex_scalars_available())
304 vscalars_.push_back( 0.0 );
306 if( vertex_selections_available())
307 vselections_.push_back(
false);
309 if( vertex_vhandles_available())
310 vvhandles_.push_back(-1);
312 if( vertex_ehandles_available())
313 vehandles_.push_back(-1);
315 if( vertex_fhandles_available())
316 vfhandles_.push_back(-1);
318 if( edge_normals_available())
319 enormals_.push_back( Point(0,0,0));
321 if( edge_colors_available())
322 ecolors_.push_back( Point(1,0,1));
324 if( edge_scalars_available())
325 escalars_.push_back( 0.0);
327 if( edge_selections_available())
328 eselections_.push_back(
false);
330 if( edge_preimage_directions_available())
331 epreimage_direction_.push_back(Point(0,0,0));
334 for (
typename CustomPropertyMap::iterator it = custom_properties.begin(); it != custom_properties.end(); ++it) {
338 size_t cur_size = p->prop_data.size();
340 p->prop_data.resize(cur_size + p->prop_size);
343 memset(p->buffer() + cur_size, 0, p->prop_size);
349 template <
class Po
intT>
360 if( vertex_normals_available() )
361 vnormals_.insert(vnormals_.begin()+_idx, Point(0,0,0));
363 if( vertex_binormals_available() )
364 vbinormals_.insert(vbinormals_.begin()+_idx, Point(0,0,0));
366 if( vertex_colors_available())
367 vcolors_.insert(vcolors_.begin()+_idx, Point(1,0,1));
369 if( vertex_scalars_available())
370 vscalars_.insert(vscalars_.begin()+_idx, 0.0 );
372 if( vertex_selections_available())
373 vselections_.insert(vselections_.begin()+_idx,
false);
375 if( vertex_vhandles_available())
376 vvhandles_.insert(vvhandles_.begin()+_idx, -1);
378 if( vertex_ehandles_available())
379 vehandles_.insert(vehandles_.begin()+_idx, -1);
381 if( vertex_fhandles_available())
382 vfhandles_.insert(vfhandles_.begin()+_idx, -1);
384 if( edge_normals_available())
385 enormals_.insert(enormals_.begin()+_idx, Point(0,0,0));
387 if( edge_colors_available())
388 ecolors_.insert(ecolors_.begin()+_idx, Point(1,0,1));
390 if( edge_scalars_available())
391 escalars_.insert(escalars_.begin()+_idx, 0.0);
393 if( edge_selections_available())
394 eselections_.insert(eselections_.begin()+_idx,
false);
396 if( edge_preimage_directions_available())
397 epreimage_direction_.insert(epreimage_direction_.begin()+_idx, Point(0,0,0));
400 for (
typename CustomPropertyMap::iterator it = custom_properties.begin(); it != custom_properties.end(); ++it) {
403 unsigned int offset = p->prop_size * _idx;
405 for (
unsigned int i = 0; i < p->prop_size; ++i)
406 p->prop_data.insert(p->prop_data.begin() + offset, 0);
414 template <
class Po
intT>
426 if( vertex_normals_available() )
427 vnormals_.erase(vnormals_.begin()+_idx);
429 if( vertex_binormals_available() )
430 vbinormals_.erase(vbinormals_.begin()+_idx);
432 if( vertex_colors_available())
433 vcolors_.erase(vcolors_.begin()+_idx);
435 if( vertex_scalars_available())
436 vscalars_.erase(vscalars_.begin()+_idx);
438 if( vertex_selections_available())
439 vselections_.erase(vselections_.begin()+_idx);
441 if( vertex_vhandles_available())
442 vvhandles_.erase(vvhandles_.begin()+_idx);
444 if( vertex_ehandles_available())
445 vehandles_.erase(vehandles_.begin()+_idx);
447 if( vertex_fhandles_available())
448 vfhandles_.erase(vfhandles_.begin()+_idx);
450 if( edge_normals_available())
451 enormals_.erase(enormals_.begin()+_idx);
453 if( edge_colors_available())
454 ecolors_.erase(ecolors_.begin()+_idx);
456 if( edge_scalars_available())
457 escalars_.erase(escalars_.begin()+_idx);
459 if( edge_selections_available())
460 eselections_.erase(eselections_.begin()+_idx);
462 if( edge_preimage_directions_available())
463 epreimage_direction_.erase(epreimage_direction_.begin()+_idx);
467 for (
typename CustomPropertyMap::iterator it = custom_properties.begin(); it != custom_properties.end(); ++it) {
470 unsigned int offset = p->prop_size * _idx;
472 for (
unsigned int i = 0; i < p->prop_size; ++i)
473 p->prop_data.erase(p->prop_data.begin() + offset);
481 template <
class Po
intT>
482 typename PolyLineT<PointT>::Scalar
488 unsigned int n =
points_.size();
492 for(
unsigned int i=0; i<n-1; ++i)
499 for(
unsigned int i=0; i<n; ++i)
512 template <
class Po
intT>
513 typename PolyLineT<PointT>::Point
517 assert(_t >=0.0 && _t<=1.0);
525 template <
class Po
intT>
526 typename PolyLineT<PointT>::Point
534 return this->
front();
537 std::cerr <<
"Warning: called position_arclength on emptu PolyLine!!!" << std::endl;
544 return this->
front();
547 unsigned int ne = this->
n_edges();
551 for(
unsigned int i=0; i<ne; ++i)
555 if(l <= _t && _t <= (l+dl))
557 Scalar tl = (_t-l)/dl;
558 if(!std::isfinite(tl))
570 return this->
front();
577 template <
class Po
intT>
582 unsigned int n = std::max((
unsigned int)(2),_n);
583 Scalar l = this->
length();
589 new_pl.copy_vertex_complete(*
this, 0, 0);
593 Scalar s = l/Scalar(n-1);
594 for(
unsigned int i=1; i<n-1; ++i)
599 Scalar s = l/Scalar(n);
600 for(
unsigned int i=1; i<n; ++i)
606 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));
616 template <
class Po
intT>
625 unsigned int n_subdivisions = 1;
627 while (n_subdivisions != 0) {
634 new_pl.copy_vertex_complete(*
this, 0, 0);
637 Scalar l2 = _largest * _largest;
639 for (
unsigned int i = 1; i <
points_.size(); ++i) {
649 new_pl.copy_vertex_complete(*
this, i, new_pl.
n_vertices() - 1);
669 template <
class Po
intT>
677 unsigned int n_collapses = 1;
679 unsigned int n_iter = 0;
681 while( n_collapses != 0 && n_iter < 5)
689 new_pl.copy_vertex_complete( *
this, 0, 0);
692 Scalar l2 = _smallest*_smallest;
694 for(
unsigned int i=1; i<
points_.size(); ++i)
697 bool vertex_selected =
false;
698 if( vertex_selections_available() && vertex_selection(i))
699 vertex_selected =
true;
707 new_pl.copy_vertex_complete( *
this, i, new_pl.
n_vertices()-1);
716 bool vertex_selected =
false;
717 if( vertex_selections_available() && vertex_selection(
points_.size()-1))
718 vertex_selected =
true;
735 template <
class Po
intT>
741 std::vector<Point> points_old(
points_ );
754 if( vertex_selections_available())
757 #pragma omp parallel for 759 for(
int i=is; i<ie; ++i)
762 if( !vertex_selection(i))
764 points_[i] = (points_old[ (i-1+n)%n ] +
765 points_old[ (i+n )%n ]*2.0 +
766 points_old[ (i+1 )%n ] )*0.25;
773 #pragma omp parallel for 775 for(
int i=is; i<ie; ++i)
778 points_[i] = (points_old[ (i-1+n)%n ] +
779 points_old[ (i+n )%n ] * 2.0 +
780 points_old[ (i+1 )%n ] )*0.25;
789 template <
class Po
intT>
795 std::vector<Point> points_old(
points_ );
808 if( vertex_selections_available())
811 #pragma omp parallel for 813 for(
int i=is; i<ie; ++i)
816 if( !vertex_selection(i))
818 points_[i] -= (points_old[ (i-2+2*n)%n ] +
819 points_old[ (i-1+2*n)%n ]*-4.0 +
820 points_old[ (i )%n ]* 6.0 +
821 points_old[ (i+1 )%n ]*-4.0 +
822 points_old[ (i+2 )%n ] )/(16.0*2.0);
828 #pragma omp parallel for 830 for(
int i=is; i<ie; ++i)
833 points_[i] -= (points_old[ (i-2+2*n)%n ] +
834 points_old[ (i-1+2*n)%n ]*-4.0 +
835 points_old[ (i )%n ]* 6.0 +
836 points_old[ (i+1 )%n ]*-4.0 +
837 points_old[ (i+2 )%n ] )/(16.0*2.0);
846 template <
class Po
intT>
852 std::vector<Point> points_old(
points_ );
865 if( vertex_selections_available())
868 #pragma omp parallel for 870 for(
int i=is; i<ie; ++i)
873 if( !vertex_selection(i))
875 points_[i] = (points_old[ (i-3+3*n)%n ] +
876 points_old[ (i-2+3*n)%n ]*(-6.0) +
877 points_old[ (i-1+3*n)%n ]*15.0 +
878 points_old[ (i ) ]*(44.0) +
879 points_old[ (i+1 )%n ]*15.0 +
880 points_old[ (i+2 )%n ]*(-6.0) +
881 points_old[ (i+3 )%n ] )/64.0;
888 #pragma omp parallel for 890 for(
int i=is; i<ie; ++i)
893 points_[i] = (points_old[ (i-3+3*n)%n ] +
894 points_old[ (i-2+3*n)%n ]*(-6.0) +
895 points_old[ (i-1+3*n)%n ]*15.0 +
896 points_old[ (i ) ]*(44.0) +
897 points_old[ (i+1 )%n ]*15.0 +
898 points_old[ (i+2 )%n ]*(-6.0) +
899 points_old[ (i+3 )%n ] )/64.0;
908 template <
class Po
intT>
911 set_to_circle(
const PointT _center,
const PointT _normal,
double _radius,
unsigned int _n_samples)
917 PointT n = _normal; n.normalize();
921 for(
unsigned int i=0; i<_n_samples; ++i)
923 double alpha = double(i)*2.0*M_PI/double(_n_samples);
925 this->
add_point(_center + u*cos(alpha) + v*sin(alpha));
933 template <
class Po
intT>
934 template <
class MeshT,
class SpatialSearchT>
939 typename MeshT::FaceHandle fh;
942 #pragma omp parallel for 944 for(
unsigned int i=0; i<
points_.size(); ++i)
954 template <
class Po
intT>
955 template <
class MeshT,
class SpatialSearchT>
959 std::vector<SpatialSearchT*>* _ssearch)
961 typename MeshT::FaceHandle fh;
964 #pragma omp parallel for 966 for(
int i=0; i< (int)
points_.size(); ++i)
969 typename MeshT::Scalar d_best = -1;
975 for(
unsigned int j=0; j<_mesh.size(); ++j)
986 if( d_new < d_best || d_best == -1)
1002 template <
class Po
intT>
1003 template <
class MeshT,
class SpatialSearchT>
1004 typename PolyLineT<PointT>::Point
1007 const Point& _point,
1008 typename MeshT::FaceHandle& _fh,
1009 SpatialSearchT * _ssearch,
1012 typename MeshT::Point p0 = (
typename MeshT::Point) _point;
1014 typename MeshT::Point p_best = _mesh.point(_mesh.vertex_handle(0));
1015 typename MeshT::Scalar d_best = (p0 - p_best).sqrnorm();
1017 typename MeshT::FaceHandle fh_best;
1019 if (_ssearch == 0) {
1021 typename MeshT::ConstFaceIter cf_it = _mesh.faces_begin();
1022 typename MeshT::ConstFaceIter cf_end = _mesh.faces_end();
1024 for (; cf_it != cf_end; ++cf_it) {
1025 typename MeshT::ConstFaceVertexIter cfv_it = _mesh.cfv_iter(*cf_it);
1027 const typename MeshT::Point& pt0 = _mesh.point(*cfv_it);
1028 const typename MeshT::Point& pt1 = _mesh.point(*(++cfv_it));
1029 const typename MeshT::Point& pt2 = _mesh.point(*(++cfv_it));
1031 typename MeshT::Point ptn;
1033 typename MeshT::Scalar d = Geometry::distPointTriangleSquared(p0, pt0, pt1, pt2, ptn);
1048 *_dbest = sqrt(d_best);
1050 return (Point) p_best;
1052 typename MeshT::FaceHandle fh = _ssearch->nearest(p0).handle;
1053 typename MeshT::CFVIter fv_it = _mesh.cfv_iter(fh);
1055 const typename MeshT::Point& pt0 = _mesh.point(*fv_it);
1056 const typename MeshT::Point& pt1 = _mesh.point(*(++fv_it));
1057 const typename MeshT::Point& pt2 = _mesh.point(*(++fv_it));
1060 d_best = Geometry::distPointTriangleSquared(p0, pt0, pt1, pt2, p_best);
1067 *_dbest = sqrt(d_best);
1069 return (Point) p_best;
1076 template <
class Po
intT>
1077 template <
class LineNodeT>
1082 typedef typename LineNodeT::value_type Vec3fL;
1088 _line_node =
new LineNodeT(LineNodeT::LineSegmentsMode, 0,
"PolyLine");
1089 _line_node->set_line_width(5.0);
1091 _line_node->set_base_color(
1092 OpenMesh::Vec4f(0.2 +
double(rand()) /
double(RAND_MAX) * 0.8, 0.2 +
double(rand()) /
double(RAND_MAX) * 0.8,
1093 0.2 +
double(rand()) /
double(RAND_MAX) * 0.8, 1.0));
1098 for (
unsigned int i = 0; i < this->
points().size() - 1; ++i) {
1099 _line_node->add_line((Vec3fL) this->
points()[i], (Vec3fL) this->
points()[i + 1]);
1104 if (!this->
points().empty()) {
1105 _line_node->add_point((Vec3fL) this->
points()[0]);
1111 _line_node =
new LineNodeT(LineNodeT::PolygonMode, 0,
"PolyLine");
1112 _line_node->set_line_width(5.0);
1114 _line_node->set_base_color(
1115 OpenMesh::Vec4f(0.2 +
double(rand()) /
double(RAND_MAX) * 0.8, 0.2 +
double(rand()) /
double(RAND_MAX) * 0.8,
1116 0.2 +
double(rand()) /
double(RAND_MAX) * 0.8, 1.0));
1121 for (
unsigned int i = 0; i < this->
points().size(); ++i) {
1122 _line_node->add_point((Vec3fL) this->
points()[i]);
1127 if (!this->
points().empty()) {
1128 _line_node->add_point((Vec3fL) this->
points()[0]);
1139 template <
class Po
intT>
1140 template <
class LineNodeT>
1153 const typename LineNodeT::PointVector& ln_points = _line_node->points();
1155 for (
unsigned int i = 0; i < ln_points.size();) {
1156 if (i != ln_points.size() - 1)
1160 if ((ln_points[ln_points.size() - 1] - ln_points[0]).sqrnorm() == 0) {
1178 const typename LineNodeT::PointVector& ln_points(_line_node->points());
1180 for (
unsigned int i = 0; i < ln_points.size(); ++i) {
1190 template <
class Po
intT>
1195 std::cerr <<
"****** PolyInfo ******\n";
1196 std::cerr <<
"closed : " <<
closed_ << std::endl;
1197 std::cerr <<
"#points: " <<
points_.size() << std::endl;
1198 for(
unsigned int i=0; i<
points_.size(); ++i)
1199 std::cerr <<
points_[i] << std::endl;
1206 template <
class Po
intT>
1207 template <
class PropT>
1225 template <
class Po
intT>
1226 template <
class PropT>
1231 if( _ref_count <= 1)
1243 template <
class Po
intT>
1251 std::cerr <<
"Warning: invalid range in PolyLine::copy_vertex_complete ( " 1252 << _i <<
" " << _j <<
" ) " << std::endl;
1262 if( _pl.vertex_normals_available())
1263 if( vertex_normals_available())
1264 vertex_normal(_j) = _pl.vertex_normal(_i);
1266 if( _pl.vertex_binormals_available())
1267 if( vertex_binormals_available())
1268 vertex_binormal(_j) = _pl.vertex_binormal(_i);
1271 if( _pl.vertex_colors_available())
1272 if( vertex_colors_available())
1273 vertex_color(_j) = _pl.vertex_color(_i);
1276 if( _pl.vertex_scalars_available())
1277 if( vertex_scalars_available())
1278 vertex_scalar(_j) = _pl.vertex_scalar(_i);
1281 if( _pl.vertex_selections_available())
1282 if( vertex_selections_available())
1283 vertex_selection(_j) = _pl.vertex_selection(_i);
1286 if( _pl.vertex_vhandles_available())
1287 if( vertex_vhandles_available())
1288 vertex_vhandle(_j) = _pl.vertex_vhandle(_i);
1291 if( _pl.vertex_ehandles_available())
1292 if( vertex_ehandles_available())
1293 vertex_ehandle(_j) = _pl.vertex_ehandle(_i);
1296 if( _pl.vertex_ehandles_available())
1297 if( vertex_ehandles_available())
1298 vertex_ehandle(_j) = _pl.vertex_ehandle(_i);
1305 template <
class Po
intT>
1313 std::cerr <<
"Warning: invalid range in PolyLine::copy_edge_complete ( " 1314 << _i <<
" " << _j <<
" ) " << std::endl;
1319 if( _pl.edge_selections_available())
1320 if( edge_selections_available())
1321 edge_selection(_j) = _pl.edge_selection(_i);
1325 if( _pl.edge_normals_available())
1326 if( edge_normals_available())
1327 edge_normal(_j) = _pl.edge_normal(_i);
1330 if( _pl.edge_colors_available())
1331 if( edge_colors_available())
1332 edge_color(_j) = _pl.edge_color(_i);
1335 if( _pl.edge_scalars_available())
1336 if( edge_scalars_available())
1337 edge_scalar(_j) = _pl.edge_scalar(_i);
1340 if( _pl.edge_selections_available())
1341 if( edge_selections_available())
1342 edge_selection(_j) = _pl.edge_selection(_i);
1345 if( _pl.edge_selections_available())
1346 if( edge_selections_available())
1347 edge_selection(_j) = _pl.edge_selection(_i);
1354 template <
class Po
intT>
1362 std::cerr <<
"Warning: inversion for closed polylines is not supported!!!\n";
1370 pl_temp.copy_vertex_complete( *
this, n_vertices()-1-i, i);
1373 for(
unsigned int i=0; i<
n_edges(); ++i)
1374 pl_temp.copy_edge_complete( *
this, n_edges()-1-i, i);
1384 template <
class Po
intT>
1393 std::cerr <<
"Warning: appending not supported for closed polylines!!!\n";
1398 unsigned int old_ne =
n_edges();
1402 for(
unsigned int i=0; i<_pl.
n_vertices(); ++i)
1403 copy_vertex_complete( _pl, i, i+old_nv);
1405 for(
unsigned int i=0; i<_pl.
n_edges(); ++i)
1406 copy_edge_complete( _pl, i, i+old_ne+1);
1413 template <
class Po
intT>
1428 template <
class Po
intT>
1435 std::cerr <<
"Warning: split_closed was called for open polyline!\n";
1447 pl_temp.copy_vertex_complete( *
this, (i+_split_idx)%
n_vertices(),i);
1449 for(
unsigned int i=0; i<
n_edges(); ++i)
1450 pl_temp.copy_edge_complete( *
this, (i+_split_idx)%n_edges(),i);
1460 template <
class Po
intT>
1474 for(
unsigned int i=_split_idx; i<
n_vertices(); ++i)
1475 _new_pl.copy_vertex_complete(*
this, i, i-_split_idx);
1477 for(
unsigned int i=_split_idx; i<
n_edges(); ++i)
1478 _new_pl.copy_edge_complete(*
this, i, i-_split_idx);
1489 template <
class Po
intT>
1490 template <
class IPo
int>
1494 const IPoint& _n_plane,
1499 double a = (_n_plane | (_p_plane - _p0));
1500 double b = (_n_plane | (_p1 - _p0));
1502 if (fabs(b) > 1e-9) {
1505 if (s >= 0.0 && s <= 1.0) {
1506 _p_int = _p0 + (_p1 - _p0) * s;
1509 if (fabs((_n_plane | (_p_int - _p_plane))) > 1e-9)
1510 std::cerr <<
"WARNING: wrong intersection point!!!\n";
1523 template <
class Po
intT>
1524 template<
class MeshT>
1530 const typename MeshT::FaceHandle _fh0,
1531 const typename MeshT::FaceHandle _fh1,
1532 std::vector<Point> & _points,
1533 std::vector<typename MeshT::EdgeHandle>& _ehandles )
1539 Point p_start = _p0;
1542 typename MeshT::FaceHandle fh_start = _fh0;
1543 typename MeshT::FaceHandle fh_end = _fh1;
1545 if( fh_start == fh_end)
1549 std::vector<Point> new_points0, new_points1;
1552 std::vector<typename MeshT::EdgeHandle> new_eh0, new_eh1;
1560 typename MeshT::HalfedgeHandle heh = _mesh.halfedge_handle(fh_start);
1561 Point p0 = (Point)_mesh.point(_mesh.to_vertex_handle( heh ));
1562 Point p1 = (Point)_mesh.point(_mesh.to_vertex_handle( heh = _mesh.next_halfedge_handle(heh) ));
1563 Point p2 = (Point)_mesh.point(_mesh.to_vertex_handle( heh = _mesh.next_halfedge_handle(heh) ));
1564 Point n_start = ((p1-p0)%(p2-p0)).normalize();
1567 heh = _mesh.halfedge_handle(fh_end);
1568 p0 = _mesh.point(_mesh.to_vertex_handle( heh ));
1569 p1 = _mesh.point(_mesh.to_vertex_handle( heh = _mesh.next_halfedge_handle(heh) ));
1570 p2 = _mesh.point(_mesh.to_vertex_handle( heh = _mesh.next_halfedge_handle(heh) ));
1571 Point n_end = ((p1-p0)%(p2-p0)).normalize();
1574 Point n_avg = n_start + n_end;
1575 if( n_avg.sqrnorm() < 1e-7) n_avg = n_start - n_end;
1579 Point n_plane = n_avg % (p_start-p_end).normalize();
1580 if( n_plane.sqrnorm() > 1e-9) n_plane.normalize();
1581 else std::cerr <<
"WARNING: Edge Resampling -> not possible to construct stable cut plane!!!\n";
1582 Point p_plane = (p_start + p_end)*0.5;
1585 std::vector<typename MeshT::HalfedgeHandle > start_hehs;
1586 std::vector<Point> start_ps;
1587 heh = _mesh.halfedge_handle(fh_start);
1589 for(
unsigned int i=0; i<3; ++i)
1592 p0 = (Point) _mesh.point(_mesh.from_vertex_handle(heh));
1593 p1 = (Point) _mesh.point(_mesh.to_vertex_handle (heh));
1598 start_hehs.push_back( heh );
1599 start_ps.push_back(p_int);
1602 heh = _mesh.next_halfedge_handle(heh);
1607 std::vector<typename MeshT::HalfedgeHandle > end_hehs;
1608 std::vector<Point> end_ps;
1609 heh = _mesh.halfedge_handle(fh_end);
1610 for(
unsigned int i=0; i<3; ++i)
1613 p0 = (Point) _mesh.point(_mesh.from_vertex_handle(heh));
1614 p1 = (Point) _mesh.point(_mesh.to_vertex_handle (heh));
1619 end_hehs.push_back( heh );
1620 end_ps.push_back(p_int);
1623 heh = _mesh.next_halfedge_handle(heh);
1628 if( start_hehs.size() != 2 || end_hehs.size() != 2)
1630 std::cerr <<
"PolyLineResampling ERROR: wrong number of intersections... ";
1631 std::cerr << start_hehs.size() <<
" ";
1632 std::cerr << end_hehs.size() << std::endl;
1638 if( start_hehs.size() == 2 && end_hehs.size() == 2)
1641 typename MeshT::HalfedgeHandle cur_heh0 = start_hehs[0];
1642 typename MeshT::HalfedgeHandle cur_heh1 = start_hehs[1];
1645 new_points0.push_back( start_ps[0]);
1646 new_eh0.push_back( _mesh.edge_handle( cur_heh0));
1648 new_points1.push_back( start_ps[1]);
1649 new_eh1.push_back( _mesh.edge_handle( cur_heh1));
1651 unsigned int count = 0;
1653 while( _mesh.face_handle(_mesh.opposite_halfedge_handle(cur_heh0)) != fh_end &&
1654 _mesh.face_handle(_mesh.opposite_halfedge_handle(cur_heh1)) != fh_end &&
1660 cur_heh0 = _mesh.opposite_halfedge_handle( cur_heh0);
1663 if( _mesh.is_boundary(cur_heh0))
1665 std::cerr <<
"ERROR: found boundary in traversal!!!\n";
1666 cur_heh0 = _mesh.opposite_halfedge_handle( cur_heh0);
1669 unsigned int old_size = new_points0.size();
1671 for(
unsigned int i=0; i<2; ++i)
1674 cur_heh0 = _mesh.next_halfedge_handle(cur_heh0);
1677 p0 = (Point) _mesh.point(_mesh.from_vertex_handle(cur_heh0));
1678 p1 = (Point) _mesh.point(_mesh.to_vertex_handle (cur_heh0));
1683 new_points0.push_back(p_int);
1684 new_eh0.push_back( _mesh.edge_handle( cur_heh0));
1690 if( new_points0.size() != old_size + 1)
1691 std::cerr <<
"WARNING: could not find new point!!!\n";
1695 cur_heh1 = _mesh.opposite_halfedge_handle( cur_heh1);
1698 if( _mesh.is_boundary(cur_heh1))
1700 std::cerr <<
"ERROR: found boundary in traversal!!!\n";
1701 cur_heh1 = _mesh.opposite_halfedge_handle( cur_heh1);
1704 unsigned int old_size = new_points1.size();
1706 for(
unsigned int i=0; i<2; ++i)
1709 cur_heh1 = _mesh.next_halfedge_handle(cur_heh1);
1712 p0 = (Point) _mesh.point(_mesh.from_vertex_handle(cur_heh1));
1713 p1 = (Point) _mesh.point(_mesh.to_vertex_handle (cur_heh1));
1718 new_points1.push_back(p_int);
1719 new_eh1.push_back( _mesh.edge_handle( cur_heh1));
1725 if( new_points1.size() != old_size + 1)
1726 std::cerr <<
"WARNING: could not find new point!!!\n";
1736 if(_mesh.face_handle(_mesh.opposite_halfedge_handle(cur_heh0)) == fh_end )
1739 _points = new_points0;
1740 _ehandles = new_eh0;
1743 if (_mesh.face_handle(_mesh.opposite_halfedge_handle(cur_heh1)) == fh_end)
1746 _points = new_points1;
1747 _ehandles = new_eh1;
1756 template <
class Po
intT>
1767 if( (
point(i) -
point(i_next)).norm() < _epsilon)
1769 if( vertex_ehandles_available())
1771 if( !_keep_edge_vertices || vertex_ehandle(i_next) == -1)
1777 if( vertex_ehandle(i) == -1)
1797 if( (
point(i) -
point(i_next)).norm() < _epsilon)
1799 if( vertex_ehandles_available())
1801 if( !_keep_edge_vertices || vertex_ehandle(i_next) == -1)
1811 if( vertex_ehandle(i) == -1)
1838 template <
class Po
intT>
1839 typename PolyLineT<PointT>::Scalar
1846 if (!edge_normals_available() || !
is_closed()) {
1847 std::cerr <<
"Warning: PolyLineT::total_gaussian_curvature requires a closed loop and edge normals!!!\n";
1851 for (
unsigned int i = 0; i <
n_edges(); ++i) {
1854 Point n0 = edge_normal(i);
1856 Point n1 = edge_normal((i + 1) %
n_edges());
1859 if (e0.norm() > 1e-8)
1862 std::cerr <<
"Warning: e0 is undefined...\n";
1865 if (e1.norm() > 1e-8)
1868 std::cerr <<
"Warning: e1 is undefined...\n";
1873 if (n0.norm() > 1e-4)
1876 std::cerr <<
"Warning: n0 is undefined...\n";
1879 if (n1.norm() > 1e-4)
1882 std::cerr <<
"Warning: n1 is undefined...\n";
1891 if (b0.norm() > 1e-8)
1894 std::cerr <<
"Warning: b0 is undefined...\n";
1906 if (d.norm() < 1e-3)
1912 double dp = (-e0 | d);
1913 dp = std::max(-1.0, dp);
1914 dp = std::min(1.0, dp);
1917 double boundary_angle = acos(dp);
1920 dp = std::max(-1.0, dp);
1921 dp = std::min(1.0, dp);
1924 boundary_angle += acos(dp);
1926 gcurv += M_PI - boundary_angle;
1930 return (2.0 * M_PI - gcurv);
1933 template <
class Po
intT>
1934 template <
class MeshT>
1938 MeshT> &component) {
1940 MeshT &mesh = component.getMesh();
1942 for (
typename MeshT::FaceIter
1943 f_it = mesh.faces_begin(), f_end = mesh.faces_end();
1944 f_it != f_end; ++f_it) {
1945 component[*f_it] = 0;
1948 unsigned int current_component = 0;
1949 for (
typename MeshT::FaceIter f_it = mesh.faces_begin(),
1950 f_end = mesh.faces_end(); f_it != f_end; ++f_it) {
1952 if (component[*f_it] != 0)
1955 ++current_component;
1960 std::stack<typename MeshT::FaceHandle> dfs;
1963 while (!dfs.empty()) {
1964 const typename MeshT::FaceHandle fh = dfs.top(); dfs.pop();
1966 component[fh] = current_component;
1972 for (
typename MeshT::FFIter ff_it = mesh.ff_begin(fh),
1973 ff_end = mesh.ff_end(fh); ff_it != ff_end; ++ff_it) {
1975 if (component[*ff_it] == 0)
1980 std::cout <<
"\x1b[33mmark_components: Mesh has " << current_component
1981 <<
" components.\x1b[0m" << std::endl;
1985 template <
class Po
intT>
1986 template<
class MeshT,
class SpatialSearchT>
1992 SpatialSearchT &_ssearch) {
1994 typename MeshT::FaceHandle fh;
1999 return component[fh];
2002 template <
class Po
intT>
2003 template <
class MeshT,
class SpatialSearchT>
2006 SpatialSearchT &_ssearch) {
2008 if (
points_.empty())
return false;
2012 "component.on_multiple_components.objecttypes.polyline" 2013 ".i8.informatik.rwth-aachen.de");
2018 const unsigned int first_component =
2021 for (
typename std::vector<PointT>::iterator pt_it = ++
points_.begin(),
2022 pt_end =
points_.end(); pt_it != pt_end; ++pt_it) {
2024 if (first_component !=
component_of(component, *pt_it, _ssearch))
2031 template <
class Po
intT>
2032 template <
class MeshT,
class SpatialSearchT>
2035 SpatialSearchT &_ssearch,
2036 std::vector<PolyLineT> &out_polylines) {
2038 if (
points_.size() < 2)
return;
2042 "component.split_into_one_per_component.objecttypes.polyline" 2043 ".i8.informatik.rwth-aachen.de");
2049 unsigned int current_component =
2052 for (
typename std::vector<PointT>::iterator pt_it = ++
points_.begin(),
2053 pt_end =
points_.end(); pt_it != pt_end; ++pt_it) {
2059 const unsigned int next_comp =
component_of(component, *pt_it, _ssearch);
2060 if (next_comp == current_component) {
2070 PointT p0 = current_polyLine.
back();
2071 const PointT p1 = *pt_it;
2072 unsigned int comp = next_comp;
2075 const double dist = (p0 - p1).norm();
2077 double firstOut = 1;
2082 static const double EPSILON = 1e-12;
2083 while ((firstOut - lastIn) * dist > EPSILON) {
2084 const double new_pos = .5 * (lastIn + firstOut);
2085 const PointT new_pt = p0 * (1.0 - new_pos) + p1 * new_pos;
2086 const unsigned int new_comp =
2089 if (new_comp == current_component) {
2098 current_polyLine.
add_point(p0 * (1.0 - lastIn) + p1 * lastIn);
2100 out_polylines.push_back(current_polyLine);
2101 current_polyLine.
clear();
2102 current_polyLine.
add_point(p0 * (1.0 - firstOut) + p1 * firstOut);
2103 current_component = comp;
2106 p0 = p0 * (1.0 - firstOut) + p1 * firstOut;
2107 }
while (comp != next_comp);
2109 if (current_polyLine.
back() != *pt_it)
2114 out_polylines.push_back(current_polyLine);
2117 if(out_polylines.size() <= 1)
2119 out_polylines.clear();
2120 out_polylines.push_back(*
this);
2124 template <
class Po
intT>
2126 size_t n = cprop_enum.size();
2127 for (
int i = 0; i < n; ++i)
2128 if (cprop_enum[i] == _prop)
2133 template <
class Po
intT>
2135 return (_handle >= 0 && _handle <
int(get_num_custom_properties()) ? cprop_enum[_handle] : NULL);
2138 template <
class Po
intT>
2140 return (_handle >= 0 && _handle <
int(get_num_custom_properties()) ? cprop_enum[_handle] : NULL);
2143 template <
class Po
intT>
2146 unsigned int _prop_size) {
2148 CustomPropertyHandle h = get_custom_property_handle(_name);
2156 pcontainer->name = _name;
2157 pcontainer->ref_count = 1;
2158 pcontainer->prop_size = _prop_size;
2160 pcontainer->datatype = 0;
2162 pcontainer->prop_data.resize(
n_vertices() * _prop_size, 0);
2164 custom_properties[_name] = pcontainer;
2166 cprop_enum.push_back(pcontainer);
2169 if (++pcontainer->ref_count < 1)
2170 pcontainer->ref_count = 1;
2173 return custom_prop_handle(pcontainer);
2176 template <
class Po
intT>
2182 if (p && --(p->ref_count) <= 0)
2183 p->prop_data.clear();
2186 template <
class Po
intT>
2190 CustomPropertyHandle h = get_custom_property_handle(_name);
2191 release_custom_property(h);
2194 template <
class Po
intT>
2198 typename CustomPropertyMap::const_iterator it = custom_properties.find(_name);
2200 if (it == custom_properties.end())
2203 return custom_prop_handle(it->second);
2206 template <
class Po
intT>
2215 std::cerr <<
"PolyLineT::get_custom_property_name - invalid handle" << std::endl;
2221 template <
class Po
intT>
2225 const void* _data) {
2228 std::cerr <<
"PolyLineT::set_custom_property - invalid data" << std::endl;
2235 unsigned int offset = p->prop_size * _i;
2238 if (offset + p->prop_size > p->prop_data.size()) {
2239 std::cerr <<
"PolyLineT::set_custom_property - out of range access" << std::endl;
2245 memcpy(p->buffer() + offset, _data, p->prop_size);
2248 std::cerr <<
"PolyLineT::set_custom_property - invalid handle" << std::endl;
2251 template <
class Po
intT>
2255 const void* _data) {
2257 CustomPropertyHandle h = get_custom_property_handle(_name);
2258 set_custom_property(h, _i, _data);
2261 template <
class Po
intT>
2268 std::cerr <<
"PolyLineT::get_custom_property - invalid destination address" << std::endl;
2276 unsigned int offset = p->prop_size * _i;
2279 if (offset + p->prop_size >= p->prop_data.size()) {
2280 std::cerr <<
"PolyLineT::get_custom_property - out of range access" << std::endl;
2285 memcpy(_dst, p->buffer() + offset, p->prop_size);
2288 std::cerr <<
"PolyLineT::get_custom_property - invalid handle" << std::endl;
2291 template <
class Po
intT>
2295 void* _data)
const {
2297 CustomPropertyHandle h = get_custom_property_handle(_name);
2298 get_custom_property(h, _i, _data);
2302 template <
class Po
intT>
2309 return p->ref_count > 0;
2315 template <
class Po
intT>
2319 CustomPropertyHandle h = get_custom_property_handle(_name);
2320 return custom_property_available(h);
2324 template <
class Po
intT>
2332 p->datatype = _datatype;
2333 p->shader_binding = _shader_input_name;
2336 std::cerr <<
"PolyLineT::bind_custom_property_to_shader - invalid handle" << std::endl;
2340 template <
class Po
intT>
2349 *_propsize = p->prop_size;
2352 *_input_name = p->shader_binding.c_str();
2355 *_datatype = p->datatype;
2357 return !p->shader_binding.empty() && p->datatype;
2360 std::cerr <<
"PolyLineT::get_custom_property_shader_binding - invalid handle" << std::endl;
2365 template <
class Po
intT>
2374 std::cerr <<
"PolyLineT::get_custom_property_buffer - invalid handle" << std::endl;
2379 template <
class Po
intT>
2382 return custom_properties.size();
2385 template <
class Po
intT>
2389 if (_i < get_num_custom_properties())
2390 return CustomPropertyHandle(_i);
bool plane_line_intersection(const IPoint &_p_plane, const IPoint &_n_plane, const IPoint &_p0, const IPoint &_p1, IPoint &_p_int)
void mark_components(OpenMesh::PropertyManager< OpenMesh::FPropHandleT< unsigned int >, MeshT > &component)
Point find_nearest_point(const MeshT &_mesh, const Point &_point, typename MeshT::FaceHandle &_fh, SpatialSearchT *_ssearch=0, double *_dbest=0)
size_t n_edges() const
Get number of edges.
LineNodeT * get_line_node(LineNodeT *&_line_node, int _mode=0)
Conversion PolyLine <-> LineNode.
void append(const PolyLineT< PointT > &_pl)
Append second polyline _pl to this one.
bool on_multiple_components(MeshT &_mesh, SpatialSearchT &_ssearch)
void project_to_mesh(const MeshT &_mesh, SpatialSearchT *_ssearch=0)
Project polyline points to nearest surface points (use spatial search!!!)
void collapse(Scalar _smallest)
Collapse polyline.
void delete_point(int _idx)
Delete point at _idx.
void smooth_uniform_laplace2()
Squared laplacian smoothing.
PolyLineT(bool _closed=false)
Constructor.
void resample_arclength_uniform(const unsigned int _n)
Perform an uniform arclength resampling while maintaining the start and end point.
Point & back()
Get last point of the polyline ( no range check!!!)
Scalar total_gaussian_curvature()
compute total gaussian curvature of enclosed surface (via Gauss-Bonnet)
void invert()
Invert polyline that first vertex becomes last.
bool closed_
Connect first and last point?
bool is_closed() const
Check if the polyline is marked as closed.
void set_closed(const bool _c)
Set if the polyline should be closed and therefore forms a loop.
void clear()
Clear the current 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 ...
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. ...
void resize(unsigned int _n)
Resize current polyline.
void prepend(const PolyLineT< PointT > &_pl)
Prepend second polyline _pl to polyline.
void print() const
Print information string to cerr.
void bind_custom_property_to_shader(CustomPropertyHandle _property_handle, const std::string &_shader_input_name, unsigned int _datatype)
Binding to vertex shader (optional)
std::vector< Point > & points()
Get all points of the polyline.
void insert_point(int _idx, const Point &_p)
insert _p at _idx into polyline
void smooth_uniform_laplace3()
Cubic laplacian smoothing.
Point edge_vector(unsigned int _i) const
get the i-th oriented edge vector
void subdivide(Scalar _largest)
Subdivide polyline.
void split(unsigned int _split_idx, PolyLineT< PointT > &_new_pl)
Split closed polyline at vertex with index _split_idx.
Point & point(unsigned int _i)
Get a point of the polyline.
std::vector< Point > points_
List of points in the polyline.
Namespace providing different geometric functions concerning angles.
Scalar length() const
Compute the length of the polyline (in future cached method)
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 add_point(const Point &_p)
Append a point to the polyline.
bool get_custom_property_shader_binding(CustomPropertyHandle _property_handle, unsigned int *_propsize, const char **_input_name, unsigned int *_datatype) const
Get shader binding information.
unsigned int component_of(const OpenMesh::PropertyManager< OpenMesh::FPropHandleT< unsigned int >, MeshT > &component, const PointT &pt, SpatialSearchT &_ssearch)
Point & front()
Get first point of the polyline ( no range check!!!)
void smooth_uniform_laplace()
Laplacian smoothing.
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)
size_t n_vertices() const
Get number of vertices.
Point position_arclength(const Scalar _t) const
Same as position but with an arclength parameterization in [0,length()].
void split_closed(unsigned int _split_idx)
Split closed polyline at vertex with index _split_idx.
VectorT< Scalar, 3 > perpendicular(const VectorT< Scalar, 3 > &v)
find a vector that's perpendicular to _v