Changeset - 18e4f7f50259
[Not reviewed]
default
0 14 0
Michael Guravage - 15 years ago 2010-06-15 11:06:33
michael.guravage@cwi.nl
Wrapped diagnostic messages in QDEBUG blocks. Information messages still go to stderr.

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

changed src/ChangeLog
changed src/VirtualLeaf.cpp
changed src/build_models/Makefile
changed src/canvas.cpp
changed src/cell.cpp
changed src/cellbase.h
changed src/data_plot.cpp
changed src/forwardeuler.cpp
changed src/mesh.cpp
changed src/mesh.h
changed src/random.cpp
changed src/wall.cpp
changed src/wallbase.cpp
changed src/wallitem.cpp
14 files changed with 368 insertions and 277 deletions:
0 comments (0 inline, 0 general)
src/ChangeLog
Show inline comments
 
2010-06-15    <guravage@caterpie.sen.cwi.nl>
 

	
 
	* cell.cpp: Wrapped diagnostic output in QDEBUG blocks.
 
	* VirtualLeaf.cpp ditto.
 
	* canvas.cpp ditto.
 
	* cell.cpp ditto.
 
	* cellbase.h
 
	* data_plot.cpp ditto.
 
	* forwardeuler.cpp ditto.
 
	* mesh.cpp ditto.
 
	* mesh.h
 
	* random.cpp ditto.
 
	* wall.cpp ditto.
 
	* wallbase.cpp ditto.
 
	* wallitem.cpp ditto.
 

	
 

	
 
2010-06-07    <guravage@caterpie.sen.cwi.nl>
 

	
 
	* VirtualLeaf.pro: Removed explicit perl invocation to regerenerate parameter files.
 
	* libplugin.pro: ditto.
 

	
 
2010-06-03    <guravage@caterpie.sen.cwi.nl>
 

	
 
	* pardialog.h: Added default versions of this automatically generated file.
 
	* pardialog.cpp: ditto.
 
	* parameter.h: ditto.
 
	* parameter.cpp: ditto.
 

	
src/VirtualLeaf.cpp
Show inline comments
 
@@ -49,37 +49,36 @@
 
#ifdef HAVE_QWT
 
#include "data_plot.h"
 
#endif
 
#include <QPalette>
 
#include <QBrush>
 
#include <QToolTip>
 
#include "simplugin.h"
 
#include <QPluginLoader>
 
#include <QDir>
 
#include "modelcatalogue.h"
 

	
 
/* #define _xstr_(s) _str_(s)
 
#define _str_(s) #s
 
#include _xstr_(REACTIONS_HEADER)
 
   #define _str_(s) #s
 
   #include _xstr_(REACTIONS_HEADER)
 
*/
 

	
 
static const std::string _module_id("$Id$");
 

	
 
extern Parameter par;
 

	
 
MainBase *main_window = 0;
 
//double auxin_account = 0.;
 

	
 

	
 

	
 
#ifdef XFIGGRAPHICS
 
#define TIMESTEP double Graphics::TimeStep(void)
 
#endif
 

	
 
class PrintNode {
 
public:
 
  void operator() (const Node &n) const 
 
  {
 
    cerr << n.Index() << ": " << n <<  endl;
 
  }
 
};
 

	
 
@@ -87,181 +86,168 @@ public:
 
class EdgeSource {
 
	
 
public:
 
  void operator() (Cell &c) {
 
		
 
    if (c.AtBoundaryP()) {
 
      cerr << "Cell " << c.Index() << " is a source cell.\n";
 
      c.SetSource(0,par.source);
 
    } else {
 
      cerr << "Cell " << c.Index() << " is _not_ a source cell.\n";
 
    }
 
  }
 
	
 
};
 

	
 

	
 

	
 
class CellInfo {
 
public:
 
  void operator() (Cell &c,std::ostream &os) const {
 
    os << "Cell " << c.index << " says: " << endl;
 
    os << "c.nodes.size() = " << c.nodes.size() << endl;
 
    for (list<Node *>::iterator i=c.nodes.begin();
 
	 i!=c.nodes.end();
 
	 i++) {
 
      cerr << (*i)->Index() << " ";
 
    }
 
    cerr << endl;
 
  }
 
};
 

	
 
double PINSum(Cell &c) {
 
	
 
	return c.Chemical(1) + c.SumTransporters(1);// + c.ReduceCellAndWalls<double>( complex_PijAj );
 
	
 
  return c.Chemical(1) + c.SumTransporters(1);// + c.ReduceCellAndWalls<double>( complex_PijAj );
 
}
 

	
 

	
 
class DrawCell {
 
public:
 
  void operator() (Cell &c,QGraphicsScene &canvas, MainBase &m) const {
 
    if (m.ShowBorderCellsP() || c.Boundary()==Cell::None) {
 
      if (!m.ShowBoundaryOnlyP() && !m.HideCellsP()) 
 
	if (m.ShowToolTipsP()) {
 
	  QString info_string=QString("Cell %1, chemicals: ( %2, %3, %4, %5, %6)\n %7 of PIN1 at walls.\n Area is %8\n PIN sum is %9\n Circumference is %10\n Boundary type is %11").arg(c.Index()).arg(c.Chemical(0)).arg(c.Chemical(1)).arg(c.Chemical(2)).arg(c.Chemical(3)).arg(c.Chemical(4)).arg(c.SumTransporters(1)).arg(c.Area()).arg(PINSum(c)).arg(c.Circumference()).arg(c.BoundaryStr());
 
					
 
	  info_string += "\n" + c.printednodelist();
 
					
 
	  c.Draw(&canvas, info_string);
 
	} else {
 
	  c.Draw(&canvas);
 
	}
 
      if (m.ShowCentersP())
 
	c.DrawCenter(&canvas);
 
    if (m.ShowFluxesP())
 
      if (m.ShowFluxesP())
 
	c.DrawFluxes(&canvas, par.arrowsize);
 
			
 
       }
 
 
 
    }
 
  }
 
	
 
};
 

	
 
Mesh mesh;
 
bool batch=false;
 

	
 

	
 
void MainBase::Plot(int resize_stride) {
 
	
 
  clear();
 
    
 
	
 
  static int count=0;
 
  if (resize_stride) {
 
    if ( !((++count)%resize_stride) ) {
 
      FitLeafToCanvas();
 
    }
 
  }
 
  mesh.LoopCells(DrawCell(),canvas,*this);
 
	
 
  if (ShowNodeNumbersP()) 
 
    mesh.LoopNodes( bind2nd (mem_fun_ref ( &Node::DrawIndex), &canvas ) ) ;
 
  if (ShowCellNumbersP()) 
 
    mesh.LoopCells( bind2nd (mem_fun_ref ( &Cell::DrawIndex), &canvas ) ) ;
 
	
 
  if (ShowCellAxesP()) 
 
    mesh.LoopCells( bind2nd (mem_fun_ref ( &Cell::DrawAxis), &canvas ) );
 
	
 
  if (ShowCellStrainP()) 
 
    mesh.LoopCells( bind2nd (mem_fun_ref ( &Cell::DrawStrain), &canvas ) );
 
	
 
  if (ShowWallsP())
 
  
 
    mesh.LoopWalls( bind2nd( mem_fun_ref( &Wall::Draw ), &canvas ) );
 
	
 
	if (ShowApoplastsP()) 
 
		mesh.LoopWalls( bind2nd( mem_fun_ref( &Wall::DrawApoplast ), &canvas ) );
 
  if (ShowApoplastsP()) 
 
    mesh.LoopWalls( bind2nd( mem_fun_ref( &Wall::DrawApoplast ), &canvas ) );
 
 
 
	if (ShowMeshP()) 
 
  if (ShowMeshP()) 
 
    mesh.DrawNodes(&canvas);
 
	
 
  if (ShowBoundaryOnlyP()) 
 
    mesh.DrawBoundary(&canvas);
 

	
 
  
 
	if ( ( batch || MovieFramesP() )) {
 
  if ( ( batch || MovieFramesP() )) {
 
		
 
		static int frame = 0;
 
		// frame numbers are sequential for the most frequently written file type.
 
		// for the less frequently written file type they match the other type
 
		if (!(count%par.storage_stride) )  {
 
    static int frame = 0;
 
    // frame numbers are sequential for the most frequently written file type.
 
    // for the less frequently written file type they match the other type
 
    if (!(count%par.storage_stride) )  {
 
		
 
			stringstream fname;
 
			fname << par.datadir << "/leaf.";
 
			fname.fill('0');
 
			fname.width(6);
 
      stringstream fname;
 
      fname << par.datadir << "/leaf.";
 
      fname.fill('0');
 
      fname.width(6);
 
	
 
			/* 
 
			 fname << frame << ".pdf";
 
			if (par.storage_stride <= par.xml_storage_stride) {
 
				frame++;
 
			}
 
      /* 
 
	 fname << frame << ".pdf";
 
	 if (par.storage_stride <= par.xml_storage_stride) {
 
	 frame++;
 
	 }
 
			
 
			// Write high-res JPG snapshot every plot step
 
			Save(fname.str().c_str(), "PDF");
 
			*/
 
	 // Write high-res JPG snapshot every plot step
 
	 Save(fname.str().c_str(), "PDF");
 
      */
 
			
 
			fname << frame << ".jpg";
 
			if (par.storage_stride <= par.xml_storage_stride) {
 
				frame++;
 
			}
 
      fname << frame << ".jpg";
 
      if (par.storage_stride <= par.xml_storage_stride) {
 
	frame++;
 
      }
 
			
 
			// Write high-res JPG snapshot every plot step
 
			Save(fname.str().c_str(), "JPEG",1024,768);
 
			
 
		}
 
      // Write high-res JPG snapshot every plot step
 
      Save(fname.str().c_str(), "JPEG",1024,768);
 
    }
 
	
 
		if (!(count%par.xml_storage_stride)) {
 
			stringstream fname;
 
			fname << par.datadir << "/leaf.";
 
			fname.fill('0');
 
			fname.width(6);
 
			fname << frame << ".xml";
 
    if (!(count%par.xml_storage_stride)) {
 
      stringstream fname;
 
      fname << par.datadir << "/leaf.";
 
      fname.fill('0');
 
      fname.width(6);
 
      fname << frame << ".xml";
 
	
 
			if (par.xml_storage_stride < par.storage_stride) {
 
				frame++;
 
			}
 
			// Write XML file every ten plot steps
 
			mesh.XMLSave(fname.str().c_str(), XMLSettingsTree());
 
		}
 
		
 
	}
 
      if (par.xml_storage_stride < par.storage_stride) {
 
	frame++;
 
      }
 
      // Write XML file every ten plot steps
 
      mesh.XMLSave(fname.str().c_str(), XMLSettingsTree());
 
    }
 
  }
 
}
 

	
 

	
 

	
 
