BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
SampleViewAligner Class Reference

Makes alignment of sample droped on graphics scene. More...

Collaboration diagram for SampleViewAligner:
[legend]

Public Member Functions

 SampleViewAligner (DesignerScene *scene)
 
void advance ()
 Applies calculated positions to views. More...
 
void alignSample (const QModelIndex &parentIndex, QPointF reference={}, bool force_alignment=false)
 Aligns sample starting from reference point. More...
 
void alignSample (SessionItem *item, QPointF reference={}, bool force_alignment=false)
 Aligns sample starting from. More...
 
void calculateForces (IView *view)
 Calculates forces acting on single view (simplified force directed spring algorithm) and deduce new position of views. More...
 
void smartAlign ()
 Spring based implified algorithm for smart alignment. More...
 
void updateForces ()
 Calculates forces acting on all views for smart alignment. More...
 
void updateViews (const QModelIndex &parentIndex={})
 Forms list of all views which are subject for smart alignment (i.e. More...
 

Private Member Functions

QList< IView * > getConnectedViews (IView *view)
 Returns list of views connected with given view for the subsequent force calculation. More...
 
IViewgetViewForIndex (const QModelIndex &index)
 

Private Attributes

DesignerScenem_scene
 
QList< IView * > m_views
 list of all views which are subject to smart align More...
 
QMap< IView *, QPointF > m_viewToPos
 

Detailed Description

Makes alignment of sample droped on graphics scene.

Implements additional algorithm for smart alignment.

Definition at line 27 of file SampleViewAligner.h.

Constructor & Destructor Documentation

◆ SampleViewAligner()

SampleViewAligner::SampleViewAligner ( DesignerScene scene)

Definition at line 33 of file SampleViewAligner.cpp.

33  : m_scene(scene)
34 {
35  ASSERT(m_scene);
36 }
#define ASSERT(condition)
Definition: Assert.h:31
DesignerScene * m_scene

References ASSERT, and m_scene.

Member Function Documentation

◆ advance()

void SampleViewAligner::advance ( )

Applies calculated positions to views.

Definition at line 105 of file SampleViewAligner.cpp.

106 {
107  for (IView* view : m_views) {
108  view->setPos(m_viewToPos[view]);
109  }
110 }
parent class for graphic representation of all ISampleNode's
Definition: IView.h:25
QList< IView * > m_views
list of all views which are subject to smart align
QMap< IView *, QPointF > m_viewToPos

References m_views, and m_viewToPos.

Referenced by smartAlign().

◆ alignSample() [1/2]

void SampleViewAligner::alignSample ( const QModelIndex &  parentIndex,
QPointF  reference = {},
bool  force_alignment = false 
)

Aligns sample starting from reference point.

If force_alignment=false, view's position will be changed only if it has Null coordinate, if force_alignment=true the position will be changed anyway. Position of View which has parent item (like Layer) will remain unchainged.

Definition at line 161 of file SampleViewAligner.cpp.

163 {
164  SampleModel* sampleModel = m_scene->getSampleModel();
165 
166  if (IView* view = getViewForIndex(parentIndex)) {
167  if ((force_alignment || view->pos().isNull()) && !view->parentObject())
168  view->setPos(reference);
169 
170  if (view->parentObject()) {
171  reference = view->mapToScene(view->pos());
172  } else {
173  reference = view->pos();
174  }
175  }
176  int child_counter = 0;
177  for (int i_row = 0; i_row < sampleModel->rowCount(parentIndex); ++i_row) {
178  QModelIndex itemIndex = sampleModel->index(i_row, 0, parentIndex);
179  if (!getViewForIndex(itemIndex))
180  continue;
181  QPointF child_reference =
182  reference + QPointF(-step_width(), step_height() * child_counter++);
183  alignSample(itemIndex, child_reference, force_alignment);
184  }
185 }
SampleModel * getSampleModel()
Definition: DesignerScene.h:49
Main model to hold sample items.
Definition: SampleModel.h:24
void alignSample(SessionItem *item, QPointF reference={}, bool force_alignment=false)
Aligns sample starting from.
IView * getViewForIndex(const QModelIndex &index)
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const
virtual int rowCount(const QModelIndex &parent) const

References alignSample(), DesignerScene::getSampleModel(), getViewForIndex(), SessionModel::index(), m_scene, and SessionModel::rowCount().

Here is the call graph for this function:

◆ alignSample() [2/2]

void SampleViewAligner::alignSample ( SessionItem item,
QPointF  reference = {},
bool  force_alignment = false 
)

Aligns sample starting from.

Definition at line 151 of file SampleViewAligner.cpp.

152 {
153  ASSERT(item);
154  alignSample(m_scene->getSampleModel()->indexOfItem(item), reference, force_alignment);
155 }
QModelIndex indexOfItem(SessionItem *item) const

References ASSERT, DesignerScene::getSampleModel(), SessionModel::indexOfItem(), and m_scene.

Referenced by alignSample(), DesignerScene::alignViews(), and DesignerScene::dropEvent().

Here is the call graph for this function:

◆ calculateForces()

void SampleViewAligner::calculateForces ( IView view)

Calculates forces acting on single view (simplified force directed spring algorithm) and deduce new position of views.

Definition at line 73 of file SampleViewAligner.cpp.

74 {
75  qreal xvel = 0;
76  qreal yvel = 0;
77 
78  // repulsive forces which are pushing items away
79 
80  double weight1(200.0);
81  for (IView* other : m_views) {
82  QPointF vec = view->mapToItem(other, other->boundingRect().center());
83  qreal dx = view->boundingRect().center().x() - vec.x();
84  qreal dy = view->boundingRect().center().y() - vec.y();
85  double l = (dx * dx + dy * dy);
86  if (l > 0) {
87  xvel -= (dx * weight1) / l;
88  yvel -= (dy * weight1) / l;
89  }
90  }
91  // attracting forces which are pulling views together
92  double weight2(100.0);
93  for (IView* other : getConnectedViews(view)) {
94  QPointF vec = view->mapToItem(other, other->boundingRect().center());
95  qreal dx = view->boundingRect().center().x() - vec.x();
96  qreal dy = view->boundingRect().center().y() - vec.y();
97  xvel += dx / weight2;
98  yvel += dy / weight2;
99  }
100  QPointF newPos = view->pos() + QPointF(xvel, yvel);
101  m_viewToPos[view] = newPos;
102 }
QList< IView * > getConnectedViews(IView *view)
Returns list of views connected with given view for the subsequent force calculation.

References getConnectedViews(), m_views, and m_viewToPos.

Referenced by updateForces().

Here is the call graph for this function:

◆ getConnectedViews()

QList< IView * > SampleViewAligner::getConnectedViews ( IView view)
private

Returns list of views connected with given view for the subsequent force calculation.

Weirdness of given function is due to the fact, that, for example, ParticleLayout view should interact not with Layer view, but with its parent - MultiLayer view. Similarly, MultiLayer is not interacting with its Layers, but directly with the ParticleLayout.

Definition at line 117 of file SampleViewAligner.cpp.

118 {
119  QList<IView*> result;
120 
121  SessionItem* itemOfView = view->getItem();
122 
123  QList<SessionItem*> connected_items;
124 
125  if (itemOfView->parent()->modelType() == "Layer") {
126  // e.g. we are dealing here with ParticleLayout, so we will use directly MultiLayer to
127  // interact with
128  connected_items.append(itemOfView->parent()->parent());
129  } else {
130  connected_items.append(itemOfView->parent());
131  }
132  if (itemOfView->modelType() == "MultiLayer") {
133  // MultiLayer will not interact with its Layers, but with they children, e.g. with
134  // ParticleLayouts
135  for (auto child : itemOfView->children()) {
136  connected_items.append(child->children().toList());
137  }
138  } else {
139  connected_items.append(itemOfView->children().toList());
140  }
141  for (auto item : connected_items) {
142  IView* view = m_scene->getViewForItem(item);
143  if (view) {
144  result.append(view);
145  }
146  }
147  return result;
148 }
IView * getViewForItem(SessionItem *item)
virtual SessionItem * getItem()
Definition: IView.h:59
SessionItem * parent() const
Returns parent of this item.
Definition: SessionItem.cpp:73
QVector< SessionItem * > children() const
Returns vector of all children.
QString modelType() const
Get model type.

References SessionItem::children(), IView::getItem(), DesignerScene::getViewForItem(), m_scene, SessionItem::modelType(), and SessionItem::parent().

Referenced by calculateForces().

Here is the call graph for this function:

◆ getViewForIndex()

IView * SampleViewAligner::getViewForIndex ( const QModelIndex &  index)
private

Definition at line 187 of file SampleViewAligner.cpp.

188 {
189  SampleModel* sampleModel = m_scene->getSampleModel();
190  SessionItem* item = sampleModel->itemForIndex(index);
191  return m_scene->getViewForItem(item);
192 }
SessionItem * itemForIndex(const QModelIndex &index) const

References DesignerScene::getSampleModel(), DesignerScene::getViewForItem(), SessionModel::itemForIndex(), and m_scene.

Referenced by alignSample(), and updateViews().

Here is the call graph for this function:

◆ smartAlign()

void SampleViewAligner::smartAlign ( )

Spring based implified algorithm for smart alignment.

Definition at line 39 of file SampleViewAligner.cpp.

40 {
41  m_views.clear();
42  updateViews();
43  updateForces();
44  advance();
45 }
void advance()
Applies calculated positions to views.
void updateForces()
Calculates forces acting on all views for smart alignment.
void updateViews(const QModelIndex &parentIndex={})
Forms list of all views which are subject for smart alignment (i.e.

References advance(), m_views, updateForces(), and updateViews().

Referenced by DesignerScene::onSmartAlign().

Here is the call graph for this function:

◆ updateForces()

void SampleViewAligner::updateForces ( )

Calculates forces acting on all views for smart alignment.

Definition at line 63 of file SampleViewAligner.cpp.

64 {
65  m_viewToPos.clear();
66  for (IView* view : m_views) {
67  calculateForces(view);
68  }
69 }
void calculateForces(IView *view)
Calculates forces acting on single view (simplified force directed spring algorithm) and deduce new p...

References calculateForces(), m_views, and m_viewToPos.

Referenced by smartAlign().

Here is the call graph for this function:

◆ updateViews()

void SampleViewAligner::updateViews ( const QModelIndex &  parentIndex = {})

Forms list of all views which are subject for smart alignment (i.e.

views which do not have parent view)

Definition at line 49 of file SampleViewAligner.cpp.

50 {
51  SampleModel* sampleModel = m_scene->getSampleModel();
52  for (int i_row = 0; i_row < sampleModel->rowCount(parentIndex); ++i_row) {
53  QModelIndex itemIndex = sampleModel->index(i_row, 0, parentIndex);
54  IView* view = getViewForIndex(itemIndex);
55  if (view && !view->parentObject()) {
56  m_views.append(view);
57  }
58  updateViews(itemIndex);
59  }
60 }

References DesignerScene::getSampleModel(), getViewForIndex(), SessionModel::index(), m_scene, m_views, and SessionModel::rowCount().

Referenced by smartAlign().

Here is the call graph for this function:

Member Data Documentation

◆ m_scene

DesignerScene* SampleViewAligner::m_scene
private

◆ m_views

QList<IView*> SampleViewAligner::m_views
private

list of all views which are subject to smart align

Definition at line 46 of file SampleViewAligner.h.

Referenced by advance(), calculateForces(), smartAlign(), updateForces(), and updateViews().

◆ m_viewToPos

QMap<IView*, QPointF> SampleViewAligner::m_viewToPos
private

Definition at line 47 of file SampleViewAligner.h.

Referenced by advance(), calculateForces(), and updateForces().


The documentation for this class was generated from the following files: