/*
*
* 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
// 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 */) {
#ifdef QDEBUG
qDebug() << "nwalls = " << nwalls << endl;
#endif
// 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 {
#ifdef QDEBUG
qDebug() << "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!" << endl;
qDebug() << "Wall: " << *this << endl;
qDebug() << "Owners are: ";
transform(wall_owners.begin(), wall_owners.end(), ostream_iterator(qDebug(), " "), mem_fun (&CellBase::Index) );
qDebug() << endl;
qDebug() << "Owners node " << n1->Index() << ": ";
for (list::iterator i = n1->owners.begin(); i!=n1->owners.end(); i++) {
qDebug() << i->getCell()->Index() << " ";
}
qDebug() << endl;
qDebug() << "Owners node " << n2->Index() << ": ";
for (list::iterator i = n2->owners.begin(); i!=n2->owners.end(); i++) {
qDebug() << i->getCell()->Index() << " ";
}
qDebug() << endl;
#endif
std::exit(1);
}
}
#ifdef QDEBUG
if (wall_owners.size() == 1) {
qDebug() << "Corner point. Special case." << endl;
}
#endif
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 {
#ifdef QDEBUG
qDebug() << "Warning, cell wall was not corrected." << endl;
#endif
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->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("");
}