diff --git a/src/wall.cpp b/src/wall.cpp new file mode 100644 --- /dev/null +++ b/src/wall.cpp @@ -0,0 +1,237 @@ +/* + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Virtual Leaf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Virtual Leaf. If not, see . + * + * Copyright 2010 Roeland Merks. + * + */ + +#include +#include "wall.h" +#include "cell.h" +#include "wallitem.h" +#include "node.h" +#include "apoplastitem.h" +#include +#include + +static const std::string _module_id("$Id$"); + +/*! Check if this Wall still belongs to Cell a, otherwise gives it to Cell b. + \return true: Wall was corrected + \return false: Wall was still correct + */ +bool Wall::CorrectWall( void ) { + + + // collect all cells to which my nodes are connected on one list + list owners; + transform(n1->owners.begin(),n1->owners.end(), back_inserter(owners), mem_fun_ref(&Neighbor::getCell)); + transform(n2->owners.begin(),n2->owners.end(), back_inserter(owners), mem_fun_ref(&Neighbor::getCell)); + + // get the list of duplicates + list wall_owners; + owners.sort(); + //transform(owners.begin(), owners.end(), ostream_iterator(cerr, ", "), mem_fun(&Cell::Index)); + duplicates_copy( owners.begin(), owners.end(), back_inserter(wall_owners) ); + + // duplicates are the cells to which the Wall belongs + /* cerr << "Wall belongs to Cells: "; + transform(wall_owners.begin(), wall_owners.end(), ostream_iterator(cerr, ", "), mem_fun(&Cell::Index)); + cerr << endl; + */ + + //list::iterator f = adjacent_find (++e,owners.end()); + + // For the first division, wall finds three "owners", including the boundary_polygon. + // Remove that one from the list. + //cerr << "wall_owners.size() = " << wall_owners.size() << endl; + if (wall_owners.size() == 3 && nwalls==1 /* bug-fix 22/10/2007; confine this condition to first division only */) { + + cerr << "nwalls = " << nwalls << endl; + // special case for first cleavage + + // find boundary polygon in the wall owners list + list::iterator bpit = find_if ( + wall_owners.begin(), wall_owners.end(), + mem_fun( &CellBase::BoundaryPolP ) + ); + + if (bpit!=wall_owners.end()) { + + // add a Wall with the boundary_polygon to each cell + Wall *bp_wall1 = new Wall( n2, n1, c1, (*bpit) ); + bp_wall1->CopyWallContents(*this); + ((Cell *)c1)->AddWall( bp_wall1); + ((Cell *)(*bpit))->AddWall(bp_wall1); + + Wall *bp_wall2 = new Wall( n1, n2, c2, (*bpit) ); + bp_wall2->CopyWallContents(*this); + ((Cell *)c2)->AddWall( bp_wall2); + ((Cell *)(*bpit))->AddWall(bp_wall2); + + wall_owners.erase(bpit); + + }else { + + cerr << "Wall::CorrectWall says: Wall has three owners, but none of them is the BoundaryPolygon. I have no clue what to do with this case... Sorry!\n"; + cerr << "Wall: " << *this << endl; + cerr << "Owners are: "; + transform(wall_owners.begin(), wall_owners.end(), ostream_iterator(cerr, " "), mem_fun (&CellBase::Index) ); + cerr << endl; + cerr << "Owners node " << n1->Index() << ": "; + for (list::iterator i = n1->owners.begin(); + i!=n1->owners.end(); + i++) { + cerr << i->getCell()->Index() << " "; + } + cerr << endl; + cerr << "Owners node " << n2->Index() << ": "; + + for (list::iterator i = n2->owners.begin(); + i!=n2->owners.end(); + i++) { + cerr << i->getCell()->Index() << " "; + } + cerr << endl; + std::exit(1); + } + + } + + if (wall_owners.size() == 1) { + cerr << "Corner point. Special case.\n"; + } + + CellBase *cell1 = wall_owners.front(); + CellBase *cell2 = wall_owners.back(); + + if ( (c1 == cell1 && c2==cell2) || (c1 == cell2 && c2 == cell1) ) { + + return false; + } + + if ( c1 == cell1 ) { + //cerr << "Block 1\n"; + ((Cell *)c2) -> RemoveWall(this); + c2 = cell2; + ((Cell *)c2) -> AddWall(this); + } else { + if ( c1 == cell2 ) { + // cerr << "Block 2\n"; + ((Cell *)c2) -> RemoveWall(this); + c2 = cell1; + ((Cell *)c2) -> AddWall(this); + } else { + if ( c2 == cell1) { + ((Cell *)c1)->RemoveWall(this); + c1 = cell2; + ((Cell *)c1) -> AddWall(this); + // cerr << "Block 3\n"; + } else { + if ( c2 == cell2) { + ((Cell *)c1)->RemoveWall(this); + c1 = cell1; + ((Cell *)c1)->AddWall(this); + // cerr << "Block 3\n"; + } else { + cerr << "Warning, cell wall was not corrected.\n"; + return false; + } + } + } + } + + return true; + + + + +} + +void Wall::Draw(QGraphicsScene *c) { + + WallItem *wi1 = new WallItem(this, 1, c); + WallItem *wi2 = new WallItem(this, 2, c); + wi1->show(); + wi2->show(); + +} + +void Wall::DrawApoplast(QGraphicsScene *c) { + ApoplastItem *apo = new ApoplastItem(this, c); + apo->show(); + +} + +void Wall::ShowStructure(QGraphicsScene *c) { + + Vector offset = Cell::Offset(); + double factor = Cell::Factor(); + + Vector startpoint ( ((offset.x+n1->x)*factor),((offset.y+n1->y)*factor)), + endpoint (((offset.x+n2->x)*factor),((offset.y+n2->y)*factor)); + + Vector linevec = endpoint - startpoint; + Vector midline = startpoint + linevec/2.; + Vector perpvec = linevec.Normalised().Perp2D(); + Vector textpos1 = midline + 100 * perpvec; + Vector textpos2 = midline - 100 * perpvec; + + QGraphicsLineItem *line = new QGraphicsLineItem(0,c); + + line->setPen( QPen(QColor(par.arrowcolor),2) ); + line->setLine(startpoint.x, startpoint.y, endpoint.x, endpoint.y ); + line->setZValue(10); + line->show(); + + QGraphicsSimpleTextItem *text1 = new QGraphicsSimpleTextItem( QString("%1").arg(c2->Index()),0,c); + QGraphicsSimpleTextItem *text2 = new QGraphicsSimpleTextItem( QString("%1").arg(c1->Index()),0,c); + + text1 -> setPos( textpos1.x, textpos1.y ); + text2 -> setPos( textpos2.x, textpos2.y ); + text1->setZValue(20); text2->setZValue(20); + + text1->setFont( QFont( "Helvetica", par.nodenumsize, QFont::Bold) ); + text2->setFont( QFont( "Helvetica", par.nodenumsize, QFont::Bold) ); + + text1->setPen ( QColor(par.textcolor) ); + text2->setPen ( text1->pen() ); + + //text1->setTextFlags(Qt::AlignCenter); + //text2->setTextFlags(Qt::AlignCenter); + text1->show(); text2->show(); + +} +string Wall::WallTypetoStr(const WallType &wt) const { + + if (wt == Normal) { + return string("normal"); + } + + if (wt == AuxSource) { + return string("aux_source"); + } + + if (wt == AuxSink) { + return string("aux_sink"); + } + + return string(""); +} + + +