Files @ 121f7720db62
Branch filter:

Location: EI/VirtualLeaf/src/wall.cpp

Michael Guravage
Removed references to XMLWriteLeafSourceCode and XMLWriteReactionsCode.

--
user: Michael Guravage <michael.guravage@cwi.nl>
branch 'default'

changed src/ChangeLog
changed src/VirtualLeaf.pro
changed src/xmlwrite.cpp
changed src/xmlwrite.h
removed src/xmlwritecode.cpp
/*
 *
 *  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 <http://www.gnu.org/licenses/>.
 *
 *  Copyright 2010 Roeland Merks.
 *
 */

#include <string>
#include "wall.h"
#include "cell.h"
#include "wallitem.h"
#include "node.h"
#include "apoplastitem.h"
#include <algorithm>
#include <QGraphicsScene>

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<CellBase *> 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<CellBase *> wall_owners;
	owners.sort();
	//transform(owners.begin(), owners.end(), ostream_iterator<int>(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<int>(cerr, ", "), mem_fun(&Cell::Index));
	 cerr << endl;
	 */
	
	//list<Cell *>::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 */) {
		
	        #ifdef QDEBUG
	        qDebug() << "nwalls = " << nwalls << endl;
		#endif
		// special case for first cleavage
		
		// find boundary polygon in the wall owners list
		list<CellBase *>::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<int>(qDebug(), "  "), mem_fun (&CellBase::Index) );
		  qDebug() << endl;
		  qDebug() << "Owners node " << n1->Index() << ": ";
		  for (list<Neighbor>::iterator i = n1->owners.begin(); i!=n1->owners.end(); i++) {
		    qDebug() << i->getCell()->Index() << " ";
		  }
		  qDebug() << endl;
		  qDebug() << "Owners node " << n2->Index() << ": ";
			
		  for (list<Neighbor>::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->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("");
}