41 SliceItem::SliceItem(
const QPolygonF& polygon,
const QLineF& cut, std::shared_ptr<EditControlLogic> tissue, QGraphicsScene* scene)
45 setBrush(QColor(220,220,220,255));
46 setAcceptHoverEvents(
true);
47 setFlag(GraphicsItemFlag::ItemIsSelectable);
52 QVariant SliceItem::itemChange(GraphicsItemChange change,
const QVariant& value)
54 if (change == QGraphicsItem::ItemSelectedHasChanged && isSelected()) {
58 return QGraphicsPolygonItem::itemChange(change, value);
61 void SliceItem::hoverEnterEvent(QGraphicsSceneHoverEvent* )
63 setBrush(QColor(51, 102, 0, 255));
66 void SliceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* )
68 setBrush(QColor(220,220,220,255));
71 void SliceItem::TruncateLeaf()
73 std::list<Cell*> cellsToBeDeleted;
74 std::list<Cell*> cellsToBeSliced;
75 auto mesh = m_tissue->GetMesh()->GetMesh();
77 for (
auto cell : m_tissue->GetCells()) {
79 bool fullyContained =
true;
80 for (
Node* node : cell->GetNodes()) {
81 QPointF point((*node)[0], (*node)[1]);
82 if (polygon().containsPoint(point, Qt::OddEvenFill) || polygon().contains(point)) {
86 fullyContained =
false;
90 cellsToBeDeleted.push_back(cell);
92 else if (!fullyContained) {
93 cellsToBeSliced.push_back(cell);
97 std::vector<QPointF> corners = polygon().toStdVector();
98 std::map<Cell*, std::list<Node*>> newNodes;
99 std::map<Node*, std::list<NeighborNodes>> newOwners;
100 for (
auto cell : cellsToBeSliced) {
101 newNodes.insert(std::make_pair(cell, std::list<Node*>()));
106 QLineF line((*n1)[0], (*n1)[1], (*n2)[0], (*n2)[1]);
107 QPointF intersection;
109 if (m_cut.intersect(line, &intersection) == QLineF::BoundedIntersection) {
110 if (find(newNodes[cell].begin(), newNodes[cell].end(), *node) == newNodes[cell].end()) {
111 if (intersection == QPointF((*n1)[0], (*n1)[1])) {
112 newNodes[cell].push_back(n1);
114 else if (intersection == QPointF((*n2)[0], (*n2)[1])) {
115 newNodes[cell].push_back(n2);
118 auto owner = find_if(newOwners.begin(), newOwners.end(),
119 [intersection](std::pair<Node*, std::list<NeighborNodes>> entry)
120 {
return intersection == QPointF((*entry.first)[0], (*entry.first)[1]);});
121 if (owner == newOwners.end()) {
123 assert(mesh->GetEdgeOwners(edge).size() > 0 &&
"Edge doesn't exist in the mesh.");
125 auto newNode = mesh->BuildNode({{intersection.x(), intersection.y(), 0}}, mesh->IsAtBoundary(&edge));
126 assert(newOwners.find(newNode) == newOwners.end() &&
"The created node already existed.");
128 newOwners[newNode] = std::list<NeighborNodes>();
130 if (std::find_if(newOwners[newNode].begin(), newOwners[newNode].end(),
132 == newOwners[newNode].end()) {
134 newOwners[newNode].push_back(
138 newNodes[cell].push_back(newNode);
141 newNodes[cell].push_back(owner->first);
146 }
while (++node != cell->GetNodes().begin());
149 for (
auto entry : newOwners) {
150 for (
auto nb : entry.second) {
156 std::list<Wall*> tmpWalls;
157 for (
auto cell : cellsToBeSliced) {
158 for (
Wall* w : cell->GetWalls()) {
159 if (std::find(tmpWalls.begin(), tmpWalls.end(), w) == tmpWalls.end()) {
160 tmpWalls.push_back(w);
161 mesh->UpdateNodeOwningWalls(w);
168 auto cmp = [
this](
Node* p1,
Node* p2) {
169 return pow(m_cut.p1().x() - (*p1)[0], 2) + pow(m_cut.p1().y() - (*p1)[1], 2)
170 < pow(m_cut.p1().x() - (*p2)[0], 2) + pow(m_cut.p1().y() - (*p2)[1], 2);
174 auto contains_point = [
this](
const QPointF& p) {
175 QPolygonF rect(QRectF(p.x() - g_accuracy / 4, p.y() - g_accuracy / 4, g_accuracy / 2, g_accuracy / 2));
176 return (polygon().contains(p) || polygon().containsPoint(p, Qt::OddEvenFill) || polygon().intersected(rect).size() > 0);
180 auto it = newNodes.begin();
181 while (it != newNodes.end()) {
182 std::list<Cell*> currentCells({it->first});
183 auto& nodes = it->second;
184 if (nodes.size() > 1) {
186 auto current = nodes.begin();
188 while (
next != nodes.end()) {
189 auto currentCell = std::find_if(currentCells.begin(), currentCells.end(), [current,
next](
Cell* c){
190 auto first = std::find(c->GetNodes().begin(), c->GetNodes().end(), *current);
191 auto second = std::find(c->GetNodes().begin(), c->GetNodes().end(), *
next);
192 return (first != c->GetNodes().end() && second != c->GetNodes().end());
195 if (currentCell != currentCells.end()) {
196 std::vector<Cell*> newCells = m_tissue->SplitCell(*currentCell, *current, *
next);
197 if (newCells.size() > 1) {
198 assert(newCells.size() == 2 &&
"The cell should be split into two parts.");
200 currentCells.erase(currentCell);
201 currentCells.push_back(newCells.front());
202 currentCells.push_back(newCells.back());
204 current = nodes.erase(current);
219 for (
auto c : currentCells) {
220 Node* nonCutNode =
nullptr;
221 for (
auto n : c->GetNodes()) {
222 if (std::find(nodes.begin(), nodes.end(), n) == nodes.end()) {
227 assert(nonCutNode !=
nullptr &&
"There has to be at least one node in this cell that isn't located on the cut.");
229 if (!contains_point(QPointF((*nonCutNode)[0], (*nonCutNode)[1]))) {
230 cellsToBeDeleted.push_back(c);
237 m_tissue->DeleteCells(cellsToBeDeleted);
A cell contains walls and nodes.
Namespace for SimPT tissue editor package.
Cell * GetCell() const
Return the cell of this Neighbor pair.
Combo header for circular iterator.
Namespace for SimPT shell package.
see the online Qt documentation
Interface for NeighborNodes.
Namespace for the core simulator.
An Edge connects two nodes and is ambidextrous.
Namespace for container related classes.
SliceItem(const QPolygonF &polygon, const QLineF &cut, std::shared_ptr< EditControlLogic > tissue, QGraphicsScene *scene)
Constructor.
virtual ~SliceItem()
Destructor.
Node * GetNb1() const
Return first node of this Neighbor pair.
Structure of neighboring nodes: two neighboring nodes from standpoint of a given cell with an orderin...
Node * GetNb2() const
Return second node of this Neighbor pair.
CircularIterator< T > next(CircularIterator< T > i)
Helper yields the position the iterator would have if moved forward (in circular fashion) by 1 positi...
ConstCircularIterator< typename T::const_iterator > make_const_circular(const T &c)
Helper produces const circular iterator whose range corresponds to the begin and end iterators of a c...
A cell wall, runs between cell corner points and consists of wall elements.