INIT {
 
	
 
	//mesh.SetSimPlugin(plugin);
 
	if (leaffile) { 
 
		xmlNode *settings;
 
		mesh.XMLRead(leaffile, &settings);
 
  //mesh.SetSimPlugin(plugin);
 
  if (leaffile) { 
 
    xmlNode *settings;
 
    mesh.XMLRead(leaffile, &settings);
 
		
 
    main_window->XMLReadSettings(settings);
 
    xmlFree(settings);
 
    main_window->UserMessage(QString("Ready. Time is %1").arg(mesh.getTimeHours().c_str()));
 
		
 
  } else {
 
	  mesh.StandardInit();
 
    mesh.StandardInit();
 
  }
 
}
 

	
 
TIMESTEP {
 
	
 
  static int i=0;
 
  static int t=0;
 
  static int ncells;
 
	
 
  if (!batch) {
 
    UserMessage(QString("Time: %1").arg(mesh.getTimeHours().c_str()),0);
 
  }
 
@@ -274,116 +260,111 @@ TIMESTEP {
 
  if(DynamicCellsP()) {
 
    dh = mesh.DisplaceNodes();
 
			
 
    // Only allow for node insertion, cell division and cell growth
 
    // if the system has equillibrized
 
    // i.e. cell wall tension equillibrization is much faster
 
    // than biological processes, including division, cell wall yielding
 
    // and cell expansion
 
    mesh.InsertNodes(); // (this amounts to cell wall yielding)
 
			
 
    if ( (-dh) < par.energy_threshold) {
 
				
 
		mesh.IncreaseCellCapacityIfNecessary();
 
		mesh.DoCellHouseKeeping();
 
		//mesh.LoopCurrentCells(mem_fun(&plugin->CellHouseKeeping)); // this includes cell division
 
      mesh.IncreaseCellCapacityIfNecessary();
 
      mesh.DoCellHouseKeeping();
 
      //mesh.LoopCurrentCells(mem_fun(&plugin->CellHouseKeeping)); // this includes cell division
 
				
 
      // Reaction diffusion	
 
		/*CelltoCellTransport *transport_f = &TestPlugin::CelltoCellTransport;
 
      CellReaction *cellreaction_f = new plugin->CellDynamics();
 
      WallReaction *wall_f = new WallDynamics();*/
 
      /*CelltoCellTransport *transport_f = &TestPlugin::CelltoCellTransport;
 
	CellReaction *cellreaction_f = new plugin->CellDynamics();
 
	WallReaction *wall_f = new WallDynamics();*/
 
				
 
      mesh.ReactDiffuse(par.rd_dt);
 
		
 
				
 
      t++;
 
				
 
      Plot(par.resize_stride);
 
		
 
		/*QVector< QPair<double, int> > angles=mesh.VertexAnglesValues();
 
		QString afname=QString("Angles/anglesvalues%1.dat").arg(t,6,10,QChar('0'));
 
		ofstream af(afname.toStdString().c_str());
 
		*/
 
      /*QVector< QPair<double, int> > angles=mesh.VertexAnglesValues();
 
	QString afname=QString("Angles/anglesvalues%1.dat").arg(t,6,10,QChar('0'));
 
	ofstream af(afname.toStdString().c_str());
 
      */
 
		
 
		/*for (QVector< QPair<qreal, int> >::const_iterator v=angles.begin();
 
			 v!=angles.end();
 
			 v++) {
 
			af << v->first << " " << v->second << endl;
 
			}
 
			*/
 
			}
 
      /*for (QVector< QPair<qreal, int> >::const_iterator v=angles.begin();
 
	v!=angles.end();
 
	v++) {
 
	af << v->first << " " << v->second << endl;
 
	}
 
      */
 
    }
 
		
 
			} else {
 
  } else {
 
			
 
  /*  TransportFunction *transport_f = new CelltoCellTransport();
 
    CellReaction *cellreaction_f = new CellDynamics();
 
    WallReaction *wall_f = new WallDynamics();
 
    /*  TransportFunction *transport_f = new CelltoCellTransport();
 
	CellReaction *cellreaction_f = new CellDynamics();
 
	WallReaction *wall_f = new WallDynamics();
 
			
 
    mesh.ReactDiffuse_New(transport_f, cellreaction_f, wall_f, par.rd_dt);*/
 
				mesh.ReactDiffuse(par.rd_dt);
 
	mesh.ReactDiffuse_New(transport_f, cellreaction_f, wall_f, par.rd_dt);*/
 
    mesh.ReactDiffuse(par.rd_dt);
 
		
 
    Plot(par.resize_stride);
 
			
 
  }
 
	
 
	
 

	
 
		
 
		
 
  i++;
 
  return mesh.getTime();
 
		
 
}
 
		
 
		
 
				
 
/* Called if a cell is clicked */
 
void Cell::OnClick(QMouseEvent *e) {
 
  /* #ifdef HAVE_QWT
 
	// Launch DataPlot window
 
	QStringList curvenames;
 
    for (int i=0;i<NChem();i++) {
 
		curvenames += QString("Chem #%1").arg(i);
 
	}
 
    PlotDialog *plot = new PlotDialog((Main *)main_window, QString("Monitor for Cell %1").arg(Index()), curvenames);
 
    QObject::connect(this, SIGNAL(ChemMonValue(double, double *)),
 
                     plot, SLOT(AddValue(double,double *)));
 
#endif
 
	*/
 
	//getMesh().plugin->OnClick(*this);
 
  // Launch DataPlot window
 
  QStringList curvenames;
 
  for (int i=0;i<NChem();i++) {
 
  curvenames += QString("Chem #%1").arg(i);
 
  }
 
  PlotDialog *plot = new PlotDialog((Main *)main_window, QString("Monitor for Cell %1").arg(Index()), curvenames);
 
  QObject::connect(this, SIGNAL(ChemMonValue(double, double *)),
 
  plot, SLOT(AddValue(double,double *)));
 
  #endif
 
  */
 
  //getMesh().plugin->OnClick(*this);
 
}
 
				
 

	
 
/* Custom message handler - Default appends a newline character to the end of each line. */ 
 
 void vlMessageOutput(QtMsgType type, const char *msg)
 
 {
 
     switch (type) {
 
     case QtDebugMsg:
 
       //fprintf(stderr, "Debug: %s\n", msg);
 
       cerr << msg << flush;
 
       break;
 
     case QtWarningMsg:
 
       //fprintf(stderr, "Warning: %s\n", msg);
 
       cerr << "Warning: " << msg << flush;
 
       break;
 
     case QtCriticalMsg:
 
       fprintf(stderr, "Critical: %s\n", msg);
 
       cerr << "Critical: " << msg << flush;
 
       break;
 
     case QtFatalMsg:
 
       //fprintf(stderr, "Fatal: %s\n", msg);
 
       cerr << "Fatal: " << msg << flush;
 
       abort();
 
     }
 
 }
 
void vlMessageOutput(QtMsgType type, const char *msg)
 
{
 
  switch (type) {
 
  case QtDebugMsg:
 
    //fprintf(stderr, "Debug: %s\n", msg);
 
    cerr << msg << flush;
 
    break;
 
  case QtWarningMsg:
 
    //fprintf(stderr, "Warning: %s\n", msg);
 
    cerr << "Warning: " << msg << flush;
 
    break;
 
  case QtCriticalMsg:
 
    fprintf(stderr, "Critical: %s\n", msg);
 
    cerr << "Critical: " << msg << flush;
 
    break;
 
  case QtFatalMsg:
 
    //fprintf(stderr, "Fatal: %s\n", msg);
 
    cerr << "Fatal: " << msg << flush;
 
    abort();
 
  }
 
}
 
				
 

	
 
Parameter par;
 
				
 
int main(int argc,char **argv) {
 
					
 
  try {
 
						
 

	
 
    int c;
 

	
 
						
 
@@ -461,76 +442,73 @@ int main(int argc,char **argv) {
 

	
 
    
 
    QPalette tooltippalette = QToolTip::palette();
 
    QColor transparentcolor = QColor(tooltippalette.brush(QPalette::Window).color());
 

	
 
    tooltippalette.setBrush (QPalette::Window, QBrush (transparentcolor) );
 
    QToolTip::setPalette( tooltippalette );
 

	
 
    QGraphicsScene canvas(0,0,8000,6000);
 

	
 
	  
 
    if (useGUI) {
 
         main_window=new Main(canvas, mesh);
 
      main_window=new Main(canvas, mesh);
 
      if ( QApplication::desktop()->width() > ((Main *)main_window)->width() + 10
 
	   && QApplication::desktop()->height() > ((Main *)main_window)->height() +30 ) {
 

	
 
	((Main *)main_window)->show();
 
	((Main *)main_window)->resize( ((Main *)main_window)->sizeHint());
 
      } else {
 
        ((Main *)main_window)->showMaximized();
 
      }
 
    } else {
 
        ((Main *)main_window)->showMaximized();
 
      main_window=new MainBase(canvas, mesh);
 

	
 
    }
 
  } else {
 
        main_window=new MainBase(canvas, mesh);
 

	
 
 }
 

	
 
    
 
	  
 
    canvas.setSceneRect(QRectF());
 
    if (!batch) {
 
      QObject::connect( qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()) );
 
    }
 

	
 
	  // Load plugins
 
	  /*QVector<SimPluginInterface *> plugins = LoadPlugins();
 
	  InstallPlugin(plugins[0], main_window);
 
    // Load plugins
 
    /*QVector<SimPluginInterface *> plugins = LoadPlugins();
 
      InstallPlugin(plugins[0], main_window);
 
	  
 
	  cerr << "List of models:" << endl;
 
	  foreach (SimPluginInterface *p, plugins) {
 
		  cerr << p->ModelID().toStdString() << endl;
 
	  }
 
	  */
 
      cerr << "List of models:" << endl;
 
      foreach (SimPluginInterface *p, plugins) {
 
      cerr << p->ModelID().toStdString() << endl;
 
      }
 
    */
 

	
 
	 	  
 
    // Install model or read catalogue of models
 
    ModelCatalogue model_catalogue(&mesh, useGUI?(Main *)main_window:0,modelfile);
 
    if (useGUI)
 
      model_catalogue.PopulateModelMenu();
 
    model_catalogue.InstallFirstModel();
 
    
 

	
 
    if (leaffile) 
 
      main_window->Init(leaffile);
 
	  
 
    Cell::SetMagnification(1);
 
    Cell::setOffset(0,0);
 
						
 
    main_window->FitLeafToCanvas();
 
							
 
						
 
    main_window->Plot();
 

	
 
						
 

	
 
    if (batch) {
 
      double t=0.;
 
      do {
 
	t = main_window->TimeStep();
 
      } while (t < par.maxt);
 
							
 
    } else
 
      return app.exec();
 
	  
 
						
 
  } catch (const char *message) {
 
    if (batch) { 
 
@@ -545,14 +523,13 @@ int main(int argc,char **argv) {
 
  } catch (ios_base::failure) {
 
    stringstream error_message;
 
    error_message << "I/O failure: " << strerror(errno);
 
    if (batch) {
 
      cerr << error_message.str() <<endl;
 
      abort();
 
    } else {
 
      QString qmess(error_message.str().c_str());
 
      QMessageBox::critical(0, "I/O Error", qmess );
 
      abort();
 
    }
 
  }
 
					
 
}
src/build_models/Makefile
Show inline comments
 
# $Id$
 

	
 
QMAKE = qmake
 

	
 
all: plugin_auxingrowth plugin_leaf plugin_meinhardt plugin_test
 
all: plugin_auxingrowth plugin_meinhardt plugin_test
 

	
 
plugin_auxingrowth: Makefile.plugin_auxingrowth
 
	make -f Makefile.plugin_auxingrowth
 

	
 
Makefile.plugin_auxingrowth: plugin_auxingrowth.pro
 
	$(QMAKE) -makefile -o $@ $< 
 

	
 
plugin_leaf: Makefile.plugin_leaf
 
	make -f Makefile.plugin_leaf
 

	
 
Makefile.plugin_leaf: plugin_leaf.pro
 
	$(QMAKE) -makefile -o $@ $< 
 

	
 
plugin_meinhardt: Makefile.plugin_meinhardt
 
	make -f Makefile.plugin_meinhardt
 

	
 
Makefile.plugin_meinhardt: plugin_meinhardt.pro
 
	$(QMAKE) -makefile -o $@ $< 
 

	
 
plugin_test: Makefile.plugin_test
 
	make -f Makefile.plugin_test
 

	
 
Makefile.plugin_test: plugin_test.pro
 
	$(QMAKE) -makefile -o $@ $< 
 

	
 
clean:
 
	make -f Makefile.plugin_auxingrowth clean
 
	make -f Makefile.plugin_leaf clean
 
	make -f Makefile.plugin_meinhardt clean
 
	make -f Makefile.plugin_test clean
 
	touch plugin_auxingrowth.pro
 
	touch plugin_leaf.pro
 
	touch plugin_meinhardt.pro
 
	touch plugin_test.pro
 

	
 
#finis
src/canvas.cpp
Show inline comments
 
@@ -34,24 +34,25 @@
 
#include <qprinter.h>
 
#include <qlabel.h>
 
#include <qimage.h>
 
#include <q3progressdialog.h>
 
#include <qtimer.h>
 
#include <qslider.h>
 
#include <qpixmap.h>
 
#include <qfile.h>
 
#include <qdir.h>
 
#include <q3filedialog.h>
 
#include <QGraphicsItem>
 
#include <QList>
 
#include <QDebug>
 

	
 
#include <set>
 

	
 
//Added by qt3to4:
 
#include <Q3ValueList>
 
#include <Q3PopupMenu>
 
#include <QMouseEvent>
 
#include <typeinfo>
 
#include <cstring>
 
#include <q3process.h>
 
#include <qlayout.h>
 
#include <qspinbox.h>
 
@@ -219,26 +220,28 @@ void FigureEditor::mousePressEvent(QMous
 
      intersection_line->setPen( QPen( QColor("red"), 3, Qt::DashLine ) );
 
      intersection_line->setLine( QLineF(p,p) );
 
      intersection_line->setZValue( 100 );
 
      intersection_line->show();
 
    }
 
  
 
    for (QList<QGraphicsItem *>::Iterator it=l.begin(); it!=l.end(); ++it) {
 
      /*if ( (*it)->rtti() == imageRTTI ) {
 
	ImageItem *item= (ImageItem*)(*it);
 
	if ( !item->hit( p ) )
 
	continue;
 
	}*/
 
      cerr << typeid(**it).name() << endl;
 
    
 
      #ifdef QDEBUG
 
      qDebug() << typeid(**it).name() << endl;
 
      #endif QDEBUG
 

	
 
      if ( !strcmp(typeid(**it).name(),"8NodeItem")) {
 
	//moving = dynamic_cast<NodeItem*>(*it);
 
	//moving = *it;
 
	//moving_start = p;
 
      
 
	stringstream data_strstream;
 
	data_strstream << (dynamic_cast<NodeItem*>(*it))->getNode();
 
	dynamic_cast<Main *>(parent())->UserMessage(QString(data_strstream.str().c_str()));
 
      
 
	(dynamic_cast<NodeItem*>(*it))->OnClick(e->button());
 
      }
 
      else 
 
@@ -339,38 +342,41 @@ void FigureEditor::mouseMoveEvent(QMouse
 
  
 
}
 

	
 
//void FigureEditor::contentsMouseReleaseEvent(QMouseEvent* e)
 
void FigureEditor::mouseReleaseEvent(QMouseEvent* e)
 
{
 
  
 
  emit MouseReleased();
 
  // intersection line for leaf was finished now.
 
  
 
  if (e->button()==Qt::LeftButton) { 
 
    if (intersection_line ) {
 
    
 
      cerr << "Trying to cut leaf\n";
 
      #ifdef QDEBUG
 
      qDebug() << "Trying to cut leaf" << endl;
 
      #endif
 
      QPointF sp = intersection_line -> line().p1(); // startpoint
 
      //QPointF ep = matrix().inverted().map(e->pos()); // endpoint
 
      QPointF ep = mapToScene(e->pos());
 

	
 
      intersection_line -> setLine( QLineF(sp, ep) ); 
 
      intersection_line -> show();
 

	
 
      vector <CellItem *> intersected_cells = getIntersectedCells();
 
    
 
      // no cells selected, do nothing
 
      if (intersected_cells.size()==0) {
 
	cerr << "No cells detected :-( \n";
 
        #ifdef QDEBUG
 
	qDebug() << "No cells detected :-(" << endl;
 
	#endif
 
	return;
 
      }
 
      
 
    
 
      Vector startpoint = Vector(sp.x(), sp.y()) / Cell::Factor() - Cell::Offset();
 
      Vector endpoint = Vector(ep.x(), ep.y()) / Cell::Factor() - Cell::Offset();
 
    
 
      // Mesh &m(intersected_cells.front()->getCell().getMesh());
 
      NodeSet *node_set = new NodeSet;
 
      
 
      for (vector<CellItem *>::iterator it = intersected_cells.begin();
 
	   it != intersected_cells.end();
 
@@ -379,32 +385,38 @@ void FigureEditor::mouseReleaseEvent(QMo
 
	//(*it)->Mark();
 
	(*it)->setBrush(QBrush("purple"));
 
       
 
	Cell &c=(*it)->getCell();
 
      
 
	// sometimes the cell hasn't properly divided yet before the
 
	// next division is called?  so check for it?  let's find a way
 
	// to do this later. Note that this functionality currently
 
	// might result in a segmentation fault for users who are
 
	// quickly dragging and releasing division lines...
 
	scene()->update();
 
	
 
	cerr << "Dividing Cell " << c.Index() << endl;
 
	#ifdef QDEBUG
 
	qDebug() << "Dividing Cell " << c.Index() << endl;
 
	#endif
 

	
 
	c.DivideOverGivenLine( startpoint, endpoint, true, node_set);
 
      }
 
      
 
      node_set->CleanUp();
 
      mesh.AddNodeSet(node_set);
 
      
 
      cerr << "Done DivideOverGivenLine\n";
 
      #ifdef QDEBUG
 
      qDebug() << "Done DivideOverGivenLine" << endl;
 
      #endif
 

	
 
      mesh.TestIllegalWalls();
 
      // Do the actual cutting and removing
 
      if (intersected_cells.size()) {
 
	//      Mesh &m(intersected_cells.front()->getCell().getMesh());
 
	mesh.CutAwayBelowLine( startpoint, endpoint ); 
 
	
 
	// Correct flags of nodeset
 
	for (
 
	     NodeSet::iterator i = node_set->begin(); 
 
	     i != node_set->end();
 
	     i++) {
 
	  (*i)->SetSAM();
 
@@ -416,38 +428,45 @@ void FigureEditor::mouseReleaseEvent(QMo
 
	//   If a cell attached to a NodeSet divides (with a division plane intersecting the node set), 
 
	//   we must insert a new node into the node set.
 
	// For now, we add a layer of "virtual cells" inbetween. 
 
	list<Cell *> cells_attached_to_nodeset = node_set->getCells();
 
	for ( list<Cell *>::iterator c = cells_attached_to_nodeset.begin();
 
	      c != cells_attached_to_nodeset.end(); 
 
	      c++) {
 
	  (*c)->SetBoundary(Cell::SAM);
 
	}
 

	
 

	
 

	
 
	cerr << "Done CutAwayBelowLine\n";
 
	#ifdef QDEBUG
 
	qDebug() << "Done CutAwayBelowLine" << endl;
 
	#endif
 
	mesh.TestIllegalWalls();
 
	mesh.RepairBoundaryPolygon();
 
	cerr << "Done RepairBoundaryPolygon\n";
 
	#ifdef QDEBUG
 
	qDebug() << "Done RepairBoundaryPolygon" << endl;
 
	#endif
 
	mesh.TestIllegalWalls();
 
	mesh.CleanUpWalls();
 
	cerr << "Done CleanUpWalls\n";
 
	#ifdef QDEBUG
 
	qDebug() << "Done CleanUpWalls" << endl;
 
	#endif
 
	mesh.TestIllegalWalls();
 
      }
 
      
 
      dynamic_cast<Main *>(parent())->Plot();
 
      
 
      cerr << "NodeSet of cutting line: " << *node_set << endl;
 

	
 
        #ifdef QDEBUG
 
	qDebug() << "NodeSet of cutting line: " << *node_set << endl;
 
	#endif
 
    }
 
  } else 
 
    if (e->button()==Qt::RightButton) {
 
      
 
      if (intersection_line /* && !angle_line*/) {
 
	
 
	//QPointF p = matrix().inverted().map(e->pos());
 
	QPointF p = mapToScene(e->pos());
 
	QPointF sp = intersection_line->line().p1();
 
	
 
	viewport()->setMouseTracking( TRUE );
 
	/* angle_line = new QGraphicsLineItem( 0, scene() );
 
@@ -460,28 +479,33 @@ void FigureEditor::mouseReleaseEvent(QMo
 
            
 
    }
 
}
 

	
 

	
 
// returns a vector of pointer to cells colliding with intersection line
 
vector <CellItem *> FigureEditor::getIntersectedCells(void) { 
 
  
 
  vector <CellItem *> colliding_cells;
 
  
 
  QList<QGraphicsItem *> l = intersection_line->collidingItems( );
 
  
 
  cerr << "l.size() = " << l.size() << endl;
 
  #ifdef QDEBUG
 
  qDebug() <<  "l.size() = " << l.size() << endl;
 
  #endif
 

	
 
  for (QList<QGraphicsItem *>::Iterator it=l.begin(); it!=l.end(); ++it) {
 
    
 
    cerr << typeid(**it).name() << endl;
 
    #ifdef QDEBUG
 
    qDebug() << typeid(**it).name() << endl;
 
    #endif
 
    
 
    if ( !strcmp(typeid(**it).name(),"8CellItem") ) {
 
      
 
      colliding_cells.push_back(dynamic_cast<CellItem *>(*it));
 
      
 
    }
 
  }
 
  
 
  delete intersection_line;
 
  intersection_line = 0;
 
  return colliding_cells;
 
    
 
@@ -525,25 +549,29 @@ void FigureEditor::insertNode(QPointF p)
 
}
 

	
 
static uint mainCount = 0;
 

	
 
Main::Main(QGraphicsScene& c, Mesh &m, QWidget* parent, const char* name, Qt::WindowFlags f) :
 
  Q3MainWindow(parent,name,f),
 
  MainBase(c,m),
 
  mesh(m)
 
	   
 
	  //canvas(c)
 
{
 
  editor = new FigureEditor(canvas,mesh, this);
 
  cerr << "Interactive = " << editor->isEnabled();
 

	
 
  #ifdef QDEBUG
 
  qDebug() << "Interactive = " << editor->isEnabled();
 
  #endif
 

	
 
  working_dir = 0;
 
  QObject::connect( editor, SIGNAL(MousePressed()), this, SLOT(PauseIfRunning()));
 
  QObject::connect( editor, SIGNAL(MouseReleased()), this, SLOT(ContIfRunning()));
 
  QMenuBar* menu = menuBar();
 
  
 
  Q3PopupMenu* file = new Q3PopupMenu( menu );
 
 // file->insertItem("&Fill canvas", this, SLOT(init()), Qt::CTRL+Qt::Key_F);
 
	file->insertItem("&Read leaf", this, SLOT(readStateXML()));
 
	file->insertItem("&Save leaf", this, SLOT(saveStateXML()));
 
	file->insertItem("Snapshot", this, SLOT(snapshot()), Qt::CTRL+Qt::SHIFT+Qt::Key_S);
 
 // file->insertItem("&New view", this, SLOT(newView()), Qt::CTRL+Qt::Key_N);
 
   file->insertSeparator();
 
@@ -582,27 +610,27 @@ Main::Main(QGraphicsScene& c, Mesh &m, Q
 
  view = new Q3PopupMenu( menu );
 
  //view->insertItem("&Enlarge", this, SLOT(enlarge()), SHIFT+CTRL+Key_Plus);
 
  //view->insertItem("Shr&ink", this, SLOT(shrink()), SHIFT+CTRL+Key_Minus);
 
	view->insertItem("&Zoom in", this, SLOT(zoomIn()), Qt::CTRL+Qt::Key_Equal);
 
  view->insertItem("Zoom &out", this, SLOT(zoomOut()), Qt::CTRL+Qt::Key_Minus);
 
	view->insertSeparator();
 
	com_id = view->insertItem("Show cell &centers", this, SLOT(toggleShowCellCenters()));
 
  view->setItemChecked(com_id, FALSE);
 
  //view->insertItem("Cell monitor", this, SLOT(cellmonitor()));
 
  mesh_id = view->insertItem("Show &nodes", this, SLOT(toggleShowNodes()), Qt::CTRL+Qt::SHIFT+Qt::Key_N);
 
  view->setItemChecked(mesh_id, TRUE);
 
  node_number_id = view->insertItem("Show node numbers", this, SLOT(toggleNodeNumbers()), Qt::CTRL+Qt::SHIFT+Qt::Key_M);
 
  view->setItemChecked(node_number_id, TRUE);
 
  view->setItemChecked(node_number_id, FALSE);
 
  cell_number_id = view->insertItem("Show cell numbers", this, SLOT(toggleCellNumbers()));
 
  view->setItemChecked(cell_number_id, TRUE);
 
  view->setItemChecked(cell_number_id, FALSE);
 
  hide_cells_id = view->insertItem("Hide cells", this, SLOT(toggleHideCells()));
 
  view->setItemChecked(hide_cells_id, FALSE);
 
  border_id = view->insertItem("Show &border cells", this, SLOT(toggleShowBorderCells()));
 
  view->setItemChecked(border_id, FALSE);
 
  cell_axes_id = view->insertItem("Show cell &axes", this, SLOT(toggleCellAxes()));
 
  cell_strain_id = view->insertItem("Show cell &strain", this, SLOT(toggleCellStrain()));
 
  view->setItemChecked(cell_axes_id, FALSE);
 
  fluxes_id = view->insertItem("Show &fluxes", this, SLOT(toggleShowFluxes()));
 
  view->setItemChecked(fluxes_id, FALSE);
 
  cell_walls_id = view->insertItem("Show transporters", this, SLOT(toggleShowWalls()));
 
	view->setItemChecked(cell_walls_id, FALSE);
 
	apoplasts_id = view->insertItem("Show apoplasts", this, SLOT(toggleShowApoplasts()));
 
@@ -902,41 +930,45 @@ void Main::readPrevStateXML() {
 
    readStateXML((const char *)next_file);
 
    
 
  }
 
  
 
  
 
}
 

	
 
int Main::readStateXML(const char *filename, bool geometry, bool pars, bool simtime) {
 
 
 
  try {
 
    xmlNode *settings;
 
    mesh.XMLRead((const char *)filename, &settings, geometry, pars, simtime);
 
	cerr << "Reading done.\n";
 
    #ifdef QDEBUG
 
    qDebug() << "Reading done."<< endl;
 
    #endif
 
    XMLReadSettings(settings);
 
    xmlFree(settings);
 
    Cell::SetMagnification(1);
 
    Cell::setOffset(0,0);
 
    
 
    FitLeafToCanvas();
 
    
 
    currentFile =  QString(filename);
 
	
 
    Plot();
 
    QString status_message = QString("Succesfully read leaf from file %1. Time is %2 h.\n").arg(currentFile).arg(mesh.getTimeHours().c_str());
 
    cerr << status_message.toStdString() << endl;
 
	setCaption(caption_with_file.arg(filename));
 
    statusBar()->message(status_message);
 
    emit ParsChanged();
 
	cerr << "Done. Returning 0.\n";
 
    #ifdef QDEBUG
 
    qDebug() << "Done. Returning 0." << endl;
 
    #endif
 
    return 0;
 
  } catch (const char *error_message) {
 
    QMessageBox mb( "Read leaf from XML file",
 
		    QString(error_message),
 
		    QMessageBox::Critical,
 
		    QMessageBox::Ok | QMessageBox::Default,
 
		    Qt::NoButton,
 
		    Qt::NoButton);
 
    mb.exec();
 
    return 1;
 
  }
 
  
 
@@ -1019,25 +1051,27 @@ void Main::readFirstStateXML() {
 

	
 
    readStateXML((const char*)next_file);
 
  }
 
  
 
  
 
}
 

	
 
void Main::readStateXML() {
 

	
 
  //  extern Mesh mesh;
 

	
 
  stopSimulation();
 
  cerr << "Trying to open an OptionFileDialog\n";
 
  #ifdef QDEBUG
 
  qDebug() << "Trying to open an OptionFileDialog" << endl;
 
  #endif
 
  OptionFileDialog *fd = new OptionFileDialog( this, "read dialog", TRUE );
 
  fd->setMode( OptionFileDialog::ExistingFile );
 
  fd->setFilter( "XML files (*.xml)");
 
  if (working_dir) {
 
    fd->setDir(*working_dir);
 
  }
 
  QString fileName;
 
  if ( fd->exec() == QDialog::Accepted ) {
 
    
 
    fileName = fd->selectedFile();
 
    if (working_dir) {
 
      delete working_dir;
 
@@ -1195,37 +1229,37 @@ void Main::toggleHideCells(void) {
 

	
 

	
 
  void Main::startSimulation(void) {
 
    //run->setItemChecked(paused_id, false);
 
    timer->start( 0 );
 
    statusBar()->message("Simulation started");
 
    running = true;
 
  }
 

	
 
  void Main::stopSimulation(void) {
 
    //run->setItemChecked(paused_id, true);
 
    timer->stop();
 
    cerr << "Stopping simulation\n";
 
    cerr << "Stopping simulation" << endl;
 
    statusBar()->message("Simulation paused");
 
    running = false;
 
  }
 

	
 
  void Main::togglePaused()
 
  {
 
    bool s = run->isItemChecked(paused_id);
 
    if (s) {
 
      cerr << "Calling start simulation\n";
 
      cerr << "Calling start simulation" << endl;
 
      startSimulation();
 
    } else {
 
      cerr << "Calling stop simulation\n";
 
      cerr << "Calling stop simulation" << endl;
 
      stopSimulation();
 
    }
 
  }
 

	
 
  void Main::setFluxArrowSize(int size) {
 
  
 
    flux_arrow_size = size/100.;
 
  }
 

	
 

	
 
  void Main::enlarge()
 
  {
 
@@ -1264,32 +1298,36 @@ void Main::toggleHideCells(void) {
 
  }
 

	
 

	
 
  void Main::print()
 
  {
 
    if ( !printer ) printer = new QPrinter;
 
    
 
    if ( printer->setup(this) ) {
 
    
 
      //    extern Mesh mesh;
 
      Vector bbll,bbur;
 
      mesh.BoundingBox(bbll,bbur);
 
      cerr << "bbll = " << bbll << endl;
 
      cerr << "bbur = " << bbur << endl;
 

	
 
      #ifdef QDEBUG
 
      qDebug() << "bbll = " << bbll << endl;
 
      qDebug() << "bbur = " << bbur << endl;
 
      #endif
 
      double cw = (bbur.x - bbll.x);
 
      double ch = (bbur.y - bbll.y);
 
      QPainter pp(printer);
 
      QRect vp=pp.viewport();
 
      cerr << "Paper width = " << vp.width() << " x " << vp.height() << endl;
 
    
 
      #ifdef QDEBUG
 
      qDebug() << "Paper width = " << vp.width() << " x " << vp.height() << endl;
 
      #endif
 

	
 
      // Note that Cell is also translated...
 
      pp.translate(-bbur.x,-bbur.y);
 
      if (cw>ch) {
 
	pp.scale(vp.width()/(2*cw*Cell::Magnification()), vp.width()/(2*cw*Cell::Magnification()));
 
      } else {
 
	pp.scale(vp.height()/(2*ch*Cell::Magnification()), vp.height()/(2*ch*Cell::Magnification()));
 
      }
 
      canvas.render(&pp, QRectF(), QRectF(0.,0.,canvas.width(),canvas.height()));
 
    }
 
  }
 

	
 
@@ -1307,25 +1345,25 @@ void Main::toggleHideCells(void) {
 

	
 

	
 
  void Main::RestartSim(void) {
 

	
 
    stopSimulation();
 
    if ( QMessageBox::question(
 
			       this,
 
			       tr("Restart simulation?"),
 
			       tr("Restart simulation.\n"
 
				  "Are you sure?"),
 
							   QMessageBox::Yes | QMessageBox::No, QMessageBox::NoButton ) == QMessageBox::Yes ) {
 

	
 
		cerr << "Restarting simulation\n";
 
      cerr << "Restarting simulation" << endl;
 
      //    extern Mesh mesh;
 
      mesh.Clear();
 
      Init();
 
		Plot();
 
		editor->FullRedraw();
 
    } 
 
    //startSimulation();
 
  }
 

	
 
  /*
 
    void Main::SaveToGifAnim(void) {
 
  
 
@@ -1388,31 +1426,33 @@ void Main::toggleHideCells(void) {
 
       if (gifanim)
 
       gifanim->close();
 

	
 
       }*/
 

	
 

	
 
void Main::FitCanvasToWindow(void) {
 
  
 
  double scale_factor_x = (double)editor->width()/(double)canvas.width();
 
  double scale_factor_y = (double)editor->height()/(double)canvas.height();
 
  double scale_factor = scale_factor_x > scale_factor_y ? scale_factor_x : scale_factor_y;
 
  QMatrix m = editor->matrix();
 
  
 
  cerr << "editor->width() = " << editor->width() << endl;
 
  cerr << "editor->height() = " << editor->height() << endl;
 

	
 
  #ifdef QDEBUG  
 
  qDebug() << "editor->width() = " << editor->width() << endl;
 
  qDebug() << "editor->height() = " << editor->height() << endl;
 
  
 
  cerr << "scale_factor = " << scale_factor << endl;
 
  cerr << "scale_factor_x = " << scale_factor_x << endl;
 
  cerr << "scale_factor_y = " << scale_factor_y << endl;
 
  qDebug() << "scale_factor = " << scale_factor << endl;
 
  qDebug() << "scale_factor_x = " << scale_factor_x << endl;
 
  qDebug() << "scale_factor_y = " << scale_factor_y << endl;
 
  #endif
 
  m.scale( scale_factor, scale_factor );
 
  editor->setMatrix( m );
 
  editor->show();
 
}
 

	
 
  void Main::PauseIfRunning(void) {
 
    if (running) {
 
      timer->stop();
 
    }
 
  }
 

	
 
  void Main::ContIfRunning(void) {
src/cell.cpp
Show inline comments
 
@@ -10,36 +10,37 @@
 
 *  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 <QDebug>
 

	
 
#include <string>
 
#include "cell.h"
 
#include "node.h"
 
#include "mesh.h"
 
#include "tiny.h"
 
#include "nodeset.h"
 
#include "cellitem.h"
 
#include "nodeitem.h"
 
#include "qcanvasarrow.h"
 
#include "parameter.h"
 

	
 
#include <QDebug>
 

	
 
static const std::string _module_id("$Id$");
 

	
 
extern Parameter par;
 

	
 
double Cell::factor=1.;
 
double Cell::offset[3]={0,0,0};
 

	
 
Cell::Cell(void) : CellBase() {
 

	
 
	m=0;
 

	
 
@@ -102,72 +103,84 @@ void Cell::DivideOverAxis(Vector axis) {
 
	
 
	DivideWalls(new_node_locations, centroid, centroid+axis);
 
	
 
}
 
double Cell::MeanArea(void) {
 
	return m->MeanArea();
 
}
 

	
 

	
 
void Cell::Apoptose(void) {
 
	
 
	// First kill walls
 
	cerr << "This is cell " << Index() << "\n";
 
	cerr << "Number of walls: " << walls.size() << endl;
 
	
 
	for (list<Wall *>::iterator w=walls.begin();
 
		 w!=walls.end();
 
		 w++) {
 
		cerr << "Before apoptosis, wall " << (*w)->Index() << " says: c1 = " << (*w)->c1->Index() << ", c2 = " << (*w)->c2->Index() << endl;
 
        #ifdef QDEBUG
 
        qDebug() << "This is cell " << Index() << endl;
 
	qDebug() << "Number of walls: " << walls.size() << endl;
 
	#endif
 
	for (list<Wall *>::iterator w=walls.begin(); w!=walls.end(); w++) {
 
             #ifdef QDEBUG
 
	     qDebug() << "Before apoptosis, wall " << (*w)->Index() << " says: c1 = "
 
		      << (*w)->c1->Index() << ", c2 = " << (*w)->c2->Index() << endl;
 
             #endif
 
	}
 
	for (list<Wall *>::iterator w=walls.begin();
 
		 w!=walls.end();
 
		 w++) {
 
		
 
		bool illegal_flag = false;
 
		if ((*w)->c1 == (*w)->c2 ) 
 
			illegal_flag=true;
 
		if ((*w)->c1 == this) {
 
			
 
			// invert wall?
 
			(*w)->c1 = (*w)->c2;      
 
			(*w)->c2 = m->boundary_polygon;
 
			
 
			Node *n1 = (*w)->n1;
 
			(*w)->n1 = (*w)->n2;
 
			(*w)->n2 = n1;
 
			
 
		} else {
 
			(*w)->c2 = m->boundary_polygon;
 
		}
 
		
 
		#ifdef QDEBUG
 
		if (illegal_flag && (*w)->c1==(*w)->c2) {
 
			cerr << "I created an illegal wall.\n";
 
		  qDebug() << "I created an illegal wall." << endl;
 
		}
 
		#endif
 

	
 
		if ( ((*w)->N1()->DeadP() || (*w)->N2()->DeadP()) ||
 
			((*w)->C1() == (*w)->C2() ) ){
 
			// kill wall
 
			cerr << "Killing wall.\n";
 
		        #ifdef QDEBUG
 
		        qDebug() << "Killing wall." << endl;
 
			#endif
 
			(*w)->Kill();
 

	
 
			#ifdef QDEBUG
 
			if ((*w)) {
 
				cerr << "Wall " << (*w)->Index() << " says: c1 = " << (*w)->c1->Index() << ", c2 = " << (*w)->c2->Index() << endl;
 
			  qDebug() << "Wall " << (*w)->Index() << " says: c1 = " 
 
				   << (*w)->c1->Index() << ", c2 = " << (*w)->c2->Index() << endl;
 
			}
 
			#endif
 
			(*w)=0;
 
		} else {
 
			cerr << "Not killing wall.\n";
 
			cerr << "Wall " << (*w)->Index() << " says: c1 = " << (*w)->c1->Index() << ", c2 = " << (*w)->c2->Index() << endl;
 
		        #ifdef QDEBUG
 
		        qDebug() << "Not killing wall." << endl;
 
			qDebug() << "Wall " << (*w)->Index() << " says: c1 = " 
 
				 << (*w)->c1->Index() << ", c2 = " << (*w)->c2->Index() << endl;
 
                        #endif
 
		}
 
		
 
		
 
		
 
	}
 
	walls.remove(0);
 
	
 
	// Unregister me from my nodes, and delete the node if it no longer belongs to any cells
 
	list<Node *> superfluous_nodes;
 
	for (list<Node *>::iterator n=nodes.begin();
 
		 n!=nodes.end();
 
		 n++) {
 
		
 
		Node &no(*(*n));
 
		// locate myself in the node's owner list
 
		list<Neighbor>::iterator cellpos;
 
@@ -319,25 +332,27 @@ void Cell::ConstructConnections(void) {
 
 \param fixed_wall: If true: wall will be set to "fixed" (i.e. not motile)
 
 \return: true if the cell divided, false if not (i.e. no intersection between v1 and v2, and the cell)
 
 */
 
bool Cell::DivideOverGivenLine(const Vector v1, const Vector v2, bool fix_cellwall, NodeSet *node_set ) {
 
	
 
	if (dead) return false;
 
	
 
	
 
	
 
	// check each edge for intersection with the line
 
	ItList new_node_locations;
 
	
 
	cerr << "Cell " << Index() << " is doing DivideOverGivenLine \n";
 
	#ifdef QDEBUG
 
	qDebug() << "Cell " << Index() << " is doing DivideOverGivenLine" << endl;
 
	#endif
 
	for (list<Node *>::iterator i=nodes.begin();
 
		 i!=nodes.end();
 
		 i++) {
 
		
 
		Vector v3 = *(*i);
 
		list<Node *>::iterator nb=i;
 
		nb++;
 
		if (nb == nodes.end()) {
 
			nb = nodes.begin();
 
		}
 
		Vector v4 = *(*nb);
 
		
 
@@ -352,47 +367,49 @@ bool Cell::DivideOverGivenLine(const Vec
 
		/* double intersec_x = v1.x + ua*(v2.x-v1.x);
 
		 double intersec_y = v1.y + ua*(v2.y-v1.y);*/
 
		
 
		//cerr << "Edge " << *i << " to " << *nb << ": ua = " << ua << ", ub = " << ub << ":  ";
 
		// this construction with "TINY" should simulate open/closed interval <0,1]
 
		if ( ( TINY < ua && ua < 1.+TINY ) && ( TINY < ub && ub < 1.+TINY ) ) {
 
			// yes, intersection detected. Push the location to the list of iterators
 
			new_node_locations.push_back(nb);
 
			
 
		} 
 
	}
 
	
 
        #ifdef QDEBUG
 
	if (new_node_locations.size()<2) { 
 
		
 
		cerr << "Line does not intersect with two edges of Cell " << Index() << endl;
 
		cerr << "new_node_locations.size() = " << new_node_locations.size() << endl;
 
		return false;
 
	  qDebug() << "Line does not intersect with two edges of Cell " << Index() << endl;
 
	  qDebug() << "new_node_locations.size() = " << new_node_locations.size() << endl;
 
	  return false;
 
	}
 
	
 
	ItList::iterator i = new_node_locations.begin();
 
	list< Node *>::iterator j;
 
	cerr << "-------------------------------\n";
 
	cerr << "Location of new nodes: " << (**i)->Index() << " and ";
 
	qDebug() << "-------------------------------" << endl;
 
	qDebug() << "Location of new nodes: " << (**i)->Index() << " and ";
 

	
 
	++i;
 
	j = *i; 
 
	if (j==nodes.begin()) j=nodes.end(); j--;
 
	
 
	cerr << (*j)->Index() << endl;
 
	cerr << "-------------------------------\n";
 
	qDebug() << (*j)->Index() << endl;
 
	qDebug() << "-------------------------------" << endl;
 
    
 
	if ( **new_node_locations.begin() == *j ) {
 
		cerr << "Rejecting proposed division (cutting off zero area).\n";
 
	  qDebug() << "Rejecting proposed division (cutting off zero area)." << endl;
 
		return false;
 
	}
 
	
 
	#endif
 

	
 
	DivideWalls(new_node_locations, v1, v2, fix_cellwall, node_set);
 
	
 
	return true;
 
	
 
}
 

	
 
// Core division procedure
 
void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vector to, bool fix_cellwall, NodeSet *node_set) {
 
	
 
	if (dead) return;
 
	
 
	bool boundary_touched_flag=false;
 
@@ -442,27 +459,30 @@ void Cell::DivideWalls(ItList new_node_l
 
		// cells, remember to update the code below. There are some
 
		// fixed-size arrays over there!
 
		
 
		cerr << "Warning in Cell::Division: division of non-convex cells not fully implemented" << endl;
 
		
 
		// Reject the daughter cell and decrement the amount of cells
 
		// again. We can do this here because it is the last cell added.
 
		// Never, ever try to fully erase a cell elsewhere, because we
 
		// make heavy use of cell indices in this project; if you erase a
 
		// Cell somewhere in the middle of Mesh::Cells the indices will
 
		// get totally messed up...! (e.g. the indices used in Nodes::cells)
 
		
 
		cerr << "new_node_locations.size() = " << new_node_locations.size() <<endl;
 
		cerr << "daughter->index = " << daughter->index << endl;
 
		cerr << "cells.size() = " << m->cells.size() << endl;
 
		#ifdef QDEBUG
 
		qDebug() << "new_node_locations.size() = " << new_node_locations.size() <<endl;
 
		qDebug() << "daughter->index = " << daughter->index << endl;
 
		qDebug() << "cells.size() = " << m->cells.size() << endl;
 
		#endif
 

	
 
		m->cells.pop_back();
 
		Cell::NCells()--;
 
		m->shuffled_cells.pop_back();
 
		return;
 
	}
 
	
 
	
 
	// We can be sure we only need two positions here because divisions
 
	// of non-convex cells are rejected above.
 
	Vector new_node[2];
 
	Node *new_node_ind[2];
 
	
 
@@ -520,25 +540,25 @@ void Cell::DivideWalls(ItList new_node_l
 
		//
 
		// old, fixed value was: par.collapse_node_threshold = 0.05
 
		double collapse_node_threshold = 0.05;
 
#ifdef FLEMING
 
		collapse_node_threshold = par.collapse_node_threshold;
 
#endif
 
		
 
		double elem_length = ( (*(**i)) - (*(*nb)) ).Norm();
 
		if ( ( *(**i) - *n ).Norm() < collapse_node_threshold  * elem_length ) {
 
			new_node_flag[nnc]=1;
 
			new_node[nnc] = *(**i);
 
			new_node_ind[nnc] = **i;
 
			//cerr << **i << "\n" ;
 
			//cerr << **i << endl ;
 
		} else 
 
			if ( (*(*nb) - *n).Norm() < collapse_node_threshold * elem_length ) {
 
				new_node_flag[nnc]=2;
 
				new_node[nnc] = *(*nb);
 
				new_node_ind[nnc] = *nb;
 
			} else {
 
				new_node_flag[nnc]=0;
 
				new_node[nnc] = *n;
 
			}
 
		
 
		nnc++;
 
		delete n;
 
@@ -776,28 +796,29 @@ void Cell::DivideWalls(ItList new_node_l
 
			
 
			/*************** 1. Find the correct wall element  ********************/
 
			
 
			list<Wall *>::iterator w, start_search;
 
			w = start_search = walls.begin();
 
			do {
 
				// Find wall between this cell and neighbor cell
 
				w = find_if( start_search, walls.end(), bind2nd (mem_fun( &Wall::is_wall_of_cell_p ), neighbor_cell ) );
 
				start_search = w; start_search++; // continue searching at next element
 
			} while ( w!=walls.end() && !(*w)->IntersectsWithDivisionPlaneP( from, to ) ); // go on until we find the right one.
 
			
 
			if (w == walls.end()) {
 
				cerr << "Whoops, wall element not found...!\n";
 
				cerr << "Cell ID: " << neighbor_cell->Index() << endl;
 
				cerr << "My cell ID: " << Index() << endl;
 
				
 
			        #ifdef QDEBUG
 
			  qDebug() << "Whoops, wall element not found...!" << endl;
 
			        qDebug() << "Cell ID: " << neighbor_cell->Index() << endl;
 
				qDebug() << "My cell ID: " << Index() << endl;
 
                                #endif
 
			} else {
 
				
 
				// 2. Split it up, if we should (sometimes, the new node coincides with an existing node so
 
				// we should not split up the Wall)
 
				
 
				if (new_node_ind[i]!=(*w)->n1 && new_node_ind[i]!=(*w)->n2) {
 
					
 
					Wall *new_wall;
 
					
 
					// keep the length of the original wall; we need it to equally divide the transporter concentrations
 
					// over the two daughter walls
 
					(*w)->SetLength(); // make sure we've got the current length
 
@@ -886,25 +907,27 @@ void Cell::DivideWalls(ItList new_node_l
 
		}
 
		list<Node *>::iterator i=start;
 
		while ( i!=stop) {
 
			
 
			// give the node to the daughter
 
			// (find references to parent cell from this node,
 
			// and remove them)
 
			list<Neighbor>::iterator neighb_with_this_cell=
 
			find_if((*i)->owners.begin(),
 
					(*i)->owners.end(),
 
				bind2nd(mem_fun_ref( &Neighbor::CellEquals ),this->Index() )  );
 
			if (neighb_with_this_cell==(*i)->owners.end()) {
 
				cerr << "not found\n";
 
			        #ifdef QDEBUG
 
			  qDebug() << "not found" << endl;
 
                                #endif
 
				abort();
 
			}
 
			
 
			(*i)->owners.erase(neighb_with_this_cell);
 
			
 
			daughter->nodes.push_back( *i );
 
			
 
			
 
			i++;
 
			if (i==nodes.end())
 
				i=nodes.begin();
 
		};
 
@@ -1610,46 +1633,50 @@ void Cell::Flux(double *flux, double *D)
 
		 i!=walls.end();
 
		 i++) {
 
		
 
		
 
		// leaf cannot take up chemicals from environment ("no flux boundary")
 
		if ((*i)->c2->BoundaryPolP()) continue;
 
		
 
		
 
		// flux depends on edge length and concentration difference
 
		for (int c=0;c<NChem();c++) {
 
			double phi = (*i)->length * ( D[c] ) * ( ((Cell *)(*i)->c2)->chem[c] - chem[c] );
 
			
 
			#ifdef QDEBUG
 
			if ((*i)->c1!=this) {
 
				cerr << "Warning, bad cells boundary: " << (*i)->c1->Index() << ", " << index << endl;
 
			  qDebug() << "Warning, bad cells boundary: " << (*i)->c1->Index() << ", " << index << endl;
 
			}
 
			#endif
 
			
 
			flux[c] += phi;
 
		}    
 
	}
 
	
 
}
 

	
 

	
 
// graphics stuff, not compiled for batch versions
 
#ifdef QTGRAPHICS
 

	
 
#include "canvas.h"
 

	
 
void Cell::Draw(QGraphicsScene *c, QString tooltip) {
 
	
 
	// Draw the cell on a QCanvas object
 
	
 
	if (DeadP()) { 
 
		cerr << "Cell " << index << " not drawn, because dead.\n";
 
	        #ifdef QDEBUG
 
	  qDebug() << "Cell " << index << " not drawn, because dead." << endl;
 
		#endif
 
		return;
 
	}
 
	
 
	CellItem* p = new CellItem(this, c);
 
	
 
	QPolygonF pa(nodes.size());
 
	int cc=0;
 
	
 
	for (list<Node *>::const_iterator n=nodes.begin();
 
		 n!=nodes.end();
 
		 n++) {
 
		Node *i=*n;
 
@@ -1931,29 +1958,30 @@ void Cell::SetWallLengths(void) {
 
		(*de)->length = sum_length;
 
		
 
		//cerr << endl;
 
		// goto next de
 
	}
 
}
 

	
 

	
 
//! Add Wall w to the list of Walls
 
void Cell::AddWall( Wall *w ) {
 
	
 
	// if necessary, we could try later inserting it at the correct position
 
        #ifdef QDEBUG
 
	if (w->c1 == w->c2 ){
 
		
 
		cerr << "Wall between identical cells: " << w->c1->Index()<< endl;
 
		
 
	  qDebug() << "Wall between identical cells: " << w->c1->Index()<< endl;
 
	}
 
	#endif
 

	
 
	// Add Wall to Cell's list
 
	walls.push_back( w );
 
	
 
	// Add wall to Mesh's list if it isn't there yet
 
	
 
	if (find (
 
			  m->walls.begin(), m->walls.end(),
 
			  w )
 
		== m->walls.end() ) {
 
		m->walls.push_back(w);
 
	}
 
	
src/cellbase.h
Show inline comments
 
@@ -56,28 +56,32 @@ struct ParentInfo {
 

	
 
// We need a little trick here, to make sure the plugin and the main application will see the same static datamembers
 
// otherwise each have their own instantation.
 
// My solution is as follow. I collect all original statics in a class. The main application instantiates it and
 
// has a static pointer to it. After loading the plugin I set a static pointer to the same class 
 
class CellsStaticDatamembers {
 
	
 
public:
 
	CellsStaticDatamembers(void) {
 
		ncells = 0;
 
		nchem = 0;
 
		base_area = 0.;
 
		cerr << "Constructor of CellsStaticDatamembers\n";
 
                #ifdef QDEBUG
 
		qDebug() << "Constructor of CellsStaticDatamembers" << endl;
 
		#endif
 
	}
 
	~CellsStaticDatamembers() {
 
		cerr << "Oops! Desctructor of CellsStaticDatamembers called\n";
 
                #ifdef QDEBUG
 
	        qDebug() << "Oops! Desctructor of CellsStaticDatamembers called" << endl;
 
                #endif
 
	}
 
	int ncells;
 
	int nchem;
 
	double base_area;
 

	
 

	
 
};
 

	
 
class CellBase :  public QObject, public Vector 
 
{
 

	
 
	Q_OBJECT
src/data_plot.cpp
Show inline comments
 
@@ -23,29 +23,31 @@
 
#include <stdlib.h>
 
#include <qwt_painter.h>
 
#include <qwt_plot_canvas.h>
 
#include <qwt_plot_marker.h>
 
#include <qwt_plot_curve.h>
 
#include <qwt_scale_widget.h>
 
#include <qwt_legend.h>
 
#include <qwt_scale_draw.h>
 
#include <qwt_math.h>
 
#include <QDialog>
 
#include <QString>
 
#include <QStringList>
 
#include <QDebug>
 
#include <iostream>
 

	
 
#include "data_plot.h"
 

	
 
static const std::string _module_id("$Id$");
 
using namespace std;
 

	
 
static const string _module_id("$Id$");
 

	
 
//
 
//  Initialize main window
 
//
 
DataPlot::DataPlot(QWidget *parent, const QString title, const QStringList curvenames ):
 
  QwtPlot(parent),
 
  d_interval(0),
 
  d_timerId(-1)
 
{
 

	
 
  // Number of curves is number of names given
 
  ncurves = curvenames.size();
 
@@ -81,25 +83,29 @@ DataPlot::DataPlot(QWidget *parent, cons
 
  // Assign a title
 
  setTitle(title);
 
  insertLegend(new QwtLegend(), QwtPlot::BottomLegend);
 

	
 
  // Insert curves
 
  curves = new QwtPlotCurve[ncurves];
 
  for (int i=0;i<ncurves;i++) {
 

	
 
    curves[i].setTitle(curvenames[i]);
 
    curves[i].attach(this);
 
    curves[i].setPen(QPen(curvecolors[i]));
 
    QString col(curvecolors[i]);
 
    std::cerr << "Curvecolor " << col.toStdString() << std::endl;
 

	
 
    #ifdef QDEBUG
 
    qDebug() << "Curvecolor " << col.toStdString() << endl;
 
    #endif
 

	
 
    curves[i].setRawData(d_t, d_x[i], PLOT_SIZE);
 
  }
 
    
 
  // Axis 
 
  setAxisTitle(QwtPlot::xBottom, "Time");
 

	
 
  setAxisTitle(QwtPlot::yLeft, "Level");
 
  setAxisScale(QwtPlot::yLeft, 0, 10);
 
    
 
  //    setTimerInterval(0.0); 
 

	
 
  data_pos = 0;
src/forwardeuler.cpp
Show inline comments
 
@@ -17,25 +17,27 @@
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <cmath>
 
#include <iostream> 
 
#include "forwardeuler.h"
 
#include "warning.h"
 
#include "maxmin.h"
 
#include <string>
 

	
 
static const std::string _module_id("$Id$");
 
using namespace std;
 

	
 
static const string _module_id("$Id$");
 

	
 
// The value Errcon equals (5/Safety) raised to the power (1/PGrow), see use below.
 

	
 
/* static float maxarg1,maxarg2;
 
   #define FMAX(a,b) (maxarg1=(a),maxarg2=(b),(maxarg1) > (maxarg2) ?	\
 
   (maxarg1) : (maxarg2))
 
   static float minarg1,minarg2;
 
   #define FMIN(a,b) (minarg1=(a),minarg2=(b),(minarg1) < (minarg2) ?	\
 
   (minarg1) : (minarg2))
 
   #define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
 
*/
 

	
 
@@ -57,25 +59,25 @@ const double ForwardEuler::Tiny = 1.0e-3
 

	
 
void ForwardEuler::odeint(double *ystart, int nvar, double x1, double x2, double eps, double h1, double hmin, int *nok, int *nbad)
 
/* Runge-Kutta driver with adaptive stepsize control. Integrate starting values ystart[1..nvar]
 
  from x1 to x2 with accuracy eps, storing intermediate results in global variables. h1 should
 
  be set as a guessed first stepsize, hmin as the minimum allowed stepsize (can be zero). On
 
  output nok and nbad are the number of good and bad (but retried and fixed) steps taken, and
 
  ystart is replaced byv alues at the end of the integration interval. derivs is the user-supplied
 
  routine for calculating the right-hand side derivative, while rkqs is the name of the stepper
 
  routine to be used. */
 
{
 
  static bool warning_issued = false;
 
  if (!warning_issued) {
 
    std::cerr << "Using inaccurate method ForwardEuler\n";
 
    cerr << "Using inaccurate method ForwardEuler\n";
 
    warning_issued=true;
 
    //MyWarning::warning("Using inaccurate method ForwardEuler");
 
  }
 
  // N.B. Not for serious use and not fully usage compatible with RungeKutta
 
  // simply for testing API of integrator.
 
  
 
  double *y,*dydx;
 
  y=new double[nvar];
 
  dydx=new double[nvar];
 
  double x=x1;
 
    
 
  for (int i=0;i<nvar;i++) y[i]=ystart[i];
src/mesh.cpp
Show inline comments
 
@@ -385,27 +385,28 @@ Cell &Mesh::LeafPrimordium(int nnodes, d
 
  //petiole.nodes.push_back(n3.Index());
 
  //petiole.nodes.push_back(n4.Index());
 
  AddNodeToCell(petiole,
 
		n3,
 
		n2,
 
		n4);
 
  AddNodeToCell(petiole,
 
		n4,
 
		n3,
 
		n1);
 

	
 
  
 
  
 
  cerr << circle << endl;
 
  cerr << petiole << endl;
 
  #ifdef QDEBUG  
 
  qDebug() << circle << endl;
 
  qDebug() << petiole << endl;
 
  #endif
 
  
 
  AddNodeToCell(boundary_polygon, *it_n1, 
 
		n4,
 
		*it_n2 + ((*it_n1-*it_n2)+1)%nnodes); // is this gonna work?
 
  
 
  (*it_n1)->boundary=true;
 
  
 
  for (int i=0;i<nnodes;i++) {
 
    
 
    if (nodes[(first_node + i)]->owners.size()==1) {
 
      AddNodeToCell(boundary_polygon,
 
		    nodes[first_node +i],
 
@@ -569,28 +570,30 @@ void Mesh::Clear(void) {
 
	//Cell::ncells=0;
 
	/*    Cell::ClearNCells();
 
	 Node::nnodes=0;
 
	 
 
	 cells.clear();
 
	 nodes.clear();
 
	 shuffled_cells.clear();
 
	 shuffled_nodes.clear();
 
	 node_insertion_queue.empty();
 
	 
 
	 cerr << "Meshed cleared: cells: " << cells.size() << ", nodes: " << nodes.size() << endl;
 
	 */
 
	
 
	cerr << "cells.size() = " << cells.size() << endl;
 
	cerr << "walls.size() = " << walls.size() << endl;
 
	cerr << "nodes.size() = " << nodes.size() << endl;
 

	
 
	#ifdef QDEBUG
 
	qDebug() << "cells.size() = " << cells.size() << endl;
 
	qDebug << "walls.size() = " << walls.size() << endl;
 
	qDebug << "nodes.size() = " << nodes.size() << endl;
 
        #endif
 
}
 

	
 
double Mesh::DisplaceNodes(void) {
 

	
 
  MyUrand r(shuffled_nodes.size());
 
  random_shuffle(shuffled_nodes.begin(),shuffled_nodes.end(),r);
 
  
 
  double sum_dh=0;
 
  
 
  list<DeltaIntgrl> delta_intgrl_list;
 
  
 
  for_each( node_sets.begin(), node_sets.end(), mem_fun( &NodeSet::ResetDone ) );
 
@@ -1436,41 +1439,45 @@ void Mesh::CleanUpCellNodeLists(void) {
 
  
 
  shuffled_cells.clear();
 
  shuffled_cells = cells;
 
 
 
}
 

	
 
void Mesh::CutAwayBelowLine( Vector startpoint, Vector endpoint) {
 
  
 
  // Kills all cells below the line startpoint -> endpoint
 
  
 
  Vector perp = (endpoint-startpoint).Perp2D().Normalised();
 
  
 
  
 
  cerr << "Before Apoptose\n";
 
  #ifdef QDEBUG
 
  qDebug() << "Before Apoptose" << endl;
 
  #endif
 

	
 
  TestIllegalWalls();
 
  for (vector<Cell *>::iterator i=cells.begin();
 
       i!=cells.end();
 
       i++) {
 
    
 
    // do some vector geometry to check whether the cell is below the cutting line
 
    Vector cellvec = ((*i)->Centroid()-startpoint);
 
    
 
    if ( InnerProduct(perp, cellvec) < 0 ) {
 
      // remove those cells
 
      (*i)->Apoptose();
 
    }
 
  }
 

	
 
  cerr << "Before CleanUpCellNodeLists\n";
 
  #ifdef QDEBUG
 
  qDebug() << "Before CleanUpCellNodeLists" << endl;
 
  #endif
 
  TestIllegalWalls();
 
  
 
  CleanUpCellNodeLists();
 

	
 
}
 

	
 
void Mesh::CutAwaySAM(void) {
 

	
 
  for (vector<Cell *>::iterator i=cells.begin();
 
       i!=cells.end();
 
       i++) {
 
    
 
@@ -1483,25 +1490,27 @@ void Mesh::CutAwaySAM(void) {
 
  TestIllegalWalls();
 
  
 
  CleanUpCellNodeLists();
 

	
 

	
 
}
 
void Mesh::TestIllegalWalls(void) {
 

	
 
  for (list<Wall *>::iterator w = walls.begin();
 
       w!=walls.end();
 
       w++) {
 
    if ((*w)->IllegalP() ) {
 
      cerr << "Wall " << **w << " is illegal.\n";
 
      #ifdef QDEBUG
 
      qDebug() << "Wall " << **w << " is illegal." << endl;
 
      #endif
 
    }
 
  }
 

	
 
}
 

	
 

	
 

	
 
class node_owners_eq : public unary_function<Node, bool> {
 
  int no;
 
public:
 
  
 
  explicit node_owners_eq(int nn) { no=nn; }
 
@@ -1608,25 +1617,25 @@ void Mesh::RepairBoundaryPolygon(void) {
 
  boundary_polygon->ConstructConnections();
 
  for (list<Wall *>::iterator w=boundary_polygon->walls.begin();
 
       w!=boundary_polygon->walls.end();
 
       w++) {
 
    if ((*w)->DeadP()) {
 
      (*w)=0;
 
    }
 
  }
 
  boundary_polygon->walls.remove(0);
 
  boundary_polygon->ConstructNeighborList();
 
  
 
#ifdef QDEBUG
 
  cerr << "Repaired Boundary Polygon node indices: ";
 
  qDebug() << "Repaired Boundary Polygon node indices: ";
 
  foreach (Node* node, boundary_polygon->nodes){
 
    qDebug() << node->Index() << " " ;
 
  }
 
  qDebug() << endl ;
 

	
 
  #ifdef _undefined_
 
  qDebug() << "NODES:" << endl;
 
  foreach(Node* node, nodes) {
 
    qDebug() << *node;
 
  }
 
  qDebug() << endl;
 

	
src/mesh.h
Show inline comments
 
@@ -31,24 +31,25 @@
 
#include <algorithm>
 
#include <queue>
 
#include <iterator>
 
#include <functional>
 
#ifdef QTGRAPHICS
 
#include <QGraphicsScene>
 
#endif
 
#include "cell.h"
 
#include "node.h"
 
#include "simplugin.h"
 
#include <QVector>
 
#include <QPair>
 
#include <QDebug>
 

	
 
using namespace std;
 
// new queue which rejects duplicate elements
 
template<class T, class C = deque<T> > class unique_queue : public queue<T,C> {
 
	
 
public:
 
	typedef typename C::value_type value_type;
 
	// reimplements push: reject element if it exists already
 
	void push(const value_type &x) {
 
		if (find (queue<T,C>::c.begin(),queue<T,C>::c.end(),x)==queue<T,C>::c.end()) {
 
			queue<T,C>::c.push_back(x);
 
		}
 
@@ -101,26 +102,28 @@ public:
 
	Cell *RectangularCell(const Vector ll, const Vector ur, double rotation = 0);
 
	void CellFiles(const Vector ll, const Vector ur);
 
	
 
	/*  void GMVoutput(ostream &os, 
 
	 const char *codename=0, const char *codever=0,
 
	 const char *comments=0);*/
 
	//void RandPoints(int npoints);
 
	
 
	inline Cell &getCell(int i) {
 
		if ((unsigned)i<cells.size())
 
			return *cells[i];
 
		else {
 
			cerr << i << endl;
 
			cerr << "size is " << cells.size() << endl;
 
                        #ifdef QDEBUG
 
                        qDebug() << i << endl;
 
                        qDebug() << "size is " << cells.size() << endl;
 
                        #endif
 
			abort();
 
			//	throw("Index out of range in Mesh::getCell");
 
		}
 
	}
 
	
 
	inline Node &getNode(int i) {
 
		//if (i >= nodes.size() || i < 0) {
 
		//  cerr << "Mesh::getNode: Warning. Index " << i << " out of range.\n";
 
		// }
 
		return *nodes[i];    
 
	}
 
	
src/random.cpp
Show inline comments
 
@@ -10,24 +10,25 @@
 
 *  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 <QDebug>
 
#include <string>
 
#include <stdio.h>
 
#include <stdlib.h>
 
#include <sys/timeb.h>
 
#include <iostream>
 
#include "random.h"
 
 
static const std::string _module_id("$Id$");
 
 
static int idum = -1;
 
using namespace std;
 
 
@@ -75,27 +76,28 @@ double RANDOM(void)
 
  mj=ma[inext]-ma[inextp];
 
  if (mj < MZ) mj += MBIG;
 
  ma[inext]=mj;
 
  return mj*FAC;
 
}
 
 
/*! \param An integer random seed
 
  \return the random seed
 
**/
 
int Seed(int seed)
 
{
 
  if (seed < 0) {
 
    cerr << "Randomizing random generator, seed is ";
 
    int rseed=Randomize();
 
    cerr << rseed << "\n";
 
    #ifdef QDEBUG
 
    qDebug() << "Randomizing random generator, seed is " << rseed << endl;
 
    #endif
 
    return rseed;
 
  } else {
 
    int i;
 
    idum = -seed;
 
    for (i=0; i <100; i++)
 
      RANDOM();
 
    return seed;
 
  }
 
}
 
 
 
/*! Returns a random integer value between 1 and 'max'
src/wall.cpp
Show inline comments
 
@@ -52,78 +52,80 @@ bool Wall::CorrectWall( void ) {
 
	/* 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 */) {
 
		
 
		cerr << "nwalls = " << nwalls << endl;
 
	        #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() << ": ";
 
			
 
			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<int>(cerr, "  "), mem_fun (&CellBase::Index) );
 
			cerr << endl;
 
			cerr << "Owners node " << n1->Index() << ": ";
 
			for (list<Neighbor>::iterator i = n1->owners.begin();
 
				 i!=n1->owners.end();
 
				 i++) {
 
				cerr << i->getCell()->Index() << " ";
 
			}
 
			cerr << endl;
 
			cerr << "Owners node " << n2->Index() << ": ";
 
			
 
			for (list<Neighbor>::iterator i = n2->owners.begin();
 
				 i!=n2->owners.end();
 
				 i++) {
 
				cerr << i->getCell()->Index() << " ";
 
			}
 
			cerr << endl;
 
			std::exit(1);
 
		  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) {
 
		cerr << "Corner point. Special case.\n";
 
	  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);
 
@@ -139,25 +141,27 @@ bool Wall::CorrectWall( void ) {
 
			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";
 
				        #ifdef QDEBUG
 
				        qDebug() << "Warning, cell wall was not corrected." << endl;
 
					#endif
 
					return false;
 
				}
 
			}
 
		}
 
	}
 
	
 
	return true;
 
	
 
	
 
	
 
	
 
}
src/wallbase.cpp
Show inline comments
 
@@ -10,24 +10,26 @@
 
 *  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 <QDebug>
 

	
 
#include "wall.h"
 
#include "wallbase.h"
 
#include "node.h"
 
#include "mesh.h"
 
#include "parameter.h"
 
#include <sstream>
 
#include <string>
 
#include "warning.h"
 

	
 
#ifdef QTGRAPHICS
 
#include <QGraphicsScene>
 
#include <QGraphicsLineItem>
 
@@ -44,27 +46,29 @@ ostream &WallBase::print(ostream &os) co
 
	<< ", " << c1->Index() << " | " << c2->Index() << "} ";
 
	return os;
 
}
 

	
 
ostream &operator<<(ostream &os, const WallBase &w) { 
 
	w.print(os); 
 
	return os;
 
}
 

	
 

	
 
WallBase::WallBase(Node *sn1, Node *sn2, CellBase *sc1, CellBase *sc2) {
 
	
 
        #ifdef QDEBUG
 
	if (sc1==sc2) { 
 
		cerr << "Attempting to build a wall between identical cells: " << sc1->Index() << endl; 
 
	  qDebug() << "Attempting to build a wall between identical cells: " << sc1->Index() << endl; 
 
	}
 
	#endif
 
	
 
	c1 = sc1;
 
	c2 = sc2;
 
	
 
	n1 = sn1;
 
	n2 = sn2;
 
	
 
	transporters1 = new double[CellBase::NChem()];
 
	transporters2 = new double[CellBase::NChem()];
 
	new_transporters1 = new double[CellBase::NChem()];
 
	new_transporters2 = new double[CellBase::NChem()];
 
	
src/wallitem.cpp
Show inline comments
 
@@ -10,24 +10,25 @@
 
 *  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 <QDebug>
 
#include <string>
 
#include <QGraphicsScene>
 
#include <QVector>
 
#include "canvas.h"
 
#include "wallitem.h"
 
#include "parameter.h"
 
#include "node.h"
 
#include "transporterdialog.h"
 

	
 
static const std::string _module_id("$Id$");
 

	
 
WallItem::WallItem( Wall *w, int wallnumber, QGraphicsScene *canvas )
 
@@ -116,28 +117,30 @@ void WallItem::setColor(void) {
 
    }
 
  }
 
  
 
//   if (c->BoundaryPolP()) {
 
//     setPen(QPen(QColor("red"), 20));
 
//   }
 
}
 

	
 
void WallItem::OnClick(QMouseEvent *e) {
 
  
 

	
 
	Wall *w=&getWall();
 
	cerr << "Wall ID = " << w->Index() << ", this = " << w << "\n";
 
	cerr << "Wall item = " << this << "\n";
 
	cerr << "C1 = " << w->C1()->Index() << ", C2 = " << w->C2()->Index() << endl;
 
	cerr << "N1 = " << w->N1()->Index() << ", N2 = " << w->N2()->Index() << endl;
 
	#ifdef QDEBUG
 
	qDebug() << "Wall ID = " << w->Index() << ", this = " << w << endl;
 
	qDebug() << "Wall item = " << this << endl;
 
	qDebug() << "C1 = " << w->C1()->Index() << ", C2 = " << w->C2()->Index() << endl;
 
	qDebug() << "N1 = " << w->N1()->Index() << ", N2 = " << w->N2()->Index() << endl;
 
	#endif
 
	//double tr = wn==1?w->Transporters1(1):w->Transporters2(1);
 
	CellBase *c = wn==1?w->C1():w->C2();
 

	
 
	TransporterDialog dialog(w, c, wn);
 
	dialog.exec();
 

	
 
	if (e->button() == Qt::RightButton) {
 
		QString message;
 
		if (wn==1) {
 
			message=QString("Transporter 1 = %1, color = %2, length = %3\n").arg(w->Transporters1(1)).arg(pen().color().red()).arg(getWall().Length());
 
		} else {
 
			message=QString("Transporter 2 = %1, color = %2, length = %3\n").arg(w->Transporters2(1)).arg(pen().color().red()).arg(getWall().Length());
0 comments (0 inline, 0 general)