MorphoGraphX  2.0-1-227
MeshProcessPDG.hpp
Go to the documentation of this file.
1 //
2 // This file is part of MorphoGraphX - http://www.MorphoGraphX.org
3 // Copyright (C) 2012-2015 Richard S. Smith and collaborators.
4 //
5 // If you use MorphoGraphX in your work, please cite:
6 // http://dx.doi.org/10.7554/eLife.05864
7 //
8 // MorphoGraphX is free software, and is licensed under under the terms of the
9 // GNU General (GPL) Public License version 2.0, http://www.gnu.org/licenses.
10 //
11 #ifndef MESH_PROCESSS_PDG_HPP
12 #define MESH_PROCESSS_PDG_HPP
13 
14 #include <Process.hpp>
15 
16 #include <MeshProcessCellMesh.hpp>
17 
18 namespace mgx
19 {
20  mgxBase_EXPORT SymmetricTensor customDirectionTensor(SymmetricTensor origTensor, Point3f customX, Point3f customY, bool shearB);
21  mgxBase_EXPORT double lengthCustomDirTensor3D(SymmetricTensor origTensor, Point3f customDir);
22 
25 
28  class mgxBase_EXPORT CorrespondenceJunctions : public Process
29  {
30  public:
31  CorrespondenceJunctions(const Process& process) : Process(process)
32  {
33  setName("Mesh/Cell Axis/PDG/Check Correspondence");
34  setDesc("Find matching cell junctions between 2 meshes based on parent labeling.\n"
35  "Both meshes are simplified with Make Cells to keep only the cell junctions and centers.\n"
36  "SAVE your meshes before running!");
37  setIcon(QIcon(":/images/CorrespondenceJunctions.png"));
38 
39  addParm("Show correspondence","Draw connecting lines between corresponding junctions.","No",booleanChoice());
40  addParm("Convert to Cell Mesh","Convert the meshes into cell meshes","No",booleanChoice());
41  addParm("New","New","No",booleanChoice());
42  }
43 
44  bool run()
45  {
46  if(!checkState().mesh(MESH_NON_EMPTY, 0).mesh(MESH_NON_EMPTY, 1))
47  return false;
48  Mesh* mesh1, *mesh2;
49  if(currentMesh() == mesh(0)) {
50  mesh1 = mesh(0);
51  mesh2 = mesh(1);
52  } else if(currentMesh() == mesh(1)) {
53  mesh2 = mesh(0);
54  mesh1 = mesh(1);
55  } else
56  return false;
57 
58  bool res = run(mesh1, mesh2, stringToBool(parm("Show correspondence")), stringToBool(parm("Convert to Cell Mesh")), stringToBool(parm("New")));
59  return res;
60  }
61 
62  bool run(Mesh* mesh1, Mesh* mesh2, bool ShowVVCorrespondence, bool convert, bool newMethod = false); //Added convert parameter to enable choice of converting into a cell mesh
63  bool checkNhbd(Mesh* mesh1, Mesh* mesh2, vvGraph &T1, vvGraph &T2, bool ShowVVCorrespondence); //Original Correspondence Junctions
64 
65  bool checkNhbdNew(Mesh* mesh1, Mesh* mesh2, vvGraph &T1, vvGraph &T2, bool ShowVVCorrespondence);
66 
67  };
68 
69 typedef std::unordered_map<vertex, std::set<int> > JunctionCellsMap;
70 typedef std::unordered_map<int, std::set<vertex> > CellJunctionsMap;
71 typedef std::unordered_map<int, std::vector<vertex> > CellJunctionsInOrderMap;
72 
73 typedef std::pair<vertex, std::set<int> > VertLabelsP;
74 typedef std::pair<int, std::set<vertex> > CellJunctionsP;
75 typedef std::pair<int, std::vector<vertex> > CellJunctionsInOrderP;
76 
77  // mesh2 = later timepoint with parent labels
78  // mesh1 = earlier timepoint without parents
80  JunctionCellsMap junctionLabels1, junctionLabels2; // map from (junction) vertex to set of neighbor labels
81  CellJunctionsMap cellJunctions1, cellJunctions2; // map from cell label to vertices of its junctions
83  std::unordered_map<vertex, vertex> J1J2, J2J1;
84 
85  std::map<int, Point3d> labelParentCenterMap;
86  std::map<int, Point3d> labelDaughtersCenterMap;
87  };
88 
89  mgxBase_EXPORT void findCellJunctionsInOrder(Mesh* mesh, vvGraph& S, JunctionInformation& jInfo);
90  mgxBase_EXPORT void findCellJunctions(Mesh* mesh, vvGraph& S, JunctionInformation& jInfo);
91  mgxBase_EXPORT void findCellJunctionsParents(Mesh* mesh, vvGraph& S, JunctionInformation& jInfo);
92 
96  class mgxBase_EXPORT GrowthDirections : public Process
97  {
98  public:
99  GrowthDirections(const Process& process) : Process(process)
100  {
101  setName("Mesh/Cell Axis/PDG/Compute Growth Directions");
102  setDesc("Compute PDGs based on correspondence between junctions.\n"
103  "Adapted from Goodall and Green, 'Quantitative Analysis of Surface Growth.'Botanical Gazette (1986) \n"
104  "and Dumais and Kwiatkowska, 'Analysis of surface growth in shoot apices.'Plant Journal (2002)");
105  setIcon(QIcon(":/images/PDG.png"));
106  }
107  bool run()
108  {
109  if(!checkState().mesh(MESH_NON_EMPTY, 0).mesh(MESH_NON_EMPTY, 1))
110  return false;
111 
112  Mesh* mesh1, *mesh2;
113  if(currentMesh() == mesh(0)) {
114  mesh1 = mesh(0);
115  mesh2 = mesh(1);
116  } else if(currentMesh() == mesh(1)) {
117  mesh2 = mesh(0);
118  mesh1 = mesh(1);
119  } else
120  return false;
121 
122  bool res = run(mesh1, mesh2);
123  return res;
124  }
125 
126  bool run(Mesh* mesh1, Mesh* mesh2);
127  };
128 
132  class mgxBase_EXPORT DisplayPDGs : public Process
133  {
134  public:
135  enum ParmNames { pDisplayHeatMap, pScaleHeatMap, pRangeHeatLow, pRangeHeatHigh, pDisplayAxis,
136  pColorPos, pColorNeg, pAxisWidth, pAxisScale, pAxisOffset, pAnisotropyThreshold, pCustomShear, pNumParms};
137 
138  DisplayPDGs(const Process& process) : Process(process)
139  {
140  setName("Mesh/Cell Axis/PDG/Display Growth Directions");
141  setDesc("Display the principle growth directions on a vertex level");
142  setIcon(QIcon(":/images/PDG.png"));
143 
144  addParm("Heatmap","Display stretch ratio values in max or min direction as a color map.\n"
145  "stretch ratio = (length after/length before). No deformation means stretch ratio = 1.","StretchMax", QStringList() << "None" << "StretchMax" << "StretchMin" << "Aniso=StretchMax/StretchMin" << "StretchMax-StretchMin" << "ProductStretches" << "StretchCustomX" << "StretchCustomY" << "StretchCustomX-StretchCustomY" << "CustomX Growth Proportion" << "CustomY Growth Proportion" << "AnisoCustom" << "Shear" << "AnisoRatio"); // 0
146  addParm("ScaleHeat","Scale heat map","Auto", QStringList() << "None" << "Auto" << "Manual");
147  addParm("Heat min","High bound heat map","1");
148  addParm("Heat max","Low bound heat map","3");
149  addParm("Show Axis","Draw directions as vectors, scaled by strain.\n"
150  "strain = (stretch ratio - 1). No deformation means strain = 0.","Both", QStringList() << "Both" << "StrainMax" << "StretchMax-StretchMin" << "StrainMin" << "BothCustom" << "StrainCustomX" << "StrainCustomY" << "None"); // 4
151  addParm("Color +","Color used for expansion (strain > 0)","white", QColor::colorNames());
152  addParm("Color -","Color used for shrinkage (strain < 0)","red", QColor::colorNames());
153  addParm("Line Width","Line Width","2.0");
154  addParm("Line Scale","Length of the vectors = Scale * Strain.","2.0");
155  addParm("Line Offset","Draw the vector ends a bit tilted up for proper display on surfaces.","0.1");
156  addParm("Threshold","Minimal value of anisotropy (= stretchMax/StretchMin) required for drawing PDGs. \n"
157  "Use a value above 1.","0.0");
158  addParm("Custom Dir Shear","Custom Direction Shear","No",booleanChoice());
159  addParm("Min Dis Vtx","Min Dis Vtx","1.0");
160  }
161 
162  bool initialize(QWidget* parent);
163 
164  // Process the parameters
165  void processParms();
166 
167  bool run()
168  {
169  if(!checkState().mesh(MESH_NON_EMPTY))
170  return false;
171  return run(currentMesh());
172  }
173 
174  bool run(Mesh* mesh)
175  {
176  processParms();
177  return run(mesh, DisplayHeatMap, ScaleHeatMap, RangeHeat, DisplayAxis,
178  ColorPos, ColorNeg, AxisWidth, AxisScale, AxisOffset, AnisotropyThreshold, CustomShear);
179  }
180 
181 
182  bool run(Mesh* mesh, const QString displayHeatMap, const QString scaleHeatMap, const Point2d &rangeHeat,
183  const QString displayAxis, const QColor& colorPos, const QColor& colorNeg, float axisWidth, float axisScale,
184  float axisOffset, float anisotropyThreshold, bool customShear);
185 
186 
187 
188 
189  private:
190  QString DisplayHeatMap;
191  QString ScaleHeatMap;
192  Point2d RangeHeat;
193  QString DisplayAxis;
194  QColor ColorPos;
195  QColor ColorNeg;
196  float AxisWidth;
197  float AxisScale;
198  float AxisOffset;
199  float AnisotropyThreshold;
200  bool CustomShear;
201  };
203 
204 
208  class mgxBase_EXPORT DisplayPDGsVertex : public Process
209  {
210  public:
211  enum ParmNames { pDisplayHeatMap, pScaleHeatMap, pRangeHeatLow, pRangeHeatHigh, pDisplayAxis,
212  pColorPos, pColorNeg, pAxisWidth, pAxisScale, pAxisOffset, pAnisotropyThreshold, pCustomShear, pVtxMinDis, pNumParms};
213 
214  DisplayPDGsVertex(const Process& process) : Process(process)
215  {
216  setName("Mesh/Cell Axis/Deformation Gradient/Display Vertex Gradient");
217  setDesc("Display the principle growth directions on a vertex level");
218  setIcon(QIcon(":/images/PDG.png"));
219 
220  addParm("Heatmap","Display stretch ratio values in max or min direction as a color map.\n"
221  "stretch ratio = (length after/length before). No deformation means stretch ratio = 1.","StretchMax", QStringList() << "None" << "StretchMax" << "StretchMin" << "Aniso" << "StretchMax-StretchMin" << "ProductStretches" << "StretchCustomX" << "StretchCustomY" << "StretchCustomX-StretchCustomY" << "CustomX Growth Proportion" << "CustomY Growth Proportion" << "AnisoCustom" << "Shear" << "AnisoRatio"); // 0
222  addParm("ScaleHeat","Scale heat map","Auto", QStringList() << "None" << "Auto" << "Manual");
223  addParm("Heat min","High bound heat map","1");
224  addParm("Heat max","Low bound heat map","3");
225  addParm("Show Axis","Draw directions as vectors, scaled by strain.\n"
226  "strain = (stretch ratio - 1). No deformation means strain = 0.","Both", QStringList() << "Both" << "StrainMax" << "StretchMax-StretchMin" << "StrainMin" << "BothCustom" << "StrainCustomX" << "StrainCustomY" << "None");
227  addParm("Color +","Color used for expansion (strain > 0)","white", QColor::colorNames());
228  addParm("Color -","Color used for shrinkage (strain < 0)","red", QColor::colorNames());
229  addParm("Line Width","Line Width","2.0"); // 7
230  addParm("Line Scale","Length of the vectors = Scale * Strain.","2.0");
231  addParm("Line Offset","Draw the vector ends a bit tilted up for proper display on surfaces.","0.1");
232  addParm("Threshold","Minimal value of anisotropy (= stretchMax/StretchMin) required for drawing PDGs.\n"
233  "Use a value above 1.","0.0");
234  addParm("Custom Dir Shear","Custom Direction Shear","No",booleanChoice());
235  addParm("Min Dis Vtx","Min Dis Vtx","1.0");
236  }
237 
238  bool initialize(QWidget* parent);
239 
240  // Process the parameters
241  void processParms();
242 
243  bool run()
244  {
245  if(!checkState().mesh(MESH_NON_EMPTY))
246  return false;
247  return run(currentMesh());
248  }
249 
250  bool run(Mesh* mesh)
251  {
252  processParms();
253  return run(mesh, DisplayHeatMap, ScaleHeatMap, RangeHeat, DisplayAxis,
254  ColorPos, ColorNeg, AxisWidth, AxisScale, AxisOffset, AnisotropyThreshold, CustomShear, vtxMinDis);
255  }
256 
257  bool run(Mesh* mesh, const QString displayHeatMap, const QString scaleHeatMap, const Point2d &rangeHeat,
258  const QString displayPDGs, const QColor& colorPos, const QColor& colorNeg, float axisLineWidth,
259  float scaleAxisLength, float axisOffset, float anisotropyThreshold, bool customShear, double vtxMinDis);
260 
261  private:
262  QString DisplayHeatMap;
263  QString ScaleHeatMap;
264  Point2d RangeHeat;
265  QString DisplayAxis;
266  QColor ColorPos;
267  QColor ColorNeg;
268  float AxisWidth;
269  float AxisScale;
270  float AxisOffset;
271  float AnisotropyThreshold;
272  bool CustomShear;
273  double vtxMinDis;
274  };
275 
276 
277  class mgxBase_EXPORT AveragePDGs : public Process
278  {
279  public:
280  AveragePDGs(const Process& process) : Process(process)
281  {
282  setName("Mesh/Cell Axis/PDG/Average Growth Directions");
283  setDesc("Averages growth directions of neighboring cells");
284  setIcon(QIcon(":/images/PDG.png"));
285 
286  addParm("Project Directions on Surface","Project Directions on Surface","Yes",booleanChoice());
287  addParm("Weighting","Weighting","none",QStringList() << "none" << "n"<<"area"<<"geometric mean"<<"area weighted geometric mean");
288 
289  }
290 
291  bool run()
292  {
293  if(!checkState().mesh(MESH_NON_EMPTY))
294  return false;
295  return run(currentMesh(),stringToBool(parm("Project Directions on Surface")),parm("Weighting"));
296  }
297  bool run(Mesh *m,bool projSurf,QString avgType);
298 
299  };
300 
301 }
302 #endif
mgx::JunctionInformation::cellJunctions2
CellJunctionsMap cellJunctions2
Definition: MeshProcessPDG.hpp:81
mgx::findCellJunctionsInOrder
mgxBase_EXPORT void findCellJunctionsInOrder(Mesh *mesh, vvGraph &S, JunctionInformation &jInfo)
mgx::findCellJunctions
mgxBase_EXPORT void findCellJunctions(Mesh *mesh, vvGraph &S, JunctionInformation &jInfo)
mgx::AveragePDGs::run
bool run()
Runs the process.
Definition: MeshProcessPDG.hpp:291
Process.hpp
mgx::JunctionInformation
Definition: MeshProcessPDG.hpp:79
mgx::CorrespondenceJunctions::run
bool run()
Runs the process.
Definition: MeshProcessPDG.hpp:44
mgx::DisplayPDGsVertex::DisplayPDGsVertex
DisplayPDGsVertex(const Process &process)
Definition: MeshProcessPDG.hpp:214
mgx::JunctionInformation::J2J1
std::unordered_map< vertex, vertex > J2J1
Definition: MeshProcessPDG.hpp:83
mgx::DisplayPDGsVertex::run
bool run(Mesh *mesh)
Definition: MeshProcessPDG.hpp:250
mgx::DisplayPDGs::ParmNames
ParmNames
Definition: MeshProcessPDG.hpp:135
mgx::DisplayPDGsVertex
Definition: MeshProcessPDG.hpp:208
mgx::JunctionInformation::cellJunctionInOrder1
CellJunctionsInOrderMap cellJunctionInOrder1
Definition: MeshProcessPDG.hpp:82
mgx::DisplayPDGs::run
bool run(Mesh *mesh)
Definition: MeshProcessPDG.hpp:174
mgx::DisplayPDGs::run
bool run()
Runs the process.
Definition: MeshProcessPDG.hpp:167
mgx::DisplayPDGsVertex::run
bool run()
Runs the process.
Definition: MeshProcessPDG.hpp:243
mgx::AveragePDGs::AveragePDGs
AveragePDGs(const Process &process)
Definition: MeshProcessPDG.hpp:280
mgx::JunctionInformation::labelDaughtersCenterMap
std::map< int, Point3d > labelDaughtersCenterMap
Definition: MeshProcessPDG.hpp:86
mgx::JunctionInformation::junctionLabels1
JunctionCellsMap junctionLabels1
Definition: MeshProcessPDG.hpp:80
mgx::JunctionInformation::junctionLabels2
JunctionCellsMap junctionLabels2
Definition: MeshProcessPDG.hpp:80
mgx::VertLabelsP
std::pair< vertex, std::set< int > > VertLabelsP
Definition: MeshProcessPDG.hpp:73
mgx
Distributed matrix library.
Definition: Assert.hpp:26
mgx::customDirectionTensor
mgxBase_EXPORT SymmetricTensor customDirectionTensor(SymmetricTensor origTensor, Point3f customX, Point3f customY, bool shearB)
mgx::DisplayPDGs
Definition: MeshProcessPDG.hpp:132
mgx::findCellJunctionsParents
mgxBase_EXPORT void findCellJunctionsParents(Mesh *mesh, vvGraph &S, JunctionInformation &jInfo)
mgx::CellJunctionsP
std::pair< int, std::set< vertex > > CellJunctionsP
Definition: MeshProcessPDG.hpp:74
mgx::AveragePDGs
Definition: MeshProcessPDG.hpp:277
mgx::DisplayPDGs::pScaleHeatMap
@ pScaleHeatMap
Definition: MeshProcessPDG.hpp:135
mgx::Process
Definition: Process.hpp:219
mgx::JunctionCellsMap
std::unordered_map< vertex, std::set< int > > JunctionCellsMap
Definition: MeshProcessPDG.hpp:69
mgx::Point3f
Vector< 3, float > Point3f
Definition: CuttingSurface.hpp:25
mgx::stringToBool
mgx_EXPORT bool stringToBool(const QString &string)
Helper function converting a string into a boolean.
mgx::GrowthDirections::GrowthDirections
GrowthDirections(const Process &process)
Definition: MeshProcessPDG.hpp:99
mgx::lengthCustomDirTensor3D
mgxBase_EXPORT double lengthCustomDirTensor3D(SymmetricTensor origTensor, Point3f customDir)
mgx::SymmetricTensor
SymmetricTensor SymmetricTensor
Definition: Geometry.hpp:45
mgx::DisplayPDGs::DisplayPDGs
DisplayPDGs(const Process &process)
Definition: MeshProcessPDG.hpp:138
mgx::CorrespondenceJunctions
Definition: MeshProcessPDG.hpp:28
mgx::CorrespondenceJunctions::CorrespondenceJunctions
CorrespondenceJunctions(const Process &process)
Definition: MeshProcessPDG.hpp:31
mgx::DisplayPDGsVertex::pVtxMinDis
@ pVtxMinDis
Definition: MeshProcessPDG.hpp:212
mgx::Mesh
Definition: Mesh.hpp:54
mgx::CellJunctionsInOrderP
std::pair< int, std::vector< vertex > > CellJunctionsInOrderP
Definition: MeshProcessPDG.hpp:75
mgx::DisplayPDGsVertex::ParmNames
ParmNames
Definition: MeshProcessPDG.hpp:211
mgx::JunctionInformation::J1J2
std::unordered_map< vertex, vertex > J1J2
Definition: MeshProcessPDG.hpp:83
mgx::Vector< 2, double >
mgx::GrowthDirections
Definition: MeshProcessPDG.hpp:96
MeshProcessCellMesh.hpp
mgx::CellJunctionsInOrderMap
std::unordered_map< int, std::vector< vertex > > CellJunctionsInOrderMap
Definition: MeshProcessPDG.hpp:71
mgx::VVGraph< VertexData, EdgeData >
mgx::JunctionInformation::cellJunctions1
CellJunctionsMap cellJunctions1
Definition: MeshProcessPDG.hpp:81
mgx::JunctionInformation::labelParentCenterMap
std::map< int, Point3d > labelParentCenterMap
Definition: MeshProcessPDG.hpp:85
mgx::CellJunctionsMap
std::unordered_map< int, std::set< vertex > > CellJunctionsMap
Definition: MeshProcessPDG.hpp:70
mgx::DisplayPDGsVertex::pScaleHeatMap
@ pScaleHeatMap
Definition: MeshProcessPDG.hpp:211
mgx::GrowthDirections::run
bool run()
Runs the process.
Definition: MeshProcessPDG.hpp:107
mgx::ScaleHeatMap
Clear label to parent mapping.
Definition: MeshProcessHeatMap.hpp:391