TBTK
RayTracer.h
Go to the documentation of this file.
1 /* Copyright 2017 Kristofer Bj√∂rnson
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
23 #ifndef COM_DAFER45_TBTK_RAY_TRACER
24 #define COM_DAFER45_TBTK_RAY_TRACER
25 
26 #include "TBTK/FieldWrapper.h"
27 #include "TBTK/Model.h"
28 #include "TBTK/Property/Density.h"
29 #include "TBTK/Property/LDOS.h"
32 #include "TBTK/TBTKMacros.h"
33 #include "TBTK/Vector3d.h"
34 
35 #include <functional>
36 #include <initializer_list>
37 
38 #include <opencv2/core/core.hpp>
39 #include <opencv2/highgui/highgui.hpp>
40 
41 namespace TBTK{
42 
43 class RayTracer{
44 public:
46  RayTracer();
47 
49  RayTracer(const RayTracer &rayTracer);
50 
52  RayTracer(RayTracer &&rayTracer);
53 
55  ~RayTracer();
56 
58  RayTracer& operator=(const RayTracer &rhs);
59 
62 
64  void setCameraPosition(const Vector3d &cameraPosition);
65 
67  void setCameraPosition(std::initializer_list<double> cameraPosition);
68 
70  void setFocus(const Vector3d &focus);
71 
73  void setFocus(std::initializer_list<double> focus);
74 
76  void setUp(const Vector3d &up);
77 
79  void setUp(std::initializer_list<double> up);
80 
82  void setWidth(unsigned int width);
83 
85  void setHeight(unsigned int height);
86 
88  void setStateRadius(double stateRadius);
89 
91  void setNumDeflections(unsigned int numDeflections);
92 
94  unsigned int getNumDeflections() const;
95 
97  void setRayLength(double rayLength);
98 
100  double getRayLength() const;
101 
103  void setNumRaySegments(unsigned int numRaySegments);
104 
106  unsigned int getNumRaySegments() const;
107 
109  void plot(const Model& model, const Property::Density &density);
110 
112  void plot(
113  const Model &model,
114  const Property::Magnetization &magnetization
115  );
116 
118  void plot(
119  const Model &model,
120  const Property::WaveFunctions &waveFunctions,
121  unsigned int state
122  );
123 
125  void plot(
126  Field<std::complex<double>, double> &field
127  );
128 
130  void plot(
131  const std::vector<const FieldWrapper*> &fields
132  );
133 
135  void interactivePlot(
136  const Model &model,
137  const Property::LDOS &ldos,
138  double sigma = 0,
139  unsigned int windowSize = 51
140  );
141 
143  void save(std::string filename);
144 private:
146  class Color{
147  public:
148  double r, g, b;
149  };
150 
152  class Material{
153  public:
155  Material();
156 
158  Color color;
159 
161  double ambient, diffusive, emissive, specular;
162 
164  static constexpr double DEFAULT_AMBIENT = 1;
165  static constexpr double DEFAULT_DIFFUSIVE = 0.5;
166  static constexpr double DEFAULT_EMISSIVE = 0;
167  static constexpr double DEFAULT_SPECULAR = 0.1;
168  };
169 
171  class RenderContext{
172  public:
174  RenderContext();
175 
177  ~RenderContext();
178 
180  void setCameraPosition(const Vector3d &cameraPosition);
181 
183  void setCameraPosition(std::initializer_list<double> cameraPosition);
184 
186  const Vector3d& getCameraPosition() const;
187 
189  void setFocus(const Vector3d &focus);
190 
192  void setFocus(std::initializer_list<double> focus);
193 
195  const Vector3d& getFocus() const;
196 
198  void setUp(const Vector3d &up);
199 
201  void setUp(std::initializer_list<double> up);
202 
204  const Vector3d& getUp() const;
205 
207  void setWidth(unsigned int width);
208 
210  unsigned int getWidth() const;
211 
213  void setHeight(unsigned int height);
214 
216  unsigned int getHeight() const;
217 
219  void setStateRadius(double stateRadius);
220 
222  double getStateRadius() const;
223 
225  void setNumDeflections(unsigned int numDeflections);
226 
227  /*** Get number of deflections. */
228  unsigned int getNumDeflections() const;
229 
231  void setRayLength(double rayLength);
232 
234  double getRayLength() const;
235 
237  void setNumRaySegments(unsigned int numRaySegments);
238 
240  unsigned int getNumRaySegments() const;
241  private:
243  Vector3d cameraPosition;
244 
246  Vector3d focus;
247 
249  Vector3d up;
250 
252  double width;
253 
255  double height;
256 
258  double stateRadius;
259 
262  unsigned int numDeflections;
263 
265  double rayLength;
266 
268  unsigned int numRaySegments;
269  };
270 
271  RenderContext renderContext;
272 
274  class HitDescriptor{
275  public:
277  HitDescriptor(const RenderContext &renderContext);
278 
280  HitDescriptor(const HitDescriptor &hitDescriptor);
281 
283  HitDescriptor(HitDescriptor &&hitDescriptor);
284 
286  ~HitDescriptor();
287 
289  HitDescriptor& operator=(const HitDescriptor &rhs);
290 
292  HitDescriptor& operator=(HitDescriptor &&rhs);
293 
295  void setRaySource(const Vector3d &raySource);
296 
298  const Vector3d& getRaySource() const;
299 
301  void setRayDirection(const Vector3d &rayDirection);
302 
304  const Vector3d& getRayDirection() const;
305 
307  void setIndex(const Index &index);
308 
310  const Index& getIndex() const;
311 
313  void setCoordinate(const Vector3d coordainte);
314 
316  const Vector3d& getCoordinate() const;
317 
319  const Vector3d& getDirectionFromObject();
320 
322  const Vector3d& getImpactPosition();
323  private:
325  const RenderContext *renderContext;
326 
328  Vector3d raySource;
329 
331  Vector3d rayDirection;
332 
334  Index index;
335 
337  Vector3d coordinate;
338 
340  Vector3d *directionFromObject;
341 
343  Vector3d *impactPosition;
344  };
345 
346  class RenderResult{
347  public:
349  RenderResult(unsigned int width, unsigned int height);
350 
352  RenderResult(const RenderResult &renderResult);
353 
355  RenderResult(RenderResult &&renderResult);
356 
358  ~RenderResult();
359 
361  RenderResult& operator=(const RenderResult &rhs);
362 
364  RenderResult& operator=(RenderResult &&rhs);
365 
367  cv::Mat& getCanvas();
368 
370  const cv::Mat& getCanvas() const;
371 
373  std::vector<HitDescriptor>** getHitDescriptors();
374  private:
376  unsigned int width, height;
377 
379  cv::Mat canvas;
380 
383  std::vector<HitDescriptor> **hitDescriptors;
384  };
385 
386  RenderResult *renderResult;
387 
389  void render(
390  const IndexDescriptor &indexDescriptor,
391  const Model &model,
392  const std::vector<const FieldWrapper*> &fields,
393  std::function<Material(HitDescriptor &hitDescriptor)> &&lambdaColorPicker,
394  std::function<void(cv::Mat &canvas, const Index &index)> &&lambdaInteractive = {}
395  );
396 
398  Color trace(
399  const std::vector<Vector3d> &coordinates,
400  const Vector3d &raySource,
401  const Vector3d &rayDirection,
402  const IndexTree &indexTree,
403  const std::vector<const FieldWrapper*> &fields,
404  std::vector<HitDescriptor> &hitDescriptors,
405  std::function<Material(HitDescriptor &hitDescriptor)> lambdaColorPicker,
406  unsigned int deflections = 0
407  );
408 
410  Color traceFields(
411  const std::vector<const FieldWrapper*> &fields,
412  const Vector3d &raySource,
413  const Vector3d &rayDirection
414  );
415 
417  cv::Mat getCharImage() const;
418 
420  class EventHandler{
421  public:
423  static bool lock(
424  RayTracer *owner,
425  std::function<void(
426  int event,
427  int x,
428  int y,
429  int flags,
430  void *userData
431  )> &&lambdaOnMouseChange
432  );
433 
435  static bool unlock(const RayTracer *owner);
436 
438  static void onMouseChange(
439  int event,
440  int x,
441  int y,
442  int flags,
443  void *userdata
444  );
445  private:
447  static bool isLocked;
448 
450  static RayTracer *owner;
451 
453  static std::function<void(int event, int x, int y, int flags, void *userData)> &&lambdaOnMouseChange;
454  };
455 };
456 
457 inline void RayTracer::setCameraPosition(const Vector3d &cameraPosition){
458  renderContext.setCameraPosition(cameraPosition);
459 }
460 
462  std::initializer_list<double> cameraPosition
463 ){
464  renderContext.setCameraPosition(cameraPosition);
465 }
466 
467 inline void RayTracer::setFocus(const Vector3d &focus){
468  renderContext.setFocus(focus);
469 }
470 
471 inline void RayTracer::setFocus(std::initializer_list<double> focus){
472  renderContext.setFocus(focus);
473 }
474 
475 inline void RayTracer::setUp(const Vector3d &up){
476  renderContext.setUp(up);
477 }
478 
479 inline void RayTracer::setWidth(unsigned int width){
480  renderContext.setWidth(width);
481 }
482 
483 inline void RayTracer::setHeight(unsigned int height){
484  renderContext.setHeight(height);
485 }
486 
487 inline void RayTracer::setUp(std::initializer_list<double> up){
488  renderContext.setUp(up);
489 }
490 
491 inline void RayTracer::setStateRadius(double stateRadius){
492  renderContext.setStateRadius(stateRadius);
493 }
494 
495 inline void RayTracer::setNumDeflections(unsigned int numDeflections){
496  renderContext.setNumDeflections(numDeflections);
497 }
498 
499 inline unsigned int RayTracer::getNumDeflections() const{
500  return renderContext.getNumDeflections();
501 }
502 
503 inline void RayTracer::setRayLength(double rayLength){
504  renderContext.setRayLength(rayLength);
505 }
506 
507 inline double RayTracer::getRayLength() const{
508  return renderContext.getRayLength();
509 }
510 
511 inline void RayTracer::setNumRaySegments(unsigned int numRaySegments){
512  renderContext.setNumRaySegments(numRaySegments);
513 }
514 
515 inline unsigned int RayTracer::getNumRaySegments() const{
516  return renderContext.getNumRaySegments();
517 }
518 
519 /*inline RayTracer::RenderResult::RenderResult(
520  unsigned int width,
521  unsigned int height
522 ){
523  this->width = width;
524  this->height = height;
525 
526  canvas = cv::Mat(height, width, CV_32FC3);
527 
528  hitDescriptors = new std::vector<HitDescriptor>*[width];
529  for(unsigned int x = 0; x < width; x++)
530  hitDescriptors[x] = new std::vector<HitDescriptor>[height];
531 }
532 
533 inline RayTracer::RenderResult::~RenderResult(){
534  for(unsigned int x = 0; x < width; x++)
535  delete [] hitDescriptors[x];
536  delete [] hitDescriptors;
537 }*/
538 
539 inline cv::Mat& RayTracer::RenderResult::getCanvas(){
540  return canvas;
541 }
542 
543 inline const cv::Mat& RayTracer::RenderResult::getCanvas() const{
544  return canvas;
545 }
546 
547 inline std::vector<RayTracer::HitDescriptor>** RayTracer::RenderResult::getHitDescriptors(){
548  return hitDescriptors;
549 }
550 
551 inline RayTracer::Material::Material(){
552  color.r = 0;
553  color.g = 0;
554  color.b = 0;
555  ambient = DEFAULT_AMBIENT;
556  diffusive = DEFAULT_AMBIENT;
557  emissive = DEFAULT_EMISSIVE;
558  specular = DEFAULT_SPECULAR;
559 }
560 
561 inline void RayTracer::RenderContext::setCameraPosition(
562  const Vector3d &cameraPosition
563 ){
564  this->cameraPosition = cameraPosition;
565 }
566 
567 inline void RayTracer::RenderContext::setCameraPosition(
568  std::initializer_list<double> cameraPosition
569 ){
570  TBTKAssert(
571  cameraPosition.size() == 3,
572  "RayTracer::setCameraPosition()",
573  "Camera position can only have three coordinates.",
574  ""
575  );
576 
577  this->cameraPosition.x = *(cameraPosition.begin() + 0);
578  this->cameraPosition.y = *(cameraPosition.begin() + 1);
579  this->cameraPosition.z = *(cameraPosition.begin() + 2);
580 }
581 
582 inline const Vector3d& RayTracer::RenderContext::getCameraPosition() const{
583  return cameraPosition;
584 }
585 
586 inline void RayTracer::RenderContext::setFocus(const Vector3d &focus){
587  this->focus = focus;
588 }
589 
590 inline void RayTracer::RenderContext::setFocus(
591  std::initializer_list<double> focus
592 ){
593  TBTKAssert(
594  focus.size() == 3,
595  "RayTracer::setFocus()",
596  "Focus can only have three coordinates.",
597  ""
598  );
599 
600  this->focus.x = *(focus.begin() + 0);
601  this->focus.y = *(focus.begin() + 1);
602  this->focus.z = *(focus.begin() + 2);
603 }
604 
605 inline const Vector3d& RayTracer::RenderContext::getFocus() const{
606  return focus;
607 }
608 
609 inline void RayTracer::RenderContext::setUp(const Vector3d &up){
610  this->up = up;
611 }
612 
613 inline void RayTracer::RenderContext::setUp(
614  std::initializer_list<double> up
615 ){
616  TBTKAssert(
617  up.size() == 3,
618  "RayTracer::setCameraPosition()",
619  "Camera position can only have three coordinates.",
620  ""
621  );
622 
623  this->up.x = *(up.begin() + 0);
624  this->up.y = *(up.begin() + 1);
625  this->up.z = *(up.begin() + 2);
626 }
627 
628 inline const Vector3d& RayTracer::RenderContext::getUp() const{
629  return up;
630 }
631 
632 inline void RayTracer::RenderContext::setWidth(unsigned int width){
633  this->width = width;
634 }
635 
636 inline unsigned int RayTracer::RenderContext::getWidth() const{
637  return width;
638 }
639 
640 inline void RayTracer::RenderContext::setHeight(unsigned int height){
641  this->height = height;
642 }
643 
644 inline unsigned int RayTracer::RenderContext::getHeight() const{
645  return height;
646 }
647 
648 inline void RayTracer::RenderContext::setStateRadius(double stateRadius){
649  this->stateRadius = stateRadius;
650 }
651 
652 inline double RayTracer::RenderContext::getStateRadius() const{
653  return stateRadius;
654 }
655 
656 inline void RayTracer::RenderContext::setNumDeflections(
657  unsigned int numDeflections
658 ){
659  this->numDeflections = numDeflections;
660 }
661 
662 inline unsigned int RayTracer::RenderContext::getNumDeflections() const{
663  return numDeflections;
664 }
665 
666 inline void RayTracer::RenderContext::setRayLength(double rayLength){
667  this->rayLength = rayLength;
668 }
669 
670 inline double RayTracer::RenderContext::getRayLength() const{
671  return rayLength;
672 }
673 
674 inline void RayTracer::RenderContext::setNumRaySegments(
675  unsigned int numRaySegments
676 ){
677  this->numRaySegments = numRaySegments;
678 }
679 
680 inline unsigned int RayTracer::RenderContext::getNumRaySegments() const{
681  return numRaySegments;
682 }
683 
684 inline void RayTracer::HitDescriptor::setRaySource(
685  const Vector3d &raySource
686 ){
687  this->raySource = raySource;
688 }
689 
690 inline const Vector3d& RayTracer::HitDescriptor::getRaySource() const{
691  return this->raySource;
692 }
693 
694 inline void RayTracer::HitDescriptor::setRayDirection(
695  const Vector3d &rayDirection
696 ){
697  this->rayDirection = rayDirection;
698 }
699 
700 inline const Vector3d& RayTracer::HitDescriptor::getRayDirection() const{
701  return this->rayDirection;
702 }
703 
704 inline void RayTracer::HitDescriptor::setIndex(const Index &index){
705  this->index = index;
706 }
707 
708 inline const Index& RayTracer::HitDescriptor::getIndex() const{
709  return index;
710 }
711 
712 inline void RayTracer::HitDescriptor::setCoordinate(const Vector3d coordinate){
713  this->coordinate = coordinate;
714 }
715 
716 inline const Vector3d& RayTracer::HitDescriptor::getCoordinate() const{
717  return coordinate;
718 }
719 
720 inline bool RayTracer::EventHandler::lock(
721  RayTracer *owner,
722  std::function<void(
723  int event,
724  int x,
725  int y,
726  int flags,
727  void *userData
728  )> &&lambdaOnMouseChange
729 ){
730  if(isLocked){
731  return false;
732  }
733  else{
734  isLocked = true;
735  EventHandler::owner = owner;
736  EventHandler::lambdaOnMouseChange = lambdaOnMouseChange;
737  return true;
738  }
739 }
740 
741 inline bool RayTracer::EventHandler::unlock(const RayTracer *owner){
742  if(EventHandler::owner == owner){
743  EventHandler::owner = nullptr;
744  EventHandler::isLocked = false;
745  EventHandler::lambdaOnMouseChange = nullptr;
746  return true;
747  }
748  else{
749  return false;
750  }
751 }
752 
753 inline void RayTracer::EventHandler::onMouseChange(
754  int event,
755  int x,
756  int y,
757  int flags,
758  void *userData
759 ){
760  if(lambdaOnMouseChange){
761  lambdaOnMouseChange(event, x, y, flags, userData);
762  }
763  else{
764  TBTKExit(
765  "RayTracer::EventHandler::onMouseChange()",
766  "lambdaOnMouseChange is nullptr.",
767  "This should never happen, contact the developer."
768  );
769  }
770 }
771 
772 }; //End namespace TBTK
773 
774 #endif
void setNumDeflections(unsigned int numDeflections)
Definition: RayTracer.h:495
Property container for local density of states (LDOS).
Definition: LDOS.h:33
void setFocus(const Vector3d &focus)
Definition: RayTracer.h:467
Describes the index structure of data stored for several indices.
Definition: IndexDescriptor.h:33
Property container for magnetization.
Definition: Magnetization.h:35
void setWidth(unsigned int width)
Definition: RayTracer.h:479
void setNumRaySegments(unsigned int numRaySegments)
Definition: RayTracer.h:511
Precompiler macros.
unsigned int getNumDeflections() const
Definition: RayTracer.h:499
Property container for local density of states (LDOS).
Container of Model related information.
Three-dimensional vector with components of double type.
RayTracer & operator=(const RayTracer &rhs)
unsigned int getNumRaySegments() const
Definition: RayTracer.h:515
void interactivePlot(const Model &model, const Property::LDOS &ldos, double sigma=0, unsigned int windowSize=51)
void setUp(const Vector3d &up)
Definition: RayTracer.h:475
void setRayLength(double rayLength)
Definition: RayTracer.h:503
Property container for density.
void setStateRadius(double stateRadius)
Definition: RayTracer.h:491
Definition: Field.h:34
Property container for magnetization.
Data structure for mapping physical indices to a linear index.
Definition: IndexTree.h:34
Flexible physical index.
Definition: Index.h:70
Definition: Vector3d.h:33
Definition: ModelFactory.h:35
Property container for wave function.
Definition: WaveFunctions.h:34
Property container for density.
Definition: Density.h:33
void save(std::string filename)
void setCameraPosition(const Vector3d &cameraPosition)
Definition: RayTracer.h:457
Property container for wave functions.
void setHeight(unsigned int height)
Definition: RayTracer.h:483
Definition: RayTracer.h:43
Container of Model related information.
Definition: Model.h:52
void plot(const Model &model, const Property::Density &density)
double getRayLength() const
Definition: RayTracer.h:507