vgl_pointset_3d.h
Go to the documentation of this file.
1 // This is core/vgl/vgl_pointset_3d.h
2 #ifndef vgl_pointset_3d_h_
3 #define vgl_pointset_3d_h_
4 //:
5 // \file
6 // \brief A 3-d pointset. points can have normals to represent sampled surface patches
7 // \author J.L. Mundy
8 //
9 // \verbatim
10 // Modifications
11 // Initial version August 29, 2015
12 // \endverbatim
13 
14 #include <iostream>
15 #include <sstream>
16 #include <string>
17 #include <utility>
18 #include <vector>
19 #include <cassert>
20 #ifdef _MSC_VER
21 # include <vcl_msvc_warnings.h>
22 #endif
23 #include <vgl/vgl_point_3d.h>
24 template <class Type>
25 class vgl_pointset_3d
26 {
27  //: members
30  std::vector<vgl_point_3d<Type> > points_;
31  std::vector<vgl_vector_3d<Type> > normals_;
32  std::vector< Type > scalars_;
33  public:
34  //: Default constructor
36 
37  //: Construct from a list
38  vgl_pointset_3d(std::vector<vgl_point_3d<Type> > points): has_normals_(false), has_scalars_(false), points_(std::move(points)){}
39 
41  has_normals_(true), has_scalars_(false), points_(std::move(points)), normals_(std::move(normals)){}
42 
43  vgl_pointset_3d(std::vector<vgl_point_3d<Type> > points, std::vector< Type > scalars):
44  has_normals_(false), has_scalars_(true), points_(std::move(points)), scalars_(std::move(scalars)){}
45 
47  std::vector<vgl_vector_3d<Type> > normals,
48  std::vector< Type > scalars):
49  has_normals_(true), has_scalars_(true), points_(std::move(points)), normals_(std::move(normals)), scalars_(std::move(scalars)){}
50 
51  //: incrementally grow points, duplicate points are allowed
53  points_.push_back(p); has_normals_=false; has_scalars_ = false;
54  }
55  //: incrementally grow points and normals duplicate pairs are allowed
57  points_.push_back(p); normals_.push_back(normal); has_normals_ = true, has_scalars_ = false;
58  }
60  points_.push_back(p); scalars_.push_back(sc); has_scalars_ = true;
61  }
63  points_.push_back(p); normals_.push_back(normal), scalars_.push_back(sc); has_normals_ = true; has_scalars_ = true;
64  }
65  //: accessors
66  bool has_normals() const {return has_normals_;}
67  bool has_scalars() const {return has_scalars_;}
68  size_t npts() const {return points_.size();}
69  size_t size() const {return points_.size();}
70  vgl_point_3d<Type> p(unsigned i) const {return points_[i];}
71  vgl_vector_3d<Type> n(unsigned i) const
72  {if(has_normals_) return normals_[i]; return vgl_vector_3d<Type>();}
73  Type sc(unsigned i) const {if(has_scalars_) return scalars_[i]; return Type(0);}
74 
75  std::vector<vgl_point_3d<Type> > points() const {return points_;}
76  std::vector<vgl_vector_3d<Type> > normals() const {return normals_;}
77  std::vector< Type > scalars() const {return scalars_;}
78  void clear(){points_.clear(); normals_.clear();}
79  void set_points(std::vector<vgl_point_3d<Type> > const& points)
80  { points_ = points; has_normals_=false; has_scalars_ = false;}
81 
83  std::vector<vgl_vector_3d<Type> > const& normals)
84  { points_ = points; normals_ = normals; has_normals_=true; has_scalars_ = false;}
85 
87  std::vector< Type > const& scalars)
89 
91  std::vector<vgl_vector_3d<Type> > const& normals,
92  std::vector< Type > const& scalars)
94 
95 
97  if(this->has_normals_ != ptset.has_normals())
98  return; // can't be done
99  unsigned npts = ptset.npts();
100  for(unsigned i = 0; i<npts; ++i){
101  if(!this->has_normals_&& !this->has_scalars_)
102  this->add_point(ptset.p(i));
103  else if(!this->has_scalars_)
104  this->add_point_with_normal(ptset.p(i), ptset.n(i));
105  else if(!this->has_normals_)
106  this->add_point_with_scalar(ptset.p(i), ptset.sc(i));
107  else
108  this->add_point_with_normal_and_scalar(ptset.p(i), ptset.n(i), ptset.sc(i));
109  }
110  }
111 
112  bool set_point(unsigned i, vgl_point_3d<Type> const& p){
113  if(i>=static_cast<unsigned>(points_.size())) return false;
114  points_[i].set(p.x(), p.y(), p.z()); return true;
115  }
116  bool set_normal(unsigned i, vgl_vector_3d<Type> const& n){
117  if(has_normals_&& i<static_cast<unsigned>(normals_.size())){
118  normals_[i].set(n.x(), n.y(), n.z()); return true;}
119  else return false;}
120 
121  bool set_scalar(unsigned i, Type sc){
122  if(has_scalars_&& i<static_cast<unsigned>(scalars_.size())){
123  scalars_[i] = sc; return true;}
124  else return false;}
125 
126  //: Equality operator
127  bool operator==(const vgl_pointset_3d<Type> &spl) const;
128 
129  bool operator!=(vgl_pointset_3d<Type>const& spl) const { return !operator==(spl); }
130 
131 };
132 
133 template <class Type>
135  unsigned n = pointset.npts();
136  if(n != this->npts())
137  return false;
138  std::vector<vgl_point_3d<Type> > pts = pointset.points();
139  for(unsigned i =0; i<n; ++i)
140  if(pts[i] != points_[i])
141  return false;
142  if((has_normals() && !pointset.has_normals()) || (!has_normals() && pointset.has_normals()))
143  return false;
144  if(has_normals_){
145  if(static_cast<unsigned>(normals_.size()) != n)
146  return false;
147  std::vector<vgl_vector_3d<Type> > normals = pointset.normals();
148  for(unsigned i =0; i<n; ++i)
149  if(normals[i] != normals_[i])
150  return false;
151  }
152  if((has_scalars() && !pointset.has_scalars()) || (!has_scalars() && pointset.has_scalars()))
153  return false;
154  if(has_scalars_){
155  if(static_cast<unsigned>(scalars_.size()) != n)
156  return false;
157  std::vector< Type > scalars = pointset.scalars();
158  for(unsigned i =0; i<n; ++i)
159  if(scalars[i] != scalars_[i])
160  return false;
161  }
162  return true;
163 }
164 
165 template <class Type>
166 std::ostream& operator<<(std::ostream& ostr, vgl_pointset_3d<Type> const& ptset){
167  if(!ostr){
168  std::cout << "Bad ostream in write vgl_pointset_3d to stream\n";
169  return ostr;
170  }
171  std::vector<vgl_point_3d<Type> > pts = ptset.points();
172  if(!ptset.has_normals()&&!ptset.has_scalars()){
173  for(unsigned i =0; i<static_cast<unsigned>(pts.size()); i++){
174  const vgl_point_3d<Type>& p = pts[i];
175  ostr << p.x() << ',' << p.y() << ',' << p.z() << '\n';
176  }
177  }else if(!ptset.has_normals()&&ptset.has_scalars()){
178  std::vector< Type > scalars = ptset.scalars();
179  for(unsigned i =0; i<static_cast<unsigned>(pts.size()); i++){
180  const vgl_point_3d<Type>& p = pts[i];
181  Type sc = scalars[i];
182  ostr << p.x() << ',' << p.y() << ',' << p.z()<< ',' << sc << '\n';
183  }
184  }else if(ptset.has_normals()&& !ptset.has_scalars()){
185  std::vector<vgl_vector_3d<Type> > normals = ptset.normals();
186  for(unsigned i =0; i<static_cast<unsigned>(pts.size()); i++){
187  const vgl_point_3d<Type>& p = pts[i];
188  const vgl_vector_3d<Type>& n = normals[i];
189  ostr << p.x() << ',' << p.y() << ',' << p.z()<< ',' << n.x() << ',' << n.y() << ',' << n.z() << '\n';
190  }
191  }else if(ptset.has_normals()&& ptset.has_scalars()){
192  std::vector< Type > scalars = ptset.scalars();
193  std::vector<vgl_vector_3d<Type> > normals = ptset.normals();
194  for(unsigned i =0; i<static_cast<unsigned>(pts.size()); i++){
195  const vgl_point_3d<Type>& p = pts[i];
196  const vgl_vector_3d<Type>& n = normals[i];
197  Type sc = scalars[i];
198  ostr << p.x() << ',' << p.y() << ',' << p.z()<< ',' << n.x() << ',' << n.y() << ',' << n.z() << ',' << sc << '\n';
199  }
200  }
201  return ostr;
202 }
203 
204 template <class Type>
205 std::istream& operator>>(std::istream& istr, vgl_pointset_3d<Type>& ptset){
206  if(!istr){
207  std::cout << "Bad istream in read vgl_pointset_3d from stream\n";
208  return istr;
209  }
210  std::vector<vgl_point_3d<Type> > pts;
211  std::vector<vgl_vector_3d<Type> > normals;
212  std::vector<Type > scalars;
213  char buf[100];
214  bool has_normals = false;
215  bool has_scalars = false;
216  //determine the number of comma or space separators
217  // 2: points
218  // 3: points and scalars
219  // 5: points and normals
220  // 6: points, normals and scalars
221  bool first_line = true;
222  while(istr.getline(buf,100)){
223  std::string buf_str;
224  if(first_line){
225  bool done = false;
226  unsigned comma_count = 0;
227  for(unsigned i =0; i<100&&!done; ++i){
228  char c = buf[i];
229  if(c == '\0'||c == '\n'){
230  done = true;
231  continue;
232  }else{
233  buf_str.push_back(c);
234  if(c == ','||c==' ')
235  comma_count++;
236  }
237  }
238  has_scalars = (comma_count == 3 || comma_count == 6) ;
239  has_normals = (comma_count == 5 || comma_count == 6) ;
240  first_line = false;
241  }else{
242  // scan in the file line by line
243  bool done = false;
244  for(unsigned i =0; i<100&&!done; ++i){
245  char c = buf[i];
246  if(c == '\0'||c == '\n'){
247  done = true;
248  continue;
249  }
250  buf_str.push_back(c);
251  }
252  }
253  // create a stream from the valid line characters
254  std::stringstream isstr(buf_str);
255  isstr >>std::noskipws;//accept spaces as separators
256  // parse the line for point and normal values
257  Type x, y, z, nx, ny, nz, sc;
258  unsigned char c;
259  isstr >> x >> c;
260  if(!(c==','||c==' ')){
261  std::cout << "stream parse error\n";
262  return istr;
263  }
264  isstr >> y >> c;
265  if(!(c==','||c==' ')){
266  std::cout << "stream parse error\n";
267  return istr;
268  }
269  if(!has_normals&&!has_scalars)
270  isstr >> z;
271  else if(has_normals || has_scalars){
272  isstr >> z >> c;
273  if(!(c==','||c==' ')){
274  std::cout << "stream parse error\n";
275  return istr;
276  }
277  }
278  if(has_normals&&!has_scalars){
279  isstr >> nx >> c;
280  if(!(c==','||c==' ')){
281  std::cout << "stream parse error\n";
282  return istr;
283  }
284  isstr >> ny >> c;
285  if(!(c==','||c==' ')){
286  std::cout << "stream parse error\n";
287  return istr;
288  }
289  isstr >> nz;
290  }else if(has_scalars&& !has_normals)
291  isstr >> sc;
292  else if( has_scalars && has_normals){
293  isstr >> nx >> c;
294  if(!(c==','||c==' ')){
295  std::cout << "stream parse error\n";
296  return istr;
297  }
298  isstr >> ny >> c;
299  if(!(c==','||c==' ')){
300  std::cout << "stream parse error\n";
301  return istr;
302  }
303  isstr >> nz >> c;
304  if(!(c==','||c==' ')){
305  std::cout << "stream parse error\n";
306  return istr;
307  }
308  isstr >> sc;
309  }
310  vgl_point_3d<Type> p(x,y,z);
311  pts.push_back(p);
312  if(has_normals){
313  vgl_vector_3d<Type> n(nx, ny, nz);
314  normals.push_back(n);
315  }
316  if(has_scalars)
317  scalars.push_back(sc);
318  }
319  if(!has_normals&&has_scalars){
320  ptset = vgl_pointset_3d<Type>(pts, scalars);
321  return istr;
322  }else if(has_normals&&!has_scalars){
323  ptset = vgl_pointset_3d<Type>(pts, normals);
324  return istr;
325  }else if(has_scalars&&has_normals){
326  ptset = vgl_pointset_3d<Type>(pts, normals, scalars);
327  return istr;
328  }
329  ptset = vgl_pointset_3d<Type>(pts);
330  return istr;
331 };
332 
333 #endif // vgl_pointset_3d_h_
std::vector< vgl_vector_3d< Type > > normals() const
vgl_point_3d< Type > p(unsigned i) const
void add_point_with_normal(vgl_point_3d< Type > const &p, vgl_vector_3d< Type > const &normal)
incrementally grow points and normals duplicate pairs are allowed.
void append_pointset(vgl_pointset_3d< Type > const &ptset)
bool set_normal(unsigned i, vgl_vector_3d< Type > const &n)
Represents a cartesian 3D point.
Definition: vgl_fwd.h:11
std::vector< vgl_vector_3d< Type > > normals_
std::ostream & operator<<(std::ostream &s, vgl_orient_box_3d< Type > const &p)
Write box to stream.
Type & z()
Definition: vgl_point_3d.h:73
bool set_scalar(unsigned i, Type sc)
vgl_pointset_3d(std::vector< vgl_point_3d< Type > > points, std::vector< vgl_vector_3d< Type > > normals)
vgl_pointset_3d(std::vector< vgl_point_3d< Type > > points)
Construct from a list.
bool operator==(const vgl_pointset_3d< Type > &spl) const
Equality operator.
vgl_pointset_3d(std::vector< vgl_point_3d< Type > > points, std::vector< Type > scalars)
a point in 3D nonhomogeneous space
bool has_normals() const
accessors.
T y() const
Definition: vgl_vector_3d.h:37
Type sc(unsigned i) const
bool has_scalars() const
bool has_normals_
members.
std::vector< vgl_point_3d< Type > > points_
void add_point(vgl_point_3d< Type > const &p)
incrementally grow points, duplicate points are allowed.
void add_point_with_normal_and_scalar(vgl_point_3d< Type > const &p, vgl_vector_3d< Type > const &normal, Type sc)
T x() const
Definition: vgl_vector_3d.h:36
T z() const
Definition: vgl_vector_3d.h:38
Type & x()
Definition: vgl_point_3d.h:71
std::vector< Type > scalars_
void set_points(std::vector< vgl_point_3d< Type > > const &points)
void set_points_with_normals_and_scalars(std::vector< vgl_point_3d< Type > > const &points, std::vector< vgl_vector_3d< Type > > const &normals, std::vector< Type > const &scalars)
std::istream & operator>>(std::istream &is, vgl_orient_box_3d< Type > &p)
Read box from stream.
std::vector< Type > scalars() const
std::vector< vgl_point_3d< Type > > points() const
void set_points_with_normals(std::vector< vgl_point_3d< Type > > const &points, std::vector< vgl_vector_3d< Type > > const &normals)
size_t size() const
void set_points_with_scalars(std::vector< vgl_point_3d< Type > > const &points, std::vector< Type > const &scalars)
bool set_point(unsigned i, vgl_point_3d< Type > const &p)
size_t npts() const
void add_point_with_scalar(vgl_point_3d< Type > const &p, Type sc)
vgl_pointset_3d()
Default constructor.
Type & y()
Definition: vgl_point_3d.h:72
bool operator!=(vgl_pointset_3d< Type >const &spl) const
vgl_vector_3d< Type > n(unsigned i) const
vgl_pointset_3d(std::vector< vgl_point_3d< Type > > points, std::vector< vgl_vector_3d< Type > > normals, std::vector< Type > scalars)