Points&Forces (survey)
Software tools facilitating the task of surveying architecture
a_screen.cxx
Go to the documentation of this file.
1 /*
2  Copyright 2002-2022 Pierre SMARS (smars@yuntech.edu.tw)
3  This program is free software: you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation, either version 2 of the License, or
6  (at your option) any later version.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 #include "vtkActor.h"
17 #include "vtkAppendPolyData.h"
18 #include "vtkCamera.h"
19 #include "vtkCellArray.h"
20 #include "vtkDataSetMapper.h"
21 #include "vtkInteractorStyleTrackballCamera.h"
22 #include "vtkJPEGWriter.h"
23 #include "vtkLight.h"
24 #include "vtkLightCollection.h"
25 #include "vtkPoints.h"
26 #include "vtkPolyDataWriter.h"
27 #include "vtkRenderLargeImage.h"
28 #include "vtkRenderer.h"
29 #include "vtkRenderWindow.h"
30 #include "vtkRenderWindowInteractor.h"
31 #include "vtkRIBExporter.h"
32 #include "vtkTIFFWriter.h"
33 #include "vtkPNGWriter.h"
34 #include "vtkVRMLExporter.h"
35 #include "vtkWindowToImageFilter.h"
36 // #include "vtkXRenderWindowTclInteractor.h"
37 #include "a_dxf_group.h"
38 #include "a_dxf_entity.h"
39 #include "a_dxf_point.h"
40 #include "a_dxf_line.h"
41 #include "a_dxf_polyline.h"
42 #include "a_interactor.h"
43 
44 #include <sstream>
45 #include <algorithm>
46 #include "a_screen.h"
47 
48 //---------------------------------------------------------------------------
49 const std::string a_screen::help()
50 {
51  std::ostringstream o;
52  o << "**********" << std::endl;
53  o << "a_screen:" << std::endl;
54  o << "**********" << std::endl;
55  o << "This is a 3D window class" << std::endl;
56  o << "Commands:" << std::endl;
57  o << "--------" << std::endl;
58  o << "a_screen W: create a window" << std::endl;
59  o << "Drawing:" << std::endl;
60  o << "......." << std::endl;
61  o << "point X Y Z: draw a point." << std::endl;
62  o << "line X1 Y1 Z1 X2 Y2 Z2: draw a line." << std::endl;
63  o << "vertex X Y Z: draw point of a polyline." << std::endl;
64  o << "endpolyline: end the polyline." << std::endl;
65  o << "closepolyline: link the last vertex with the first vertex." << std::endl;
66  o << "surfacepoint X Y Z: add a point to a surface (1 surface per layer)." << std::endl;
67  o << "......." << std::endl;
68  o << "erase point: erase last point." << std::endl;
69  o << "erase line: erase last line." << std::endl;
70  o << "erase polyline: erase last polyline." << std::endl;
71  o << "Layer management:" << std::endl;
72  o << "................" << std::endl;
73  o << "the default layer is '0'" << std::endl;
74  o << "layer new NAME: create new layer" << std::endl;
75  o << "layer set NAME: set current layer" << std::endl;
76  o << "layer on NAME: make layer visible" << std::endl;
77  o << "layer off NAME: hide layer" << std::endl;
78  o << "layer erase NAME: erase layer" << std::endl;
79  o << "(alternatively: layer rm NAME)" << std::endl;
80  o << "layer list: return a list of existing layers" << std::endl;
81  o << "(alternatively: layer ls)" << std::endl;
82  o << "layer current: return name of current layer" << std::endl;
83  o << "layer exist NAME: check whether layer exists (returns 0 or 1)" << std::endl;
84  o << "color R G B: set color of current layer" << std::endl;
85  o << "R: get the red component of current layer" << std::endl;
86  o << "G: get the green component of current layer" << std::endl;
87  o << "B: get the blue component of current layer" << std::endl;
88  o << "thickness T: set thickness of lines in currrent layer" << std::endl;
89  o << "thickness: get thickness of lines in currrent layer" << std::endl;
90  o << "Navigating:" << std::endl;
91  o << ".........." << std::endl;
92  o << "interact: start mouse control (click 'e' to exit)" << std::endl;
93  o << "redraw: refresh screen" << std::endl;
94  o << "fit: fit data to screen" << std::endl;
95  o << "background R G B: change background color" << std::endl;
96  o << "perspective on: perspective view" << std::endl;
97  o << "perspective off: parallel view" << std::endl;
98  o << "cursor on: show cursor" << std::endl;
99  o << "cursor off: hide cursor" << std::endl;
100  o << "azimuth V: set azimuth angle" << std::endl;
101  o << "azimuth: get azimuth angle" << std::endl;
102  o << "(similar functions for elevation, roll, pich, yaw, distance)" << std::endl;
103  o << "camerapoint X Y Z: set view point" << std::endl;
104  o << "camerapoint: get view point" << std::endl;
105  o << "focalpoint X Y Z: set focal point" << std::endl;
106  o << "focalpoint: get focal point" << std::endl;
107  o << "light sun: fixed light" << std::endl;
108  o << "light spot: light follow camera" << std::endl;
109  o << "Input/Output:" << std::endl;
110  o << "............" << std::endl;
111  o << "import CODE FILE: import data" << std::endl;
112  o << "(code: pt, dxf)" << std::endl;
113  o << "save CODE FILE" << std::endl;
114  o << "(code: pt, dxf, jpeg, rib, png, vec, vrml, vtk)" << std::endl;
115  o << "logfile VE_TEXT: log is saved to a a_text object" << std::endl;
116  o << "outputfile VE_TEXT: output is saved to a a_text object" << std::endl;
117  o << "VE_TEXT should be created before: ex: a_text NAME" << std::endl;
118  return o.str();
119 }
120 //---------------------------------------------------------------------------
122  //a_screen::a_screen(const std::string& id)
123 {
124  // std::string id2(id);
125  // const char * id2 = id.c_str();
126  // std::istringstream in(id);
127  // int w_id;
128  // in >> w_id;
129  // std::cerr << "{" << w_id << "}" << std::endl;
130  ren_ = vtkRenderer::New();
131  renWin_ = vtkRenderWindow::New();
132  renWin_->AddRenderer(ren_);
133  //renWin_->SetParentId(w_id);
134  // renWin_->SetParentInfo(id.c_str());
135  // renWin_->SetParentInfo(id2.c_str());
136  // renWin_->SetParentId((void *)w_id);
137  // ren_->Delete();
138  renWin_->SetStereoTypeToAnaglyph();
139  renWin_->SetSize(640,480);
140  newlayer(std::string("0")); //the basis' layer name: cf. AutoCad
141  active_layer_ = *(layers_.begin());
142  ren_->AddActor(active_layer_->actor());
143  ren_->AddActor(active_layer_->actor2());
144  // this->line(0,0,0,1,0,0);
145  // this->line(0,0,0,0,1,0);
146  // this->line(0,0,0,0,0,1);
147  // iren_ = 0;
148  // iren_ = vtkRenderWindowInteractor::New();
149  // iren_->SetRenderWindow(renWin_);
150  // iren_->Start();
151 
152  a_interactor * style = a_interactor::New();
153  style->name("screen");
154  style->keep_color();
155  iren_ = vtkRenderWindowInteractor::New();
156  iren_->SetRenderWindow(renWin_);
157  iren_->SetInteractorStyle(style);
158  iren_->Initialize();
159  // iren_->Disable();
160  empty_ = true;
161  one_point_ = false;
162  x0_ = 0; y0_ = 0; z0_ = 0;
163  spotlight_ = true;
164  clip_[0] = 0.1; clip_[1] = 1000;
165  renWin_->SetWindowName("screen");
166  log_.file("a_screen.log");
167  log_.on();
168  log_ << "#!/usr/bin/env tclsh" << std::endl;
169  log_ << "package require a_screen" << std::endl;
170  log_ << "a_screen window_name" << std::endl;
171 
172 }
173 //---------------------------------------------------------------------------
175 {
177  ren_->Delete();
178  renWin_->Delete(); // gives problems
179  if (iren_) iren_->Delete(); //only if interact() was issued!
180  log_ << "rename window_name \"\"" << std::endl;
181 }
182 //---------------------------------------------------------------------------
183 //class used to compute the bounding box of the layers_
184 class a_bounding_box
185 {
186  public:
188  void operator() (a_screenlayer *);
189  double m(const char) const;
190  double d() const;
191  private:
192  double l_[6];
193 };
195 {
196  for (int i = 0; i < 3; i++) l_[i*2] = 1e30;
197  for (int i = 0; i < 3; i++) l_[i*2+1] = -1e30;
198 }
200 {
201  if (!l->empty())
202  {
203  double b[6];
204  l->actor()->GetBounds(b);
205  for (int i = 0; i < 3; i++)
206  if (b[i*2]<l_[i*2]) {l_[i*2] = b[i*2];}
207  for (int i = 0; i < 3; i++)
208  if (b[i*2+1]>l_[i*2+1]) {l_[i*2+1] = b[i*2+1];}
209  }
210 }
211 double a_bounding_box::d() const // a reference distance
212 {
213  double d0 = 0;
214  for (int i = 0; i < 3; i++) d0 += (l_[i*2+1]-l_[i*2])*(l_[i*2+1]-l_[i*2]);
215  return sqrt(d0);
216 }
217 double a_bounding_box::m(const char i) const // the centre of the object
218 {
219  return (l_[i*2]+l_[i*2+1])/2;
220 }
221 //---------------------------------------------------------------------------
222 bool a_screen::existlayer(const std::string& s) const
223 {
224  for (auto la:layers_)
225  {
226  if (*la==s)
227  return true;
228  }
229  return false;
230 }
231 //---------------------------------------------------------------------------
232 bool a_screen::existlayer(const std::string& s, a_screenlayer *& p) const
233 {
234  for (auto la:layers_)
235  {
236  if (*la==s)
237  {
238  p = la;
239  return true;
240  }
241  }
242  return false;
243 }
244 //---------------------------------------------------------------------------
245 void a_screen::newlayer(const std::string& s)
246 {
247  if (!this->existlayer(s)) //if the layer doesn't exist yet
248  {
249  //find the center of existing points
250  double fo[3];
251  if (!empty_)
252  {
253  a_bounding_box box;
254  // box = std::for_each(layers_.begin(),layers_.end(),box);
255  for (auto la:layers_)
256  box(la);
257  for (int i = 0; i < 3; i++) fo[i] = box.m(i);
258  }
259  auto l = new a_screenlayer;
260  l->name(s);
261  layers_.push_back(l);
262  ren_->AddActor(l->actor());
263  ren_->AddActor(l->actor2());
264  l->reset(); //trick to enable the sequence "newlayer,line,setlayer,line"
265  log_ << "window_name newlayer " << s << std::endl;
266  }
267 }
268 //---------------------------------------------------------------------------
270 {
271  a_screenlayer * p;
272  if (!this->existlayer(la_in.name(),p)) //if the layer doesn't exist yet
273  {
274  //find the centre of existing points
275  double fo[3];
276  if (!empty_)
277  {
278  a_bounding_box box;
279  //box = std::for_each(layers_.begin(),layers_.end(),box);
280  for (auto la:layers_)
281  box(la);
282  for (int i = 0; i < 3; i++) fo[i] = box.m(i);
283  }
284  auto la_out = new a_screenlayer;
285  la_out->reset();
286  la_out->append(la_in);
287  layers_.push_back(la_out);
288  ren_->AddActor(la_out->actor());
289  ren_->AddActor(la_out->actor2());
290  }
291  else
292  p->append(la_in);
293 }
294 //---------------------------------------------------------------------------
295 std::string a_screen::listlayers()
296 {
297  std::string s;
298  for (auto la:layers_)
299  s += la->name() + " ";
300  if (s.size() != 0)
301  s = s.substr(0,s.size()-1);
302  log_ << "window_name listlayers" << std::endl;
303  return s;
304 }
305 //---------------------------------------------------------------------------
306 void a_screen::setlayer(const std::string& s)
307 {
308  a_screenlayer * p;
309  if (!this->existlayer(s,p)) //if the layer doesn't exist yet
310  throw no_layer_error();
311  active_layer_ = p;
312  log_ << "window_name setlayer " << s << std::endl;
313 }
314 //---------------------------------------------------------------------------
315 void a_screen::eraselayer(const std::string& s)
316 {
317  if (s == "0") //cannot erase basis layer
318  throw notallowed_error();
319  if (active_layer_->name() == s) //cannot erase current layer
320  throw notallowed_error();
321  a_screenlayer * p;
322  if (!this->existlayer(s,p)) //if the layer doesn't exist yet
323  throw no_layer_error();
324  std::vector<a_screenlayer *>::iterator li = std::find(layers_.begin(),layers_.end(),p);
325  ren_->RemoveActor(p->actor());
326  ren_->RemoveActor(p->actor2());
327  if (p->hassurface())
328  ren_->RemoveActor(p->surfaceactor());
329  /*
330 
331  SHOULD BE SOLVED
332  delete p;
333  layers_.erase(&p); new.... */
334  layers_.erase(li);
335 
336  renWin_->Render();
337  log_ << "window_name eraselayer " << s << std::endl;
338 }
339 //---------------------------------------------------------------------------
340 void a_screen::setofflayer(const std::string& s)
341 {
342  a_screenlayer * p;
343  if (!this->existlayer(s,p)) //if the layer doesn't exist yet
344  throw no_layer_error();
345  p->visibility(0);
346  renWin_->Render();
347 }
348 //---------------------------------------------------------------------------
349 void a_screen::setonlayer(const std::string& s)
350 {
351  a_screenlayer * p;
352  if (!this->existlayer(s,p)) //if the layer doesn't exist yet
353  throw no_layer_error();
354  p->visibility(1);
355  renWin_->Render();
356 }
357 //---------------------------------------------------------------------------
358 const std::string a_screen::getlayer() const
359 {
360  return active_layer_->name();
361 }
362 //---------------------------------------------------------------------------
363 void a_screen::color(float r, float g, float b)
364 {
365  active_layer_->color(r,g,b);
366  if (!active_layer_->empty())
367  renWin_->Render();
368  log_ << "window_name color " << r << " " << g << " " << b << std::endl;
369 }
370 //---------------------------------------------------------------------------
371 void a_screen::thickness(const int t)
372 {
373  if ((t<8)&&(t>0))
375  if (!active_layer_->empty())
376  renWin_->Render();
377  log_ << "window_name thickness " << t << std::endl;
378 }
379 //---------------------------------------------------------------------------
381 {
382  spotlight_ = true;
384  ren_->LightFollowCameraOn();
385  if (iren_)
386  iren_->LightFollowCameraOn();
387  renWin_->Render();
388  log_ << "window_name light spot" << std::endl;
389 }
390 //---------------------------------------------------------------------------
392 {
393  spotlight_ = false;
395  ren_->LightFollowCameraOff();
396  if (iren_)
397  iren_->LightFollowCameraOff();
398  renWin_->Render();
399  //this->output_position();
400  log_ << "window_name light sun" << std::endl;
401 }
402 //---------------------------------------------------------------------------
404 {
405  ren_->GetActiveCamera()->ParallelProjectionOn();
406  renWin_->Render();
407  log_ << "window_name perspective off" << std::endl;
408 }
409 //---------------------------------------------------------------------------
411 {
412  ren_->GetActiveCamera()->ParallelProjectionOff();
413  renWin_->Render();
414  log_ << "window_name perspective on" << std::endl;
415 }
416 //---------------------------------------------------------------------------
418 {
419  // iren_->Start();
420  // iren_->Initialize();
421  // iren_->Enable();
422  iren_->Start();
423  if (iren_==0)
424  {
425  /* std::cerr << "interactor started" << std::endl;
426  // view_pt_interactor * style = view_pt_interactor::New();
427  // iren_ = vtkRenderWindowInteractor::New();
428  // iren_->SetRenderWindow(renWin_);
429  // renWin_->Delete();
430  // iren_->SetInteractorStyle(style);
431  // iren_->Initialize();
432  vtkInteractorStyleTrackballCamera * style = vtkInteractorStyleTrackballCamera::New();
433  iren_ = vtkRenderWindowInteractor::New();
434  //iren_ = vtkXRenderWindowTclInteractor::New();
435  iren_->SetRenderWindow(renWin_);
436  // renWin_->MakeCurrent();
437  iren_->SetInteractorStyle(style);
438  // style->Delete();
439  // iren_->Initialize();
440  // std::cerr << "interactor on... " << iren_->GetInitialized() << std::endl;
441  // iren_->Start();
442  // iren_->Enable();
443  // iren_->ReInitialize();
444  // iren_->Render();
445  // std::cerr << iren_->GetRenderWindow() << std::endl;
446  // std::cerr << renWin_ << std::endl;
447  // std::cerr << "+++" << std::endl;
448  // if (!spotlight_) iren_->LightFollowCameraOff();
449  // std::cerr << *iren_ << std::endl;
450  */ }
451 }
452 //---------------------------------------------------------------------------
453 void a_screen::point(const a_point& p)
454 {
455  this->point(p.x(),p.y(),p.z());
456 }
457 //---------------------------------------------------------------------------
458 void a_screen::point(double x, double y, double z)
459 {
460  active_layer_->point(x,y,z);
461  if (empty_)
462  {
463  if (one_point_)
464  {
465  renWin_->Render();
466  renWin_->SetWindowName("screen");
467  empty_ = false;
468  }
469  else
470  one_point_ = true;
471  }
472  else
473  renWin_->Render();
474  log_ << "window_name point " << x << " " << y << " " << z << " " << std::endl;
475 }
476 //---------------------------------------------------------------------------
477 void a_screen::line(const a_point& p1, const a_point& p2)
478 {
479  this->line(p1.x(),p1.y(),p1.z(),p2.x(),p2.y(),p2.z());
480 }
481 //---------------------------------------------------------------------------
482 void a_screen::line(double x1, double y1, double z1, double x2, double y2, double z2)
483 {
484  active_layer_->line(x1,y1,z1,x2,y2,z2);
485  if (empty_)
486  {
487  empty_ = false;
488  renWin_->Render();
489  renWin_->SetWindowName("screen");
490  }
491  else
492  renWin_->Render();
493  log_ << "window_name line " << x1 << " " << y1 << " " << z1 << " "
494  << x2 << " " << y2 << " " << z2 << " " << std::endl;
495 }
496 //---------------------------------------------------------------------------
497 void a_screen::vertex(const a_point& p)
498 {
499  this->vertex(p.x(),p.y(),p.z());
500 }
501 //---------------------------------------------------------------------------
502 void a_screen::vertex(double x, double y, double z)
503 {
504  active_layer_->vertex(x,y,z);
505  log_ << "window_name vertex " << x << " " << y << " " << z << " " << std::endl;
506 }
507 //---------------------------------------------------------------------------
509 {
511  if (empty_)
512  {
513  empty_ = false;
514  renWin_->Render();
515  renWin_->SetWindowName("screen");
516  }
517  else
518  renWin_->Render();
519  log_ << "window_name endpolyline" << std::endl;
520 }
521 //---------------------------------------------------------------------------
523 {
525  if (empty_)
526  {
527  empty_ = false;
528  renWin_->Render();
529  renWin_->SetWindowName("screen");
530  }
531  else
532  renWin_->Render();
533  log_ << "window_name closepolyline" << std::endl;
534 }
535 //---------------------------------------------------------------------------
536 void a_screen::point0(double x, double y, double z)
537 {
538  active_layer_->point(x,y,z);
539 }
540 //---------------------------------------------------------------------------
541 void a_screen::line0(double x1, double y1, double z1, double x2, double y2, double z2)
542 {
543  active_layer_->line(x1,y1,z1,x2,y2,z2);
544 }
545 //---------------------------------------------------------------------------
546 void a_screen::vertex0(double x, double y, double z)
547 {
548  active_layer_->vertex(x,y,z);
549 }
550 //---------------------------------------------------------------------------
552 {
554 }
555 //---------------------------------------------------------------------------
557 {
559 }
560 //---------------------------------------------------------------------------
561 void a_screen::surfacepoint(const a_point& p)
562 {
563  this->surfacepoint(p.x(),p.y(),p.z());
564 }
565 //---------------------------------------------------------------------------
566 void a_screen::surfacepoint(double x, double y, double z)
567 {
568  active_layer_->surfacepoint(x,y,z);
569  if (active_layer_->hassurface())
570  {
572  {
573  ren_->AddActor(active_layer_->surfaceactor());
574  if (empty_)
575  {
576  empty_ = false;
577  renWin_->Render();
578  renWin_->SetWindowName("screen");
579  return;
580  }
581  }
582  renWin_->Render();
583  }
584  log_ << "window_name surfacepoint " << x << " " << y << " " << z << std::endl;
585 }
586 //---------------------------------------------------------------------------
588 {
590  renWin_->Render();
591  log_ << "window_name erase point" << std::endl;
592 }
593 //---------------------------------------------------------------------------
595 {
597  renWin_->Render();
598  log_ << "window_name erase line" << std::endl;
599 }
600 //---------------------------------------------------------------------------
602 {
604  renWin_->Render();
605  log_ << "window_name erase polylineline" << std::endl;
606 }
607 //---------------------------------------------------------------------------
608 void a_screen::azimuth(double x)
609 {
610  this->unroll();
611  ren_->GetActiveCamera()->Azimuth(x0_-x);
612  x0_ = x;
614  this->render_clip();
615 }
616 //---------------------------------------------------------------------------
617 void a_screen::elevation(double y)
618 {
619  this->unroll();
620  ren_->GetActiveCamera()->Elevation(y0_-y);
621  y0_ = y;
623  this->render_clip();
624 }
625 //---------------------------------------------------------------------------
626 void a_screen::roll(double z)
627 {
628  ren_->GetActiveCamera()->Roll(z0_-z);
629  z0_ = z;
630  this->render_clip();
631 }
632 //---------------------------------------------------------------------------
633 void a_screen::pitch(double u)
634 {
635  this->unroll();
636  ren_->GetActiveCamera()->Pitch(u-y0_);
637  y0_ = u;
639  this->render_clip();
640 }
641 //---------------------------------------------------------------------------
642 void a_screen::yaw(double v)
643 {
644  this->unroll();
645  ren_->GetActiveCamera()->Yaw(x0_-v);
646  x0_ = v;
648  this->render_clip();
649 }
650 //---------------------------------------------------------------------------
652 {
653  if (z0_ != 0)
654  {
655  ren_->GetActiveCamera()->Roll(z0_);
656  z0_ = 0;
657  }
658 }
659 //---------------------------------------------------------------------------
660 void a_screen::distance(double d)
661 {
662  a_point fop = this->focalpoint();
663  a_point pop = this->viewpoint();
664  a_point pop2 = d*(pop-fop).normalise();
665  this->viewpoint(fop+pop2);
666  this->render_clip();
667 }
668 //---------------------------------------------------------------------------
669 double a_screen::distance() const
670 {
671  a_point fop = this->focalpoint();
672  a_point pop = this->viewpoint();
673  return (fop-pop).norm();
674 }
675 //---------------------------------------------------------------------------
676 void a_screen::distance0(double v)
677 {
678  a_bounding_box box;
679  for (auto la:layers_)
680  box(la);
681  // box = std::for_each(layers_.begin(),layers_.end(),box);
682  double d0 = box.d();
683  double d = 2*d0*exp(log(10)*v/100);
684  this->distance(d);
685 }
686 //---------------------------------------------------------------------------
687 void a_screen::background(double R, double G, double B)
688 {
689  if (R>=0 && R<=1 && G>=0 && G<=1 && B>=0 && B<=1)
690  {
691  ren_->SetBackground(R,G,B);
692  renWin_->Render();
693  }
694 }
695 //---------------------------------------------------------------------------
697 {
698  vtkCamera * cam = ren_->GetActiveCamera();
699  double pt[3];
700  cam->GetFocalPoint(pt);
701  log_ << "window_name setfocalpoint " << pt[0] << " " << pt[1] << " " << pt[2] << std::endl;
702  cam->GetPosition(pt);
703  log_ << "window_name setviewpoint " << pt[0] << " " << pt[1] << " " << pt[2] << std::endl;
704 }
705 //---------------------------------------------------------------------------
706 void a_screen::pan(const double * pt)
707 {
708  a_point move(pt);
709  if (move.norm() > 0.00001)
710  {
711  a_point vn = this->viewpoint()+move;
712  a_point fn = this->focalpoint()+move;
713  double vna[] = {vn.x(), vn.y(), vn.z()};
714  double fna[] = {fn.x(), fn.y(), fn.z()};
715  this->viewpoint(vna);
716  this->focalpoint(fna);
717  }
718 }
719 //---------------------------------------------------------------------------
720 a_point a_screen::viewpoint() const
721 {
722  vtkCamera * cam = ren_->GetActiveCamera();
723  double po[3];
724  cam->GetPosition(po);
725  return a_point(po);
726 }
727 //---------------------------------------------------------------------------
728 a_point a_screen::focalpoint() const
729 {
730  vtkCamera * cam = ren_->GetActiveCamera();
731  double fp[3];
732  cam->GetFocalPoint(fp);
733  return a_point(fp);
734 }
735 //---------------------------------------------------------------------------
736 void a_screen::viewpoint(const a_point& poo)
737 {
738  vtkCamera * cam = ren_->GetActiveCamera();
739  a_point fpo = this->focalpoint();
740  //view and focal points cannot coincide
741  if ((fpo-poo).norm() > 0.00001)
742  {
743  this->unroll();
744  cam->SetPosition(poo.x(),poo.y(),poo.z());
745  cam->ComputeViewPlaneNormal();
746  cam->SetViewAngle(30);
747  a_point n = (fpo-poo).normalise();
748  if ((n.x()>0)||(n.y()>0))
749  cam->SetViewUp(0,0,1);
750  else
751  cam->SetViewUp(1,0,0);
753  this->render_clip();
754  if (n.x() != 0)
755  x0_ = (180/3.14159265358979)*atan2(n.y(),n.x());
756  else
757  {
758  if (n.y()<0)
759  x0_ = -90;
760  else
761  x0_ = 90;
762  }
763  y0_ = 90-(180/3.14159265358979)*acos(n.z());
764  }
765 }
766 //---------------------------------------------------------------------------
767 void a_screen::focalpoint(const a_point& fpo)
768 {
769  vtkCamera * cam = ren_->GetActiveCamera();
770  a_point poo = this->viewpoint();
771  //view and focal points cannot coincide
772  if ((fpo-poo).norm() > 0.00001)
773  {
774  this->unroll();
775  cam->SetFocalPoint(fpo.x(),fpo.y(),fpo.z());
776  cam->ComputeViewPlaneNormal();
777  cam->SetViewAngle(30);
778  a_point n = (fpo-poo).normalise();
779  if ((n.x()>0)||(n.y()>0))
780  cam->SetViewUp(0,0,1);
781  else
782  cam->SetViewUp(1,0,0);
784  this->render_clip();
785  if (n.x() != 0)
786  x0_ = (180/3.14159265358979)*atan2(n.y(),n.x());
787  else
788  {
789  if (n.y()<0)
790  x0_ = -90;
791  else
792  x0_ = 90;
793  }
794  y0_ = 90-(180/3.14159265358979)*acos(n.z());
795  }
796 }
797 //---------------------------------------------------------------------------
798 void a_screen::viewpoint(const double * pt)
799 {
800  this->viewpoint(a_point(pt[0],pt[1],pt[2]));
801 }
802 //---------------------------------------------------------------------------
803 void a_screen::focalpoint(const double * pt)
804 {
805  this->focalpoint(a_point(pt[0],pt[1],pt[2]));
806 }
807 //---------------------------------------------------------------------------
808 void a_screen::dxfin(const std::string& file)
809 {
810  std::ifstream ff(file.c_str());
811  if (!ff) throw filenotfound_error();
812  a_dxf_group group(&ff);
813  //loop through entitities
814  a_dxf_point point(&ff);
815  a_dxf_line line(&ff);
816  a_dxf_polyline polyline(&ff);
817  a_dxf_entity entity(&ff);
818  std::string layer0 = "0";
819  while (group.read())
820  {
821  if (group.code() != 0) throw file_error();
822  //read entity
823  if (group.data_is("POINT"))
824  {
825  if (point.read())
826  {
827  if (point.layer() != layer0)
828  {
829  layer0 = point.layer();
830  newlayer(layer0);
831  setlayer(layer0);
832  }
833  this->point0(point.x(),point.y(),point.z());
834  }
835  }
836  else if (group.data_is("LINE"))
837  {
838  if (line.read())
839  {
840  if (line.layer() != layer0)
841  {
842  layer0 = line.layer();
843  newlayer(layer0);
844  setlayer(layer0);
845  }
846  this->line0(line.x1(),line.y1(),line.z1(),line.x2(),line.y2(),line.z2());
847  }
848  }
849  else if (group.data_is("POLYLINE"))
850  {
851  polyline.init();
852  if (polyline.read())
853  {
854  if (polyline.layer() != layer0)
855  {
856  layer0 = polyline.layer();
857  newlayer(layer0);
858  setlayer(layer0);
859  }
860  for (int i=0; i<polyline.n(); i++)
861  this->vertex0(polyline.x(i),polyline.y(i),polyline.z(i));
862  this->endpolyline0();
863  }
864  }
865  else entity.read();
866  }
867  ff.close();
868  if (empty_)
869  {
870  empty_ = false;
871  renWin_->Render();
872  renWin_->SetWindowName("screen");
873  }
874  else
875  renWin_->Render();
876  log_ << "window_name import dxf " << file << std::endl;
877 }
878 //---------------------------------------------------------------------------
879 void a_screen::dxfout(const std::string& file)
880 {
881  std::ofstream o(file.c_str());
882  if (!o)
883  {
884  output_ << "cannot create file '" << file << "'" << std::endl;
885  return;
886  }
887  //header
888  o << " 0" << std::endl << "SECTION" << std::endl;
889  o << " 2" << std::endl << "ENTITIES" << std::endl;
890  //body
891  for (auto la:layers_)
892  {
893  if (la->isvisible())
894  la->dxfout(o);
895  }
896  //footer
897  o << " 0" << std::endl << "ENDSEC" << std::endl;
898  o << " 0" << std::endl << "EOF" << std::endl;
899  o.close();
900  log_ << "window_name save dxf " << file << std::endl;
901 }
902 //---------------------------------------------------------------------------
903 void a_screen::ptin(const std::string& file)
904 {
905  std::ifstream ff(file.c_str());
906  if (!ff) throw filenotfound_error();
907  active_layer_->ptin(ff);
908  ff.close();
909  if (empty_)
910  {
911  empty_ = false;
912  renWin_->Render();
913  renWin_->SetWindowName("screen");
914  }
915  else
916  renWin_->Render();
917  log_ << "window_name import pt " << file << std::endl;
918 }
919 //---------------------------------------------------------------------------
920 void a_screen::ptout(const std::string& file)
921 {
922  std::ofstream o(file.c_str());
923  if (!o)
924  {
925  output_ << "cannot create file '" << file << "'" << std::endl;
926  return;
927  }
928  active_layer_->ptout(o);
929  o.close();
930  log_ << "window_name save pt " << file << std::endl;
931 }
932 //---------------------------------------------------------------------------
933 void a_screen::jpgout(const std::string& file)
934 {
935  std::string f0 = file.substr(0,file.find_first_of('.'))+".jpg";
936  vtkWindowToImageFilter * grab = vtkWindowToImageFilter::New();
937  grab->SetInput(renWin_);
938  vtkJPEGWriter * writer = vtkJPEGWriter::New();
939  writer->SetFileName(const_cast<char *>(f0.c_str()));
940  writer->SetInputConnection(grab->GetOutputPort());
941  writer->SetQuality(100);//between 0 and 100
942  grab->Delete();
943  writer->Write();
944  writer->Delete();
945  this->output_position();
946  log_ << "window_name save jpg " << file << std::endl;
947 }
948 //---------------------------------------------------------------------------
949 void a_screen::pngout(const std::string& file)
950 {
951  std::string f0 = file.substr(0,file.find_first_of('.'))+".png";
952  vtkRenderLargeImage * grab = vtkRenderLargeImage::New();
953  grab->SetInput(ren_);
954  vtkPNGWriter * writer = vtkPNGWriter::New();
955  writer->SetFileName(const_cast<char *>(f0.c_str()));
956  writer->SetInputConnection(grab->GetOutputPort());
957  grab->Delete();
958  writer->Write();
959  writer->Delete();
960  this->output_position();
961  log_ << "window_name save png " << file << std::endl;
962 }
963 //---------------------------------------------------------------------------
964 void a_screen::vrmlout(const std::string& file)
965 {
966  vtkVRMLExporter * writer = vtkVRMLExporter::New();
967  writer->SetFileName(file.c_str());
968  writer->SetInput(renWin_);
969  writer->Write();
970  writer->Delete();
971  log_ << "window_name save vrml " << file << std::endl;
972 }
973 //---------------------------------------------------------------------------
974 void a_screen::vtkout(const std::string& file)
975 {
976  vtkAppendPolyData * datas = vtkAppendPolyData::New();
977  for (auto la:layers_)
978  {
979  datas->AddInputData(la->polydata());
980  datas->AddInputData(la->polydata2());
981  }
982  vtkPolyDataWriter * writer = vtkPolyDataWriter::New();
983  writer->SetFileName(file.c_str());
984  writer->SetInputConnection(datas->GetOutputPort());
985  datas->Delete();
986  writer->Write();
987  writer->Delete();
988  log_ << "window_name save vtk " << file << std::endl;
989 }
990 //---------------------------------------------------------------------------
991 void a_screen::ribout(const std::string& file)
992 {
993  std::string f0 = file.substr(0,file.find_first_of('.'));
994  vtkRIBExporter * writer = vtkRIBExporter::New();
995  writer->SetFilePrefix(f0.c_str());
996  writer->SetInput(renWin_);
997  writer->Write();
998  writer->Delete();
999  this->output_position();
1000  log_ << "window_name save rib " << file << std::endl;
1001 }
1002 //---------------------------------------------------------------------------
1003 void a_screen::tifout(const std::string& file)
1004 {
1005  std::string f0 = file.substr(0,file.find_first_of('.'))+".tif";
1006  vtkWindowToImageFilter * grab = vtkWindowToImageFilter::New();
1007  grab->SetInput(renWin_);
1008  vtkTIFFWriter * writer = vtkTIFFWriter::New();
1009  writer->SetFileName(const_cast<char *>(f0.c_str()));
1010  writer->SetInputConnection(grab->GetOutputPort());
1011  grab->Delete();
1012  writer->Write();
1013  writer->Delete();
1014  this->output_position();
1015  log_ << "window_name save tiff " << file << std::endl;
1016 }
1017 //---------------------------------------------------------------------------
1019 {
1020  ren_->GetActiveCamera()->SetClippingRange(clip_[0],clip_[1]);
1021  renWin_->Render();
1022 }
1023 //---------------------------------------------------------------------------
1025 {
1026  a_bounding_box box;
1027  for (auto la:layers_)
1028  box(la);
1029  // box = std::for_each(layers_.begin(),layers_.end(),box);
1030  double fo[3];
1031  for (int i = 0; i < 3; i++) fo[i] = box.m(i);
1032  double d0 = box.d();
1033  vtkCamera * cam = ren_->GetActiveCamera();
1034  cam->SetFocalPoint(fo);
1035  cam->SetPosition(fo[0],fo[1]-2*d0,fo[2]);
1036  cam->ComputeViewPlaneNormal();
1037  cam->SetViewAngle(30);
1038  cam->SetViewUp(0,0,1);
1039  this->render_clip();
1040  this->spotlight();
1041  x0_ = y0_ = z0_ = 0;
1042 }
1043 //---------------------------------------------------------------------------
1045 {
1046  double po[3], fo[3];
1047  vtkCamera * cam = ren_->GetActiveCamera();
1048  cam->GetPosition(po);
1049  cam->GetFocalPoint(fo);
1050  vtkLightCollection * lights = ren_->GetLights();
1051  lights->InitTraversal();
1052  vtkLight * light = lights->GetNextItem();
1053  light->SetPosition(po);
1054  light->SetFocalPoint(fo);
1055  light->SetIntensity(1);
1056 }
1057 //*input/output*************************************************
1058 //-operator>>----------------------------------------------------------------
1059 std::istream& operator>> (std::istream& i, a_screen& w)
1060 {
1062  int n_layers;
1063  i >> n_layers;
1064  a_screenlayer * la0;
1065  for (int k = 0; k < n_layers; k++)
1066  {
1067  auto la = new a_screenlayer;
1068  la->reset();
1069  i >> *la;
1070  if (k==0)
1071  la0 = la;
1072  w.layers_.push_back(la);
1073  w.ren_->AddActor(la->actor());
1074  w.ren_->AddActor(la->actor2());
1075  }
1076  w.active_layer_ = la0;
1077  return i;
1078 }
1079 //-operator<<----------------------------------------------------------------
1080 std::ostream& operator<< (std::ostream& o, a_screen& w)
1081 {
1082  o << w.layers_.size() << std::endl;
1083  for (auto la:w.layers_)
1084  o << *la;
1085  return o;
1086 }
1087 //---------------------------------------------------------------------------
1088 void a_screen::open(const std::string& file)
1089 {
1090  std::ifstream ff(file.c_str());
1091  if (ff)
1092  {
1093  ff >> *this;
1094  renWin_->Render();
1095  renWin_->SetWindowName("screen");
1096  log_ << "window_name open " << file << std::endl;
1097  }
1098 }
1099 //---------------------------------------------------------------------------
1100 void a_screen::save(const std::string& file)
1101 {
1102  std::ofstream ff(file.c_str());
1103  if (ff)
1104  {
1105  ff << *this;
1106  log_ << "window_name save " << file << std::endl;
1107  }
1108 }
void delete_vector(std::vector< a_axes * > &)
std::istream & operator>>(std::istream &i, a_screen &w)
Definition: a_screen.cxx:1059
std::ostream & operator<<(std::ostream &o, a_screen &w)
Definition: a_screen.cxx:1080
a_mat_sq x2(3)
double m(const char) const
void operator()(a_element *)
Definition: a_canvas.cxx:276
double d() const
a generic interactor
Definition: a_interactor.h:29
void name(const std::string &name)
Definition: a_interactor.h:39
static a_interactor * New()
void keep_color(const bool val=true)
Definition: a_interactor.h:41
a vtk screen
Definition: a_screen.h:38
virtual void eraselayer(const std::string &s)
Definition: a_screen.cxx:315
void reset()
Definition: a_screen.cxx:1024
double roll() const
Definition: a_screen.h:117
double B() const
Definition: a_screen.h:68
void closepolyline()
Definition: a_screen.cxx:522
void point(const a_point &p)
Definition: a_screen.cxx:453
static const std::string help()
Definition: a_screen.cxx:49
double z0_
Definition: a_screen.h:173
void endpolyline0()
Definition: a_screen.cxx:551
void output_position()
Definition: a_screen.cxx:696
std::vector< a_screenlayer * > layers_
Definition: a_screen.h:162
float clip_[2]
Definition: a_screen.h:175
void vertex0(double x, double y, double z)
Definition: a_screen.cxx:546
void eraselastline()
Definition: a_screen.cxx:594
void distance0(double d)
Definition: a_screen.cxx:676
void vrmlout(const std::string &file)
Definition: a_screen.cxx:964
double x0_
Definition: a_screen.h:169
void render_clip()
Definition: a_screen.cxx:1018
a_point viewpoint() const
Definition: a_screen.cxx:720
void pitch(double u)
Definition: a_screen.cxx:633
void endpolyline()
Definition: a_screen.cxx:508
void jpgout(const std::string &file)
Definition: a_screen.cxx:933
void setofflayer(const std::string &s)
Definition: a_screen.cxx:340
void point0(double x, double y, double z)
Definition: a_screen.cxx:536
const std::string getlayer() const
Definition: a_screen.cxx:358
double R() const
Definition: a_screen.h:66
void pan(const double *pt)
Definition: a_screen.cxx:706
void setonlayer(const std::string &s)
Definition: a_screen.cxx:349
void line(const a_point &p1, const a_point &p2)
Definition: a_screen.cxx:477
void line0(double x1, double y1, double z1, double x2, double y2, double z2)
Definition: a_screen.cxx:541
void color(float r, float g, float b)
Definition: a_screen.cxx:363
void tifout(const std::string &file)
Definition: a_screen.cxx:1003
a_text output_
Definition: a_screen.h:178
void eraselastpoint()
Definition: a_screen.cxx:587
virtual void newlayer(const std::string &s)
Definition: a_screen.cxx:245
void closepolyline0()
Definition: a_screen.cxx:556
void ptout(const std::string &file)
Definition: a_screen.cxx:920
double G() const
Definition: a_screen.h:67
double y0_
Definition: a_screen.h:171
double azimuth() const
Definition: a_screen.h:115
void save(const std::string &file)
Definition: a_screen.cxx:1100
bool empty_
Definition: a_screen.h:182
vtkRenderWindowInteractor * iren_
Definition: a_screen.h:166
double distance() const
Definition: a_screen.cxx:669
a_point focalpoint() const
Definition: a_screen.cxx:728
void setlightoncameraposition()
Definition: a_screen.cxx:1044
virtual void interact()
Definition: a_screen.cxx:417
bool one_point_
Definition: a_screen.h:183
void vertex(const a_point &p)
Definition: a_screen.cxx:497
bool existlayer(const std::string &s) const
Definition: a_screen.cxx:222
void ribout(const std::string &file)
Definition: a_screen.cxx:991
virtual void setlayer(const std::string &s)
Definition: a_screen.cxx:306
void sunlight()
Definition: a_screen.cxx:391
a_text log_
Definition: a_screen.h:180
void open(const std::string &file)
Definition: a_screen.cxx:1088
a_screenlayer * active_layer_
Definition: a_screen.h:163
vtkRenderer * ren_
Definition: a_screen.h:164
void dxfin(const std::string &file)
Definition: a_screen.cxx:808
void pngout(const std::string &file)
Definition: a_screen.cxx:949
void yaw(double v)
Definition: a_screen.cxx:642
void dxfout(const std::string &file)
Definition: a_screen.cxx:879
void spotlight()
Definition: a_screen.cxx:380
void background(double R, double G, double B)
Definition: a_screen.cxx:687
void unroll()
Definition: a_screen.cxx:651
void ptin(const std::string &file)
Definition: a_screen.cxx:903
void vtkout(const std::string &file)
Definition: a_screen.cxx:974
void surfacepoint(const a_point &p)
Definition: a_screen.cxx:561
void eraselastpolyline()
Definition: a_screen.cxx:601
vtkRenderWindow * renWin_
Definition: a_screen.h:165
std::string listlayers()
Definition: a_screen.cxx:295
void perspectia_view()
Definition: a_screen.cxx:410
bool spotlight_
Definition: a_screen.h:176
int thickness() const
Definition: a_screen.h:70
double elevation() const
Definition: a_screen.h:116
void parallel_view()
Definition: a_screen.cxx:403
layer used by screen to draw vector graphics
Definition: a_screenlayer.h:31
bool hassurface()
Definition: a_screenlayer.h:65
void eraselastpolyline()
void append(const a_screenlayer &)
void surfacepoint(double x, double y, double z)
vtkActor * actor2()
Definition: a_screenlayer.h:50
void name(std::string aname)
Definition: a_screenlayer.h:36
void color(float r, float g, float b)
void vertex(double x, double y, double z)
vtkActor * surfaceactor()
Definition: a_screenlayer.h:51
void line(double x1, double y1, double z1, double x2, double y2, double z2)
void thickness(const int)
bool empty() const
Definition: a_screenlayer.h:38
void visibility(const int code)
Definition: a_screenlayer.h:73
bool surfaceready()
Definition: a_screenlayer.h:66
void ptout(std::ostream &o) const
void point(double x, double y, double z)
vtkActor * actor()
Definition: a_screenlayer.h:49
void ptin(std::istream &in)
double v(const uint32_t step, const uint32_t n)
Definition: generate.cxx:42
uint32_t n[]
Definition: generate.cxx:34
Definition: stlb2stla.cxx:21