TBTK
Need a break? Support the development by playing Polarity Puzzles
RayTracer.h
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 
17 
24 #ifndef COM_DAFER45_TBTK_RAY_TRACER
25 #define COM_DAFER45_TBTK_RAY_TRACER
26 
27 #include "TBTK/FieldWrapper.h"
28 #include "TBTK/Model.h"
29 #include "TBTK/Property/Density.h"
30 #include "TBTK/Property/LDOS.h"
33 #include "TBTK/TBTKMacros.h"
34 #include "TBTK/Vector3d.h"
35 
36 #include <functional>
37 #include <initializer_list>
38 
39 #include <opencv2/core/core.hpp>
40 #include <opencv2/highgui/highgui.hpp>
41 
42 namespace TBTK{
43 
44 class RayTracer{
45 public:
47  RayTracer();
48 
50  RayTracer(const RayTracer &rayTracer);
51 
53  RayTracer(RayTracer &&rayTracer);
54 
56  ~RayTracer();
57 
59  RayTracer& operator=(const RayTracer &rhs);
60 
62  RayTracer& operator=(RayTracer &&rhs);
63 
65  void setCameraPosition(const Vector3d &cameraPosition);
66 
68  void setCameraPosition(std::initializer_list<double> cameraPosition);
69 
71  void setFocus(const Vector3d &focus);
72 
74  void setFocus(std::initializer_list<double> focus);
75 
77  void setUp(const Vector3d &up);
78 
80  void setUp(std::initializer_list<double> up);
81 
83  void setWidth(unsigned int width);
84 
86  void setHeight(unsigned int height);
87 
89  void setStateRadius(double stateRadius);
90 
92  void setNumDeflections(unsigned int numDeflections);
93 
95  unsigned int getNumDeflections() const;
96 
98  void setRayLength(double rayLength);
99 
101  double getRayLength() const;
102 
104  void setNumRaySegments(unsigned int numRaySegments);
105 
107  unsigned int getNumRaySegments() const;
108 
110  void plot(const Model& model, const Property::Density &density);
111 
113  void plot(
114  const Model &model,
115  const Property::Magnetization &magnetization
116  );
117 
119  void plot(
120  const Model &model,
121  const Property::WaveFunctions &waveFunctions,
122  unsigned int state
123  );
124 
126  void plot(
127  Field<std::complex<double>, double> &field
128  );
129 
131  void plot(
132  const std::vector<const FieldWrapper*> &fields
133  );
134 
136  void interactivePlot(
137  const Model &model,
138  const Property::LDOS &ldos,
139  double sigma = 0,
140  unsigned int windowSize = 51
141  );
142 
144  void save(std::string filename);
145 private:
147  class Color{
148  public:
149  double r, g, b;
150  };
151 
153  class Material{
154  public:
156  Material();
157 
159  Color color;
160 
162  double ambient, diffusive, emissive, specular;
163 
165  static constexpr double DEFAULT_AMBIENT = 1;
166  static constexpr double DEFAULT_DIFFUSIVE = 0.5;
167  static constexpr double DEFAULT_EMISSIVE = 0;
168  static constexpr double DEFAULT_SPECULAR = 0.1;
169  };
170 
172  class RenderContext{
173  public:
175  RenderContext();
176 
178  ~RenderContext();
179 
181  void setCameraPosition(const Vector3d &cameraPosition);
182 
184  void setCameraPosition(std::initializer_list<double> cameraPosition);
185 
187  const Vector3d& getCameraPosition() const;
188 
190  void setFocus(const Vector3d &focus);
191 
193  void setFocus(std::initializer_list<double> focus);
194 
196  const Vector3d& getFocus() const;
197 
199  void setUp(const Vector3d &up);
200 
202  void setUp(std::initializer_list<double> up);
203 
205  const Vector3d& getUp() const;
206 
208  void setWidth(unsigned int width);
209 
211  unsigned int getWidth() const;
212 
214  void setHeight(unsigned int height);
215 
217  unsigned int getHeight() const;
218 
220  void setStateRadius(double stateRadius);
221 
223  double getStateRadius() const;
224 
226  void setNumDeflections(unsigned int numDeflections);
227 
228  /*** Get number of deflections. */
229  unsigned int getNumDeflections() const;
230 
232  void setRayLength(double rayLength);
233 
235  double getRayLength() const;
236 
238  void setNumRaySegments(unsigned int numRaySegments);
239 
241  unsigned int getNumRaySegments() const;
242  private:
244  Vector3d cameraPosition;
245 
247  Vector3d focus;
248 
250  Vector3d up;
251 
253  double width;
254 
256  double height;
257 
259  double stateRadius;
260 
263  unsigned int numDeflections;
264 
266  double rayLength;
267 
269  unsigned int numRaySegments;
270  };
271 
272  RenderContext renderContext;
273 
275  class HitDescriptor{
276  public:
278  HitDescriptor(const RenderContext &renderContext);
279 
281  HitDescriptor(const HitDescriptor &hitDescriptor);
282 
284  HitDescriptor(HitDescriptor &&hitDescriptor);
285 
287  ~HitDescriptor();
288 
290  HitDescriptor& operator=(const HitDescriptor &rhs);
291 
293  HitDescriptor& operator=(HitDescriptor &&rhs);
294 
296  void setRaySource(const Vector3d &raySource);
297 
299  const Vector3d& getRaySource() const;
300 
302  void setRayDirection(const Vector3d &rayDirection);
303 
305  const Vector3d& getRayDirection() const;
306 
308  void setIndex(const Index &index);
309 
311  const Index& getIndex() const;
312 
314  void setCoordinate(const Vector3d coordainte);
315 
317  const Vector3d& getCoordinate() const;
318 
320  const Vector3d& getDirectionFromObject();
321 
323  const Vector3d& getImpactPosition();
324  private:
326  const RenderContext *renderContext;
327 
329  Vector3d raySource;
330 
332  Vector3d rayDirection;
333 
335  Index index;
336 
338  Vector3d coordinate;
339 
341  Vector3d *directionFromObject;
342 
344  Vector3d *impactPosition;
345  };
346 
347  class RenderResult{
348  public:
350  RenderResult(unsigned int width, unsigned int height);
351 
353  RenderResult(const RenderResult &renderResult);
354 
356  RenderResult(RenderResult &&renderResult);
357 
359  ~RenderResult();
360 
362  RenderResult& operator=(const RenderResult &rhs);
363 
365  RenderResult& operator=(RenderResult &&rhs);
366 
368  cv::Mat& getCanvas();
369 
371  const cv::Mat& getCanvas() const;
372 
374  std::vector<HitDescriptor>** getHitDescriptors();
375  private:
377  unsigned int width, height;
378 
380  cv::Mat canvas;
381 
384  std::vector<HitDescriptor> **hitDescriptors;
385  };
386 
387  RenderResult *renderResult;
388 
390  void render(
391  const IndexDescriptor &indexDescriptor,
392  const Model &model,
393  const std::vector<const FieldWrapper*> &fields,
394  std::function<Material(HitDescriptor &hitDescriptor)> &&lambdaColorPicker,
395  std::function<void(cv::Mat &canvas, const Index &index)> &&lambdaInteractive = {}
396  );
397 
399  Color trace(
400  const std::vector<Vector3d> &coordinates,
401  const Vector3d &raySource,
402  const Vector3d &rayDirection,
403  const IndexTree &indexTree,
404  const std::vector<const FieldWrapper*> &fields,
405  std::vector<HitDescriptor> &hitDescriptors,
406  std::function<Material(HitDescriptor &hitDescriptor)> lambdaColorPicker,
407  unsigned int deflections = 0
408  );
409 
411  Color traceFields(
412  const std::vector<const FieldWrapper*> &fields,
413  const Vector3d &raySource,
414  const Vector3d &rayDirection
415  );
416 
418  cv::Mat getCharImage() const;
419 
421  class EventHandler{
422  public:
424  static bool lock(
425  RayTracer *owner,
426  std::function<void(
427  int event,
428  int x,
429  int y,
430  int flags,
431  void *userData
432  )> &&lambdaOnMouseChange
433  );
434 
436  static bool unlock(const RayTracer *owner);
437 
439  static void onMouseChange(
440  int event,
441  int x,
442  int y,
443  int flags,
444  void *userdata
445  );
446  private:
448  static bool isLocked;
449 
451  static RayTracer *owner;
452 
454  static std::function<void(int event, int x, int y, int flags, void *userData)> &&lambdaOnMouseChange;
455  };
456 };
457 
458 inline void RayTracer::setCameraPosition(const Vector3d &cameraPosition){
459  renderContext.setCameraPosition(cameraPosition);
460 }
461 
462 inline void RayTracer::setCameraPosition(
463  std::initializer_list<double> cameraPosition
464 ){
465  renderContext.setCameraPosition(cameraPosition);
466 }
467 
468 inline void RayTracer::setFocus(const Vector3d &focus){
469  renderContext.setFocus(focus);
470 }
471 
472 inline void RayTracer::setFocus(std::initializer_list<double> focus){
473  renderContext.setFocus(focus);
474 }
475 
476 inline void RayTracer::setUp(const Vector3d &up){
477  renderContext.setUp(up);
478 }
479 
480 inline void RayTracer::setWidth(unsigned int width){
481  renderContext.setWidth(width);
482 }
483 
484 inline void RayTracer::setHeight(unsigned int height){
485  renderContext.setHeight(height);
486 }
487 
488 inline void RayTracer::setUp(std::initializer_list<double> up){
489  renderContext.setUp(up);
490 }
491 
492 inline void RayTracer::setStateRadius(double stateRadius){
493  renderContext.setStateRadius(stateRadius);
494 }
495 
496 inline void RayTracer::setNumDeflections(unsigned int numDeflections){
497  renderContext.setNumDeflections(numDeflections);
498 }
499 
500 inline unsigned int RayTracer::getNumDeflections() const{
501  return renderContext.getNumDeflections();
502 }
503 
504 inline void RayTracer::setRayLength(double rayLength){
505  renderContext.setRayLength(rayLength);
506 }
507 
508 inline double RayTracer::getRayLength() const{
509  return renderContext.getRayLength();
510 }
511 
512 inline void RayTracer::setNumRaySegments(unsigned int numRaySegments){
513  renderContext.setNumRaySegments(numRaySegments);
514 }
515 
516 inline unsigned int RayTracer::getNumRaySegments() const{
517  return renderContext.getNumRaySegments();
518 }
519 
520 /*inline RayTracer::RenderResult::RenderResult(
521  unsigned int width,
522  unsigned int height
523 ){
524  this->width = width;
525  this->height = height;
526 
527  canvas = cv::Mat(height, width, CV_32FC3);
528 
529  hitDescriptors = new std::vector<HitDescriptor>*[width];
530  for(unsigned int x = 0; x < width; x++)
531  hitDescriptors[x] = new std::vector<HitDescriptor>[height];
532 }
533 
534 inline RayTracer::RenderResult::~RenderResult(){
535  for(unsigned int x = 0; x < width; x++)
536  delete [] hitDescriptors[x];
537  delete [] hitDescriptors;
538 }*/
539 
540 inline cv::Mat& RayTracer::RenderResult::getCanvas(){
541  return canvas;
542 }
543 
544 inline const cv::Mat& RayTracer::RenderResult::getCanvas() const{
545  return canvas;
546 }
547 
548 inline std::vector<RayTracer::HitDescriptor>** RayTracer::RenderResult::getHitDescriptors(){
549  return hitDescriptors;
550 }
551 
552 inline RayTracer::Material::Material(){
553  color.r = 0;
554  color.g = 0;
555  color.b = 0;
556  ambient = DEFAULT_AMBIENT;
557  diffusive = DEFAULT_AMBIENT;
558  emissive = DEFAULT_EMISSIVE;
559  specular = DEFAULT_SPECULAR;
560 }
561 
562 inline void RayTracer::RenderContext::setCameraPosition(
563  const Vector3d &cameraPosition
564 ){
565  this->cameraPosition = cameraPosition;
566 }
567 
568 inline void RayTracer::RenderContext::setCameraPosition(
569  std::initializer_list<double> cameraPosition
570 ){
571  TBTKAssert(
572  cameraPosition.size() == 3,
573  "RayTracer::setCameraPosition()",
574  "Camera position can only have three coordinates.",
575  ""
576  );
577 
578  this->cameraPosition.x = *(cameraPosition.begin() + 0);
579  this->cameraPosition.y = *(cameraPosition.begin() + 1);
580  this->cameraPosition.z = *(cameraPosition.begin() + 2);
581 }
582 
583 inline const Vector3d& RayTracer::RenderContext::getCameraPosition() const{
584  return cameraPosition;
585 }
586 
587 inline void RayTracer::RenderContext::setFocus(const Vector3d &focus){
588  this->focus = focus;
589 }
590 
591 inline void RayTracer::RenderContext::setFocus(
592  std::initializer_list<double> focus
593 ){
594  TBTKAssert(
595  focus.size() == 3,
596  "RayTracer::setFocus()",
597  "Focus can only have three coordinates.",
598  ""
599  );
600 
601  this->focus.x = *(focus.begin() + 0);
602  this->focus.y = *(focus.begin() + 1);
603  this->focus.z = *(focus.begin() + 2);
604 }
605 
606 inline const Vector3d& RayTracer::RenderContext::getFocus() const{
607  return focus;
608 }
609 
610 inline void RayTracer::RenderContext::setUp(const Vector3d &up){
611  this->up = up;
612 }
613 
614 inline void RayTracer::RenderContext::setUp(
615  std::initializer_list<double> up
616 ){
617  TBTKAssert(
618  up.size() == 3,
619  "RayTracer::setCameraPosition()",
620  "Camera position can only have three coordinates.",
621  ""
622  );
623 
624  this->up.x = *(up.begin() + 0);
625  this->up.y = *(up.begin() + 1);
626  this->up.z = *(up.begin() + 2);
627 }
628 
629 inline const Vector3d& RayTracer::RenderContext::getUp() const{
630  return up;
631 }
632 
633 inline void RayTracer::RenderContext::setWidth(unsigned int width){
634  this->width = width;
635 }
636 
637 inline unsigned int RayTracer::RenderContext::getWidth() const{
638  return width;
639 }
640 
641 inline void RayTracer::RenderContext::setHeight(unsigned int height){
642  this->height = height;
643 }
644 
645 inline unsigned int RayTracer::RenderContext::getHeight() const{
646  return height;
647 }
648 
649 inline void RayTracer::RenderContext::setStateRadius(double stateRadius){
650  this->stateRadius = stateRadius;
651 }
652 
653 inline double RayTracer::RenderContext::getStateRadius() const{
654  return stateRadius;
655 }
656 
657 inline void RayTracer::RenderContext::setNumDeflections(
658  unsigned int numDeflections
659 ){
660  this->numDeflections = numDeflections;
661 }
662 
663 inline unsigned int RayTracer::RenderContext::getNumDeflections() const{
664  return numDeflections;
665 }
666 
667 inline void RayTracer::RenderContext::setRayLength(double rayLength){
668  this->rayLength = rayLength;
669 }
670 
671 inline double RayTracer::RenderContext::getRayLength() const{
672  return rayLength;
673 }
674 
675 inline void RayTracer::RenderContext::setNumRaySegments(
676  unsigned int numRaySegments
677 ){
678  this->numRaySegments = numRaySegments;
679 }
680 
681 inline unsigned int RayTracer::RenderContext::getNumRaySegments() const{
682  return numRaySegments;
683 }
684 
685 inline void RayTracer::HitDescriptor::setRaySource(
686  const Vector3d &raySource
687 ){
688  this->raySource = raySource;
689 }
690 
691 inline const Vector3d& RayTracer::HitDescriptor::getRaySource() const{
692  return this->raySource;
693 }
694 
695 inline void RayTracer::HitDescriptor::setRayDirection(
696  const Vector3d &rayDirection
697 ){
698  this->rayDirection = rayDirection;
699 }
700 
701 inline const Vector3d& RayTracer::HitDescriptor::getRayDirection() const{
702  return this->rayDirection;
703 }
704 
705 inline void RayTracer::HitDescriptor::setIndex(const Index &index){
706  this->index = index;
707 }
708 
709 inline const Index& RayTracer::HitDescriptor::getIndex() const{
710  return index;
711 }
712 
713 inline void RayTracer::HitDescriptor::setCoordinate(const Vector3d coordinate){
714  this->coordinate = coordinate;
715 }
716 
717 inline const Vector3d& RayTracer::HitDescriptor::getCoordinate() const{
718  return coordinate;
719 }
720 
721 inline bool RayTracer::EventHandler::lock(
722  RayTracer *owner,
723  std::function<void(
724  int event,
725  int x,
726  int y,
727  int flags,
728  void *userData
729  )> &&lambdaOnMouseChange
730 ){
731  if(isLocked){
732  return false;
733  }
734  else{
735  isLocked = true;
736  EventHandler::owner = owner;
737  EventHandler::lambdaOnMouseChange = lambdaOnMouseChange;
738  return true;
739  }
740 }
741 
742 inline bool RayTracer::EventHandler::unlock(const RayTracer *owner){
743  if(EventHandler::owner == owner){
744  EventHandler::owner = nullptr;
745  EventHandler::isLocked = false;
746  EventHandler::lambdaOnMouseChange = nullptr;
747  return true;
748  }
749  else{
750  return false;
751  }
752 }
753 
754 inline void RayTracer::EventHandler::onMouseChange(
755  int event,
756  int x,
757  int y,
758  int flags,
759  void *userData
760 ){
761  if(lambdaOnMouseChange){
762  lambdaOnMouseChange(event, x, y, flags, userData);
763  }
764  else{
765  TBTKExit(
766  "RayTracer::EventHandler::onMouseChange()",
767  "lambdaOnMouseChange is nullptr.",
768  "This should never happen, contact the developer."
769  );
770  }
771 }
772 
773 }; //End namespace TBTK
774 
775 #endif
776 
Precompiler macros.
Property container for local density of states (LDOS).
Container of Model related information.
Three-dimensional vector with components of double type.
Property container for density.
Property container for magnetization.
Definition: Boolean.h:32
Property container for wave functions.