14#ifndef PLASK__GEOMETRY_ALIGN_H
15#define PLASK__GEOMETRY_ALIGN_H
22#include <boost/lexical_cast.hpp>
23#include "../utils/xml.hpp"
24#include "../memory.hpp"
25#include "../utils/metaprog.hpp"
37template <Direction direction>
59template <Direction _direction>
81 virtual double getAlign(
double low,
double hi)
const = 0;
126 std::map<std::string,double>
dict;
142template <Direction _direction>
163 double getAlign(
double low,
double hi)
const {
return this->
held->getAlign(low, hi); }
189 return this->
held->align(toAlign);
205 return this->
held->asDict(axis_names);
232 std::string
str()
const {
return this->
held; }
241template <Direction _direction>
272 if (this->useBounds() &&
toAlign.getChild())
275 toAlign.translation[direction2D] = this->getAlign(0.0, 0.0);
291template <Direction direction>
302 void print(std::ostream& out)
const override { out <<
"align object position along axis " <<
direction <<
" to " << this->
coordinate; }
312template <Direction _direction1, Direction _direction2>
315 static_assert(
_direction1 <
_direction2,
"Wrong Aligner template parameters, two different directions are required and first direction must have lower index than second one. Try swapping Aligner template parameters.");
392 std::string
str()
const {
return boost::lexical_cast<std::string>(*
this); }
400 std::map<std::string,double>
dict;
423template <Direction _direction1, Direction _direction2>
467 if (this->useBounds() &&
toAlign.getChild())
470 toAlign.translation[0] = this->dir1aligner.getAlign(0.0, 0.0);
471 toAlign.translation[1] = this->dir2aligner.getAlign(0.0, 0.0);
492 : dir1aligner(dir1aligner), dir2aligner(dir2aligner), dir3aligner(dir3aligner) {}
498 bool useBounds()
const {
return dir1aligner.useBounds() || dir2aligner.useBounds() || dir3aligner.useBounds(); }
520 if (useBounds() &&
toAlign.getChild())
523 toAlign.translation[0] = dir1aligner.getAlign(0.0, 0.0);
524 toAlign.translation[1] = dir2aligner.getAlign(0.0, 0.0);
525 toAlign.translation[2] = dir3aligner.getAlign(0.0, 0.0);
543 std::string
str()
const {
return boost::lexical_cast<std::string>(*
this); }
551 std::map<std::string,double>
dict;
569 bool isNull() {
return dir1aligner.isNull() || dir2aligner.isNull() || dir3aligner.isNull(); }
634inline double lowToCoordinate(
double lo,
double ,
double coordinate) {
return coordinate -lo; }
635inline double hiToCoordinate(
double ,
double hi,
double coordinate) {
return coordinate -hi; }
636inline double centerToCoordinate(
double lo,
double hi,
double coordinate) {
return coordinate -(lo+hi)/2.0; }
638struct LEFT {
static constexpr const char*
value =
"left"; };
639struct RIGHT {
static constexpr const char*
value =
"right"; };
640struct FRONT {
static constexpr const char*
value =
"front"; };
641struct BACK {
static constexpr const char*
value =
"back"; };
642struct TOP {
static constexpr const char*
value =
"top"; };
648template <Direction direction, alignStrategy strategy,
typename name_tag>
653 double getAlign(
double low,
double hi)
const override {
661 void print(std::ostream& out)
const override { out <<
"align " << name_tag::value <<
" to " << this->
coordinate; }
663 std::string
key(
const AxisNames& )
const override {
return name_tag::value; }
706typedef std::function<plask::optional<double>(
const std::string& name)>
Dictionary;
723template <Direction direction>
750template <Direction direction>
765template <Direction direction>
781template <Direction direction>
786template <Direction direction>
791template <Direction direction>
805template <Direction direction1, Direction direction2>
808 if (
a1.isNull())
throw Exception(
"no aligner for axis{0} defined.", direction1);
810 if (
a2.isNull())
throw Exception(
"no aligner for axis{0} defined.", direction2);
823template <Direction direction1, Direction direction2>
837template <Direction direction1, Direction direction2>
851template <Direction direction1, Direction direction2>
865template <Direction direction1, Direction direction2, Direction direction3>
868 if (
a0.isNull())
throw Exception(
"no aligner for axis{0} defined.", 0);
870 if (
a1.isNull())
throw Exception(
"no aligner for axis{0} defined.", 1);
872 if (
a2.isNull())
throw Exception(
"no aligner for axis{0} defined.", 2);
885template <Direction direction1, Direction direction2, Direction direction3>
899template <Direction direction1, Direction direction2, Direction direction3>
913template <Direction direction1, Direction direction2, Direction direction3>
931template <
typename TranslationT,
typename Aligner1T,
typename Aligner2T>
934 auto bb =
toAlign.getChild()->getBoundingBox();