225 const std::size_t pos,
228 shared_ptr<TranslationT>
trans_geom = newTranslation(el,
aligner, stackHeights[pos] - bb.lower.vert(), bb);
230 children.insert(children.begin() + pos,
trans_geom);
231 this->aligners.insert(this->aligners.begin() + pos,
aligner);
232 stackHeights.insert(stackHeights.begin() + pos, stackHeights[pos]);
233 const double delta = bb.upper.vert() - bb.lower.vert();
234 for (std::size_t i = pos + 1; i < children.size(); ++i) {
235 stackHeights[i] += delta;
236 children[i]->translation.vert() += delta;
238 stackHeights.back() += delta;
240 this->updateAllHeights();
242 this->fireChildrenInserted(pos, pos + 1);
264 shared_ptr<TranslationT>
result(
new TranslationT(el, Primitive<dim>::ZERO_VEC));
271 if (
evt.isResize()) {
273 this->updateAllHeights();
275 this->fireChanged(
evt.originalSource(),
evt.flagsForParent());
288 this->aligners.push_back(
aligner);
290 this->updateAllHeights();
292 this->fireChildrenInserted(children.size() - 1, children.size());
298 if (ParentClass::removeIfTUnsafe(predicate)) {
299 this->rebuildStackHeights();
326 this->aligners.erase(this->aligners.begin() + index);
327 stackHeights.pop_back();
328 this->updateAllHeights(index);
338 for (
int i =
int(children.size()) - 1; i >= 0; --i) {
341 if (
auto child = children[i]->getChild()) child->writeXML(
child_tag,
write_cb, axes);
354 result->default_aligner = default_aligner;
366 result->default_aligner = default_aligner;
368 if (this->children[
child_no]->getChild())
380 result->default_aligner = default_aligner;
399 std::size_t first = 0;
403 const double height =
children[first]->getBoundingBoxSize().vert();
404 for (std::size_t i = first + 1; i <
children.size(); ++i)
415 auto elBB = el->getBoundingBox();
431 const auto bb = el->getBoundingBox();
437 const double delta = bb.upper.tran() - bb.lower.tran();
438 for (std::size_t i = pos + 1; i <
children.size(); ++i) {
440 children[i]->translation.tran() += delta;
452 result->resizableGap = resizableGap;
463 result->resizableGap = resizableGap;
475 result->resizableGap = resizableGap;
494template <
typename UpperClass>
496 Box result = UpperClass::getBoundingBox();
497 result.upper[UpperClass::GROWING_DIR] =
498 result.lower[UpperClass::GROWING_DIR] +
499 (
result.upper[UpperClass::GROWING_DIR] -
result.lower[UpperClass::GROWING_DIR]) * repeat_count;
503template <
typename UpperClass>
505 return UpperClass::getBoundingBox();
518template <
typename UpperClass>
520 std::vector<Box>&
dest,
522 if (predicate(*
this)) {
523 dest.push_back(getBoundingBox());
526 if (repeat_count == 0)
return;
528 UpperClass::getBoundingBoxesToVec(predicate,
dest, path);
530 const double stackHeight = stackHeights.back() - stackHeights.front();
531 for (
unsigned r = 1; r < repeat_count; ++r) {
534 i->translateDir(UpperClass::GROWING_DIR,
stackHeight * r);
538template <
typename UpperClass>
542 if (predicate(*
this)) {
546 if (repeat_count == 0)
return;
548 UpperClass::getObjectsToVec(predicate,
dest, path);
550 for (
unsigned r = 1; r < repeat_count; ++r)
554template <
typename UpperClass>
556 std::vector<DVec>&
dest,
558 if (predicate(*
this)) {
562 if (repeat_count == 0)
return;
564 UpperClass::getPositionsToVec(predicate,
dest, path);
566 const double stackHeight = stackHeights.back() - stackHeights.front();
567 for (
unsigned r = 1; r < repeat_count; ++r)
594template <
typename UpperClass>
600 const std::size_t size =
result.children.size();
601 const double stackHeight = stackHeights.back() - stackHeights.front();
602 for (
unsigned r = 1; r < repeat_count; ++r)
614template <
typename UpperClass>
624template <
typename UpperClass>
626 if (repeat_count == 0)
return false;
628 if (!reduceHeight(
p_reduced[UpperClass::GROWING_DIR]))
return false;
632template <
typename UpperClass>
638 return UpperClass::getMaterial(
p_reduced);
641template <
typename UpperClass>
643 if (
child_no >= getChildrenCount()) {
649 auto result = children[
child_no % children.size()]->copyShallow();
650 result->translation[UpperClass::GROWING_DIR] +=
651 double(
child_no / children.size()) * (stackHeights.back() - stackHeights.front());
656 return UpperClass::getChildrenCount();
659template <
typename UpperClass>
661 return UpperClass::getChildNo(
child_no);
664template <
typename UpperClass>
670template <
typename StackContainerT>
671static inline void addChild(
681static inline void addChild(
690template <
typename StackContainerT>
714template <
typename UpperClass>
728template <
typename UpperClass>
739template <
typename UpperClass>
743 double min_step_size)
const {
744 if (repeat_count == 0)
return;
745 if (repeat_count == 1 || direction != UpperClass::GROWING_DIR + (3 - DIM)) {
746 UpperClass::addPointsAlongToSet(points, direction, max_steps, min_step_size);
749 double shift = stackHeights.back() - stackHeights.front();
751 UpperClass::addPointsAlongToSet(
points0, direction, max_steps, min_step_size);
752 for (
size_t i = 0; i < repeat_count; ++i) {
753 double trans = i * shift;
754 for (
double p :
points0) points.insert(p + trans);
758template <
typename UpperClass>
762 double min_step_size)
const {
763 if (repeat_count == 0)
return;
764 if (repeat_count == 1) {
765 UpperClass::addLineSegmentsToSet(segments, max_steps, min_step_size);
770 UpperClass::addLineSegmentsToSet(
segments0, max_steps, min_step_size);
772 shift[size_t(UpperClass::GROWING_DIR)] = stackHeights.back() - stackHeights.front();
773 for (
size_t i = 0; i < repeat_count; ++i) {
774 DVec trans = i * shift;
775 for (
const auto& s :
segments0) segments.insert(LineSegment(s.p0() + trans, s.p1() + trans));
794 whereWasZero(reader.hasAttribute(
BASEH_ATTR) ? -2 : -1),
798 inline void setZero(shared_ptr<plask::GeometryObject> stack) {
799 if (whereWasZero != -1)
throw XMLException(reader, format(
"{} shift has already been specified.", what));
800 whereWasZero =
int(stack->getRealChildrenCount());
819 if (whereWasZero >= 0) {
821 stack->alignZeroOn(
reverse ? stack->getRealChildrenCount() - whereWasZero - 1 : whereWasZero,
824 stack->setZeroBefore(
reverse ? stack->getRealChildrenCount() - whereWasZero : whereWasZero);
830 HeightReader
height_reader(reader.source,
"Stack's vertical");
862 HeightReader
height_reader(reader.source,
"Shelf's horizontal");
883 plask::optional<double>
total_size_attr = reader.source.getAttribute<
double>(
"total");
885 if (
total_size_gap)
throw XMLException(reader.source,
"total size has been already chosen.");
893 ->addGap(reader.source.requireAttribute<
double>(
894 Gap1D<2, Primitive<2>::DIRECTION_TRAN>::XML_SIZE_ATTR))
898 reader.registerObjectNameFromCurrentNode(
this_gap);
899 reader.source.requireTagEnd();
906 reader.manager.throwErrorIfNotDraft(
907 XMLException(reader.source,
"required total width of shelf is lower than sum of children widths"));
916 }
catch (
const Exception&
e) {
917 reader.manager.throwErrorIfNotDraft(XMLException(reader.source,
e.what()));
923static GeometryReader::RegisterObjectReader horizontalstack_reader(
PLASK_SHELF_NAME, read_ShelfContainer2D);
924static GeometryReader::RegisterObjectReader horizontalstack2D_reader(
926 read_ShelfContainer2D);