From c9169048678438a0bb9a9977cc8ab010a4be5a9b Mon Sep 17 00:00:00 2001 From: ARDATI-Rami Date: Wed, 21 May 2025 15:48:24 +0200 Subject: [PATCH 1/9] Add batch processing script for VirtualLeaf model: implement XML handling, simulation execution, and result plotting --- Old_run_in_batch.py | 130 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 Old_run_in_batch.py diff --git a/Old_run_in_batch.py b/Old_run_in_batch.py new file mode 100644 index 0000000..550afe7 --- /dev/null +++ b/Old_run_in_batch.py @@ -0,0 +1,130 @@ +import xml.etree.ElementTree as ET +from pathlib import Path +import subprocess +import numpy as np + +class MyXML: + """Utility to clone a LeafML file and tweak simple entries.""" + + def __init__(self, templatefile: str): + self.tree = ET.parse(templatefile) + self.root = self.tree.getroot() + self.parameters = self.root.find("parameter") + + def set_simple_param(self, name: str, value) -> None: + """Change the ‘val’ attribute of .""" + par = self.parameters.find(f"./par[@name='{name}']") + if par is None: + raise KeyError(f"Parameter '{name}' not found in XML") + par.set("val", str(value)) + + def write(self, filename: str) -> None: + """Write a full XML document in UTF‑8.""" + # ① simply pass the *path* to ElementTree; it opens the file in 'wb' + self.tree.write(filename, encoding="utf-8", xml_declaration=True) + + # --- alternative --- + # with open(filename, "wb") as fh: # binary mode! + # self.tree.write(fh, encoding="utf-8", xml_declaration=True) + +# ----------------------------------------------------------------------------- +leaf_in = Path("data/leaves/cambium.xml") +model = "libmodel_exp.so" +# Fixed expansion rate and different elastic modulus values +number_of_runs = 3 +for r in number_of_runs: + # Create unique output names + datadir = f"/home/ardati/Data_VirtualLeaf/Cambium_r_{r}" + output_suffix = f"_{r}" + leaf_out = leaf_in.with_name(leaf_in.stem + output_suffix + ".xml") + + # Create and modify XML + xml = MyXML(leaf_in) + xml.set_simple_param("maxt", 1500) + xml.set_simple_param("datadir", datadir) + xml.set_simple_param("xml_storage_stride", 1) # Pour enregiustrer tous les pas de temps + xml.set_simple_param("rseed", 1) #set seed to 1 for reproducibility + + + # Write XML file + xml.write(leaf_out) + + # Run simulation + print(f"Running simulation with number {r} and output {leaf_out}") + subprocess.run([ + "./bin/VirtualLeaf", + "-b", + "-l", str(leaf_out), + "-m", model + ], check=True) + +# After all simulations complete, analyze and plot the results +import matplotlib.pyplot as plt +import os +import re + +# Collect area data for each elastic modulus value +areas = [] + +for r in number_of_runs: + datadir = f"/home/ardati/Data_VirtualLeaf/model_exp_pressure_em{r}" + print(f"getcwd : {os.getcwd()}") + # Find the latest XML file based on numeric part + xml_files = [f for f in os.listdir(datadir) if f.endswith('.xml')] + if not xml_files: + print(f"No XML files found in {datadir}") + continue + + # Extract numbers from filenames like "leaf.000050.xml" + pattern = re.compile(r'leaf\.(\d+)\.xml') + latest_num = -1 + latest_file = None + + for file in xml_files: + match = pattern.match(file) + if match: + num = int(match.group(1)) + if num > latest_num: + latest_num = num + latest_file = file + + if not latest_file: + print(f"No matching XML files found in {datadir}") + continue + + latest_xml = os.path.join(datadir, latest_file) + print(f"Using {latest_file} for elastic_modulus {elastic_modulus}") + + # Parse the XML + # Parse the XML + tree = ET.parse(latest_xml) + root = tree.getroot() + cells = root.find("cells") + if cells is not None: + found = False + for cell in cells.findall("cell"): + if cell.get("index") == "0": + found = True + area = float(cell.get("area")) + areas.append((elastic_modulus, area)) + print(f"Elastic modulus {elastic_modulus}: Cell area = {area}") + break # Stop after finding the target cell + if not found: + print(f"Cell with index 131 not found in {latest_xml}") + +# Plot the results +if areas: + modulus_values, area_values = zip(*sorted(areas)) + area_mean = sum(area_values) / len(area_values) + plt.figure(figsize=(10, 6)) + plt.plot(modulus_values, area_values, 'o-') + # plt.ylim(area_mean*0.9, area_mean*1.1) # fixed, generous y‑window + # plt.yticks(np.arange(area_mean, area_mean*1.1, 2)) # tidy ticks + plt.xlabel('Elastic Modulus') + plt.ylabel('Cell Area') + plt.title(f'Cell Area vs Elastic Modulus (Expansion Rate = {expansion_rate})') + plt.grid(True) + plt.savefig('area_vs_elastic_modulus.png') + plt.show() +else: + print("No area data found to plot") \ No newline at end of file From 0229ed0396f2be4a17baa6d2ad4c8dd69ff5a484 Mon Sep 17 00:00:00 2001 From: ARDATI-Rami Date: Thu, 22 May 2025 19:11:19 +0200 Subject: [PATCH 2/9] Add initial area calculation to CellBase: implement SetInitialArea method and add getter for InitialArea --- src/Library/cellbase.cpp | 5 +++++ src/Library/cellbase.h | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Library/cellbase.cpp b/src/Library/cellbase.cpp index f574c71..6001b08 100755 --- a/src/Library/cellbase.cpp +++ b/src/Library/cellbase.cpp @@ -701,4 +701,9 @@ void CellBase::correctNeighbors() {} double CellBase::elastic_limit() { return std::nan("1"); } + +double CellBase::SetInitialArea(void) { + InitialArea = this->CalcArea(); + return InitialArea; +} /* finis*/ diff --git a/src/Library/cellbase.h b/src/Library/cellbase.h index e3d954b..8f55efc 100755 --- a/src/Library/cellbase.h +++ b/src/Library/cellbase.h @@ -101,6 +101,7 @@ class CellBase : public QObject, public Vector public: CellBase(QObject *parent=0); CellBase(double x,double y,double z=0); // constructor + double InitialArea = 0.0; // Initialize to zero virtual ~CellBase() { delete[] chem; @@ -112,6 +113,7 @@ class CellBase : public QObject, public Vector CellBase(const CellBase &src); // copy constructor virtual bool BoundaryPolP(void) const { return false; } + const list& getNodes() const { return nodes; } // Ajout Rouges 2025 CellBase operator=(const CellBase &src); // assignment operator CellBase operator=(const Vector &src); @@ -199,6 +201,8 @@ class CellBase : public QObject, public Vector inline int Index(void) const { return index; } + double SetInitialArea(void); // Calculate and store the initial area + double GetInitialArea(void) const { return InitialArea; } // Getter method void SetTargetArea(double tar_ar) { target_area=tar_ar; } inline void SetTargetLength(double tar_l) { target_length=tar_l; } @@ -584,7 +588,9 @@ inline Vector PINdir(CellBase *here, CellBase *nb, Wall *w) { return w->getTransporter( here, 1) * w->getInfluxVector(here); } - #endif + + + /* finis*/ From b3e3c41eb57076086e473a3c824dfee17618c308 Mon Sep 17 00:00:00 2001 From: ARDATI-Rami Date: Thu, 22 May 2025 19:12:20 +0200 Subject: [PATCH 3/9] Add elastic modulus parameter handling: implement reading from XML and error checking --- src/Library/parameter.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Library/parameter.cpp b/src/Library/parameter.cpp index db9d9cd..ed27647 100644 --- a/src/Library/parameter.cpp +++ b/src/Library/parameter.cpp @@ -1935,6 +1935,10 @@ if (!strcmp(namec, "elastic_limit")) { elastic_limit = standardlocale.toDouble(valc, &ok); if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'elastic_limit' from XML file.",valc); } } +if (!strcmp(namec, "elastic_modulus")) { + elastic_modulus = standardlocale.toDouble(valc, &ok); + if (!ok) { MyWarning::error("Read error: cannot convert string \"%s\" to double while reading parameter 'elastic_modulus' from XML file.",valc); } +} if (!strcmp(namec, "movie")) { movie = strtobool(valc); } From b136dd4c74c7370acb7db6d71ea080c47148d30d Mon Sep 17 00:00:00 2001 From: ARDATI-Rami Date: Thu, 22 May 2025 19:12:40 +0200 Subject: [PATCH 4/9] Refactor cambium cell stiffness handling: adjust stiffness parameters for cell types and implement wall stiffness printing for debugging --- src/Models/Cambium/cambium.cpp | 187 ++++++++++++++++++++++----------- 1 file changed, 123 insertions(+), 64 deletions(-) diff --git a/src/Models/Cambium/cambium.cpp b/src/Models/Cambium/cambium.cpp index e6fd857..31bdf60 100755 --- a/src/Models/Cambium/cambium.cpp +++ b/src/Models/Cambium/cambium.cpp @@ -37,7 +37,7 @@ Cell Types and Their Behavior: CellType(0) : Bark Cells - Can grow slightly (prevents potential bugs if restricted completely). - Cannot divide. -- Stiffness = 10 × Cambium stiffness. +- Stiffness = 5 × Cambium stiffness. CellType(1) : Cambium Cells - Can grow until a specific threshold is reached. @@ -52,7 +52,7 @@ CellType(2) : Growing Xylem Cells CellType(3) : Mature Xylem Cells - Cannot grow or divide. -- Stiffness = 100 × Cambium stiffness. +- Stiffness = 5 × Cambium stiffness. */ @@ -78,28 +78,76 @@ void cambium::AfficherNoeuds(CellBase *c) { // Node operations can be added here if needed } } +void PrintWallStiffness(CellBase *c) { + qDebug() << "Cell" << c->Index() << "wall stiffness values:"; + int wall_count = 0; + + c->LoopWallElements([&wall_count](auto wallElementInfo){ + double stiffness = wallElementInfo->getWallElement()->getStiffness(); + qDebug() << " Wall element" << wall_count++ << "stiffness:" << stiffness; + }); +} void cambium::SetCellTypeProperties(CellBase *c) { // Set cell properties /* SetLambdaLength property notes: + - Default value 0 for all cell mode 0 - High values (>2) cause cells to "flow" - Very low values (<0.01) for bark prevent cells from moving between bark cells - This is the elasticity coefficient of the wall, allowing it to extend to lambda * initial value */ - if (c->CellType()==0){ - c-> SetWallStiffness(1); - c-> SetLambdaLength(0); + // Define stiffness parameters for different cell types + const double cambium_added_stiffness = 0; // Base stiffness (used by cambium) + const double bark_added_stiffness = 0; // Additional stiffness for bark cells + const double mature_xylem_added_stiffness = 0; // Additional stiffness for mature xylem + + if (c->CellType()==0) { // Bark Cells + c->SetLambdaLength(0); + + // Set stiffness to default + added stiffness for bark + double stiffness = bark_added_stiffness; + double* p_stiffness = &stiffness; + + c->LoopWallElements([p_stiffness](auto wallElementInfo){ + wallElementInfo->getWallElement()->setStiffness(*p_stiffness); + }); } - else if (c->CellType()==1){ - c-> SetWallStiffness(1); - c-> SetLambdaLength(0); + else if (c->CellType()==1) { // Cambium Cells + c->SetLambdaLength(0); + + // Set stiffness to default (no modification) + double stiffness = cambium_added_stiffness; + double* p_stiffness = &stiffness; + + c->LoopWallElements([p_stiffness](auto wallElementInfo){ + wallElementInfo->getWallElement()->setStiffness(*p_stiffness); + }); } - else if (c->CellType()==2){ - c-> SetWallStiffness(1); - c-> SetLambdaLength(0); + else if (c->CellType()==2) { // Growing Xylem Cells + c->SetLambdaLength(0); + + // Calculate growth progress (0.0 to 1.0) + double progress = (c->Area() - c->BaseArea()) / (2.0 * c->BaseArea()); + progress = std::min(1.0, std::max(0.0, progress)); // Clamp between 0 and 1 + + // Gradually increase stiffness from default to higher values as the cell grows + // Add up to 0.5 additional stiffness as the cell reaches full growth + double stiffness = mature_xylem_added_stiffness * progress; + double* p_stiffness = &stiffness; + + c->LoopWallElements([p_stiffness](auto wallElementInfo){ + wallElementInfo->getWallElement()->setStiffness(*p_stiffness); + }); } - else { - c-> SetWallStiffness(1); - c-> SetLambdaLength(0); + else { // Mature Xylem Cells (Type 3) + c->SetLambdaLength(0); + + // Set stiffness to default + added stiffness for mature xylem + double stiffness = mature_xylem_added_stiffness; + double* p_stiffness = &stiffness; + + c->LoopWallElements([p_stiffness](auto wallElementInfo){ + wallElementInfo->getWallElement()->setStiffness(*p_stiffness); + }); } } @@ -224,9 +272,19 @@ void cambium::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *d //} void cambium::CellHouseKeeping(CellBase *c) { // How cells behave after division - qDebug() << "Cell elastic limit :" << c->elastic_limit() ; + // Set initial area on first call to this function for each cell + static std::set initialized_cells; + if (initialized_cells.find(c->Index()) == initialized_cells.end()) { + c->SetInitialArea(); + initialized_cells.insert(c->Index()); + } - SetCellTypeProperties(c); + qDebug() << "Cell type: " << c->CellType() << ", Area: " << c->Area() << ", BaseArea: " << c->BaseArea() << "InitialArea" <GetInitialArea(); + // Print wall stiffness for debugging +// if (c->Index() == 28) { // Only print for a specific cell if desired +// PrintWallStiffness(c); +// } +// SetCellTypeProperties(c); // Check if a cambium cell is no longer adjacent to the bark, if not it has to be transformed into a Growing Xylem cell if (c->CellType() == 1) { @@ -268,54 +326,55 @@ void cambium::CellHouseKeeping(CellBase *c) { // How cells behave after division else if (c->CellType() == 0) { /* If the cell is a bark cell (type 0), we need to slightly enlarge it to prevent excessive stretching, which could cause issues in the simulation. This adjustment ensures stability during runtime. */ - - // Get current area values - double area = c->Area(); - double baseArea = c->BaseArea(); - - // Use static maps to store growth data for each cell by its index - static std::map growth_additions; - static std::map last_growth_step; - static int current_step = 0; - - // Increment step counter each time function is called (simulation step) - current_step++; - - // Initialize growth addition for this cell if not present - if (growth_additions.find(c->Index()) == growth_additions.end()) { - growth_additions[c->Index()] = 0.0; - last_growth_step[c->Index()] = 0; - } - - // Check if we need to increase the growth_addition (every 500 simulation steps) - if (current_step - last_growth_step[c->Index()] >= 200) { - // Increase growth_addition by 5% of baseArea - growth_additions[c->Index()] += baseArea * 0.15; - // Update last growth step - last_growth_step[c->Index()] = current_step; - - if (c->Index() == 28) { - qDebug() << "Cell 28 - GROWTH UPDATE - Step:" << current_step - << "New Growth Addition:" << growth_additions[c->Index()]; - } - } - - // Use effective base area (original baseArea + growth_addition) - double effective_base_area = baseArea + growth_additions[c->Index()]; - - // Maintain effective base area if cell has shrunk - if (area < effective_base_area) { - // Gradually increase target area to reach effective base area - c->EnlargeTargetArea(par->cell_expansion_rate); - - if (c->Index() == 28) { - qDebug() << "Cell 28 - ENLARGING TARGET AREA - Step:" << current_step - << "Effective base area:" << effective_base_area - << "Current area:" << area - << "Target area:" << c->TargetArea() - << "Rate:" << par->cell_expansion_rate; - } - } + c->EnlargeTargetArea(0.5 * par->cell_expansion_rate); +// // Get current area values +// double area = c->Area(); +// double baseArea = c->BaseArea(); +// +// // Use static maps to store growth data for each cell by its index +// static std::map growth_additions; +// static std::map last_growth_step; +// static int current_step = 0; +// +// // Increment step counter each time function is called (simulation step) +// current_step++; +// +// // Initialize growth addition for this cell if not present +// if (growth_additions.find(c->Index()) == growth_additions.end()) { +// growth_additions[c->Index()] = 0.0; +// last_growth_step[c->Index()] = 0; +// } +// +// // Check if we need to increase the growth_addition (every 500 simulation steps) +// if (current_step - last_growth_step[c->Index()] >= 200) { +// +// // Increase growth_addition by 25% of baseArea +// growth_additions[c->Index()] += baseArea * 0.25; +// // Update last growth step +// last_growth_step[c->Index()] = current_step; +// +// if (c->Index() == 28) { +// qDebug() << "Cell 28 - GROWTH UPDATE - Step:" << current_step +// << "New Growth Addition:" << growth_additions[c->Index()]; +// } +// } +// +// // Use effective base area (original baseArea + growth_addition) +// double effective_base_area = baseArea + growth_additions[c->Index()]; +// +// // Maintain effective base area if cell has shrunk +// if (area < effective_base_area) { +// // Gradually increase target area to reach effective base area +// c->EnlargeTargetArea(par->cell_expansion_rate); +// +// if (c->Index() == 28) { +// qDebug() << "Cell 28 - ENLARGING TARGET AREA - Step:" << current_step +// << "Effective base area:" << effective_base_area +// << "Current area:" << area +// << "Target area:" << c->TargetArea() +// << "Rate:" << par->cell_expansion_rate; +// } +// } } } From 8e5628f1959d671cd5576d506e6a950faf265496 Mon Sep 17 00:00:00 2001 From: ARDATI-Rami Date: Wed, 11 Jun 2025 20:11:49 +0200 Subject: [PATCH 5/9] Enhance debugging and cell division logic: add debug flags for wall stiffness, implement random target length for nodes, and refine cell division types with detailed logging --- Change_XML.py | 842 ++++++++++----------- src/GUI/GUI.pro | 2 + src/GUI/VirtualLeaf.cpp | 2 +- src/GUI/cell.cpp | 491 ++++++++----- src/GUI/cell.h | 73 +- src/GUI/mesh.cpp | 138 +++- src/GUI/mesh.h | 5 +- src/Library/cellbase.h | 15 + src/Models/Cambium/Makefile | 2 +- src/Models/Cambium/Makefile.cambium | 1010 -------------------------- src/Models/Cambium/cambium.cpp | 67 +- src/Models/Cambium/moc_predefs.h | 4 +- src/Models/Tutorial1A/tutorial1A.cpp | 6 + src/Models/Tutorial1C/tutorial1C.cpp | 4 +- src/VirtualLeaf.pro | 18 +- 15 files changed, 965 insertions(+), 1714 deletions(-) delete mode 100644 src/Models/Cambium/Makefile.cambium diff --git a/Change_XML.py b/Change_XML.py index 68356a1..3f85f33 100644 --- a/Change_XML.py +++ b/Change_XML.py @@ -5,7 +5,7 @@ from virtualleaf_xml_model import VirtualLeaf_XML, Node import math -doc = VirtualLeaf_XML("data/leaves/cambium_virgin.xml") +doc = VirtualLeaf_XML("data/leaves/cambium.xml") doc.leaf.name = "Cambium_01" doc.leaf.date = str(date.today()) doc.leaf.simtime = 0 @@ -19,112 +19,128 @@ # Settings doc.settings.set_setting(name='save_movie_frames',value="true") +# Add random target_length to each node +import random +print("Adding random target_length (2.0-2.5) to each node...") +for node in doc.nodes.nodes: + # Generate random value between 2.0 and 2.5 + random_length = random.uniform(2.0, 2.5) + # Set the attribute on the node element + node.elem.set("target_length", f"{random_length:.6g}") -# Other -double_mesh = False - -coords = {n.nr: (n.x, n.y) for n in doc.nodes.nodes} -# add at the top of the script, near the imports, for convenience -id2node = {n.nr: n for n in doc.nodes.nodes} # nr → Node dataclass -nodes_elem = doc.nodes.elem -next_nr = max(coords) + 1 - - -if double_mesh: - # ── STEP 1 & 2 – global edge dictionary ────────────────────────────────── - edge2mid = {} # { (min(a,b), max(a,b)) : mid_id } - - for cell in doc.cells.cells: - verts = cell.vertices - for a, b in zip(verts, verts[1:] + verts[:1]): # closed ring - key = tuple(sorted((a, b))) - if key in edge2mid: - continue # midpoint already made - - # ---------------------------------------------------------------------- - # create ONE midpoint node for this geometric edge (shared by both cells) - # ---------------------------------------------------------------------- - x1, y1 = coords[a]; - x2, y2 = coords[b] - mx, my = (x1 + x2) / 2.0, (y1 + y2) / 2.0 - - na, nb = id2node[a], id2node[b] # Node dataclasses - - sam_flag = na.sam and nb.sam # TRUE only if both endpoints - boundary_flag = na.boundary and nb.boundary # are TRUE - fixed_flag = na.fixed and nb.fixed - - new_node_elem = etree.Element( - "node", - nr=str(next_nr), - x=f"{mx:.6g}", - y=f"{my:.6g}", - sam="true" if sam_flag else "false", - boundary="true" if boundary_flag else "false", - fixed="true" if fixed_flag else "false", - ) - - nodes_elem.append(new_node_elem) - new_nd = Node(next_nr, mx, my, sam_flag, boundary_flag, fixed_flag, new_node_elem) - doc.nodes.nodes.append(new_nd) - id2node[next_nr] = new_nd # keep lookup in sync - coords[next_nr] = (mx, my) - edge2mid[key] = next_nr - next_nr += 1 - - # ── STEP 3 & 4 – rebuild every cell with shared midpoints ──────────────── - indent_tail = "\n " - - for cell in doc.cells.cells: - old_ring = cell.vertices - new_ring = [] - - for a, b in zip(old_ring, old_ring[1:] + old_ring[:1]): - new_ring.append(a) - new_ring.append(edge2mid[tuple(sorted((a, b)))]) - - cell.vertices = new_ring # keep Python object in sync - - # keep the walls to re-attach later - walls = cell.elem.xpath("./wall") - - # 2) remove every existing child exactly once - for child in list(cell.elem.getchildren()): # make a real Python list first - cell.elem.remove(child) # no duplicates → no ValueError - - # -------------------------------------------------------------------------- - # 3) choose a geometry-aware sort key ← REPLACE THIS SINGLE LINE - # -------------------------------------------------------------------------- - - # OLD (pure numeric, gave ugly ordering): - # for idx in sorted(set(new_ring)): - - # NEW (angle about cell centroid): - vx, vy = zip(*(coords[i] for i in new_ring)) # coordinates of vertices - cx, cy = sum(vx) / len(vx), sum(vy) / len(vy) # centroid - - - def polar_angle(i): - x, y = coords[i] - return math.atan2(y - cy, x - cx) - +# ── housekeeping and save ──────────────────────────────────────────────── +objectify.deannotate(doc.root, cleanup_namespaces=True) +etree.indent(doc.tree, space=" ") +doc.save(output_xml) - for idx in sorted(set(new_ring), key=polar_angle): - n_elem = etree.SubElement(cell.elem, "node", n=str(idx)) - n_elem.tail = indent_tail - # re-attach walls - for w in walls: - cell.elem.append(w) - w.tail = indent_tail +# +# +# # Other +# double_mesh = False +# +# coords = {n.nr: (n.x, n.y) for n in doc.nodes.nodes} +# # add at the top of the script, near the imports, for convenience +# id2node = {n.nr: n for n in doc.nodes.nodes} # nr → Node dataclass +# nodes_elem = doc.nodes.elem +# next_nr = max(coords) + 1 +# +# +# if double_mesh: +# # ── STEP 1 & 2 – global edge dictionary ────────────────────────────────── +# edge2mid = {} # { (min(a,b), max(a,b)) : mid_id } +# +# for cell in doc.cells.cells: +# verts = cell.vertices +# for a, b in zip(verts, verts[1:] + verts[:1]): # closed ring +# key = tuple(sorted((a, b))) +# if key in edge2mid: +# continue # midpoint already made +# +# # ---------------------------------------------------------------------- +# # create ONE midpoint node for this geometric edge (shared by both cells) +# # ---------------------------------------------------------------------- +# x1, y1 = coords[a]; +# x2, y2 = coords[b] +# mx, my = (x1 + x2) / 2.0, (y1 + y2) / 2.0 +# +# na, nb = id2node[a], id2node[b] # Node dataclasses +# +# sam_flag = na.sam and nb.sam # TRUE only if both endpoints +# boundary_flag = na.boundary and nb.boundary # are TRUE +# fixed_flag = na.fixed and nb.fixed +# +# new_node_elem = etree.Element( +# "node", +# nr=str(next_nr), +# x=f"{mx:.6g}", +# y=f"{my:.6g}", +# sam="true" if sam_flag else "false", +# boundary="true" if boundary_flag else "false", +# fixed="true" if fixed_flag else "false", +# ) +# +# nodes_elem.append(new_node_elem) +# new_nd = Node(next_nr, mx, my, sam_flag, boundary_flag, fixed_flag, new_node_elem) +# doc.nodes.nodes.append(new_nd) +# id2node[next_nr] = new_nd # keep lookup in sync +# coords[next_nr] = (mx, my) +# edge2mid[key] = next_nr +# next_nr += 1 +# +# # ── STEP 3 & 4 – rebuild every cell with shared midpoints ──────────────── +# indent_tail = "\n " +# +# for cell in doc.cells.cells: +# old_ring = cell.vertices +# new_ring = [] +# +# for a, b in zip(old_ring, old_ring[1:] + old_ring[:1]): +# new_ring.append(a) +# new_ring.append(edge2mid[tuple(sorted((a, b)))]) +# +# cell.vertices = new_ring # keep Python object in sync +# +# # keep the walls to re-attach later +# walls = cell.elem.xpath("./wall") +# +# # 2) remove every existing child exactly once +# for child in list(cell.elem.getchildren()): # make a real Python list first +# cell.elem.remove(child) # no duplicates → no ValueError +# +# # -------------------------------------------------------------------------- +# # 3) choose a geometry-aware sort key ← REPLACE THIS SINGLE LINE +# # -------------------------------------------------------------------------- +# +# # OLD (pure numeric, gave ugly ordering): +# # for idx in sorted(set(new_ring)): +# +# # NEW (angle about cell centroid): +# vx, vy = zip(*(coords[i] for i in new_ring)) # coordinates of vertices +# cx, cy = sum(vx) / len(vx), sum(vy) / len(vy) # centroid +# +# +# def polar_angle(i): +# x, y = coords[i] +# return math.atan2(y - cy, x - cx) +# +# +# for idx in sorted(set(new_ring), key=polar_angle): +# n_elem = etree.SubElement(cell.elem, "node", n=str(idx)) +# n_elem.tail = indent_tail +# +# # re-attach walls +# for w in walls: +# cell.elem.append(w) +# w.tail = indent_tail # # ────────────────────────────────────────────────────────────────────────── # # SORT CELLS BY (radius, angle) → re-assign sequential indices # # -------------------------------------------------------------------------- # 1) centroid of the *whole* tissue – average of all node coords -tx, ty = np.mean(list(coords.values()), axis=0) +# tx, ty = np.mean(list(coords.values()), axis=0) # # # ─────────────────────────────────────────────────────────────────────────── # # CLUSTER + RADIAL-ANGULAR SORT → reassign cell.index & cell.id @@ -203,323 +219,323 @@ def polar_angle(i): # Reorder tags under to match their 'index' attribute # ──────────────────────────────────────────────────────────────────────────── -cells_parent = doc.root.find("cells") # top-level element -all_cells = list(cells_parent.findall("cell")) # snapshot of originals - -# sort the Element proxies by their integer index -sorted_cells = sorted( - all_cells, - key=lambda c: int(c.attrib.get("index", c.attrib.get("id", 0))) -) - -# remove all originals in one pass -for c in all_cells: - cells_parent.remove(c) - -# append back in the new order -for c in sorted_cells: - cells_parent.append(c) +# cells_parent = doc.root.find("cells") # top-level element +# all_cells = list(cells_parent.findall("cell")) # snapshot of originals # -# ──────────────────────────────────────────────────────────────────────────── -# COMPUTE & ATTACH target_length TO -# ──────────────────────────────────────────────────────────────────────────── - -# 1) collect unique edges from *refined* cells -edge_set = set() -for c in doc.cells.cells: - verts = c.vertices - for a, b in zip(verts, verts[1:] + verts[:1]): # closed loop - edge_set.add(tuple(sorted((a, b)))) - -# 2) compute lengths -lengths = [] -for a, b in edge_set: - x1, y1 = coords[a] - x2, y2 = coords[b] - lengths.append(math.hypot(x2 - x1, y2 - y1)) - -# 3) mean segment length and target length (half of mean) -mean_len = sum(lengths) / len(lengths) if lengths else 0.0 -target_len = mean_len/2 -print(f"Mean segment length: {mean_len:.6g}") -print(f"Target length (half mean): {target_len:.6g}") -# 4) attach as attribute on -nodes_elem.attrib["target_length"] = f"{target_len:.6g}" -# 5) add the new number of nodes to the element -nodes_elem.attrib["n"] = str(len(doc.nodes.nodes)) +# # sort the Element proxies by their integer index +# sorted_cells = sorted( +# all_cells, +# key=lambda c: int(c.attrib.get("index", c.attrib.get("id", 0))) +# ) +# +# # remove all originals in one pass +# for c in all_cells: +# cells_parent.remove(c) +# +# # append back in the new order +# for c in sorted_cells: +# cells_parent.append(c) +# # +# # ──────────────────────────────────────────────────────────────────────────── +# # COMPUTE & ATTACH target_length TO +# # ──────────────────────────────────────────────────────────────────────────── +# +# # 1) collect unique edges from *refined* cells +# edge_set = set() +# for c in doc.cells.cells: +# verts = c.vertices +# for a, b in zip(verts, verts[1:] + verts[:1]): # closed loop +# edge_set.add(tuple(sorted((a, b)))) +# +# # 2) compute lengths +# lengths = [] +# for a, b in edge_set: +# x1, y1 = coords[a] +# x2, y2 = coords[b] +# lengths.append(math.hypot(x2 - x1, y2 - y1)) +# +# # 3) mean segment length and target length (half of mean) +# mean_len = sum(lengths) / len(lengths) if lengths else 0.0 +# target_len = mean_len/2 +# print(f"Mean segment length: {mean_len:.6g}") +# print(f"Target length (half mean): {target_len:.6g}") +# # 4) attach as attribute on +# nodes_elem.attrib["target_length"] = f"{target_len:.6g}" +# # 5) add the new number of nodes to the element +# nodes_elem.attrib["n"] = str(len(doc.nodes.nodes)) +# # +# # ──────────────────────────────────────────────────────────────────────────── +# # RESET CHILDREN TO THE REFINED BOUNDARY LOOP +# # ──────────────────────────────────────────────────────────────────────────── +# +# # 1) find the boundary_polygon element +# poly = doc.cells.elem.find("boundary_polygon") +# if poly is None: +# raise RuntimeError("No found under .") +# +# # 2) collect all nodes flagged boundary="true" +# b_nodes = [n for n in doc.nodes.nodes if n.boundary] +# +# # 3) sort them CCW around tissue centre (tx,ty from before) +# def angle_about_center(node): +# x, y = node.x, node.y +# return math.atan2(y - ty, x - tx) +# +# b_nodes.sort(key=angle_about_center) +# +# # 4) wipe existing children and append fresh entries +# for ch in list(poly.getchildren()): +# poly.remove(ch) +# +# tail = "\n " # matches the indent in your file +# for n in b_nodes: +# elem = etree.SubElement(poly, "node", n=str(n.nr)) +# elem.tail = tail +# +# # reposition the boundary polygon +# cells_elem = doc.root.find("cells") +# poly = cells_elem.find("boundary_polygon") +# if poly is not None: +# cells_elem.remove(poly) +# cells_elem.append(poly) +# +# +# # ──────────────────────────────────────────────────────────────────────────── +# # REBUILD WALLS AS CONTIGUOUS SEGMENTS BETWEEN CELL PAIRS +# # ──────────────────────────────────────────────────────────────────────────── +# +# +# # 1) locate and clear the existing walls +# walls_parent = doc.root.find("walls") +# for w in list(walls_parent.getchildren()): +# walls_parent.remove(w) +# +# # 2) collect every undirected edge → the two cells sharing it +# edge2cells: dict[tuple[int,int], list[int]] = {} +# for c in doc.cells.cells: +# ci = int(c.elem.get("index")) +# verts = c.vertices +# for a, b in zip(verts, verts[1:] + verts[:1]): +# key = tuple(sorted((a, b))) +# edge2cells.setdefault(key, []).append(ci) +# +# # 3) group edges by the pair of cells (interior walls only) +# pair2edges: dict[tuple[int,int], list[tuple[int,int]]] = {} +# for edge, cells in edge2cells.items(): +# if len(cells) == 2: +# pair2edges.setdefault(tuple(sorted(cells)), []).append(edge) +# +# new_walls = [] +# +# for (c1, c2), edges in pair2edges.items(): +# # build adjacency for this wall +# adj: dict[int, list[int]] = defaultdict(list) +# for u, v in edges: +# adj[u].append(v) +# adj[v].append(u) +# +# # find endpoints (degree == 1) +# endpoints = [n for n, nbrs in adj.items() if len(nbrs) == 1] +# if len(endpoints) == 2: +# start, end = endpoints +# else: +# # fallback: pick the first edge’s nodes +# start, end = edges[0] +# +# # traverse from start to end +# ordered = [start] +# prev, curr = None, start +# while curr != end: +# nbrs = adj[curr] +# # pick the neighbor that isn’t the previous node +# nxt = nbrs[0] if nbrs[0] != prev else nbrs[1] +# ordered.append(nxt) +# prev, curr = curr, nxt +# +# # compute total wall length +# length = 0.0 +# for u, v in zip(ordered, ordered[1:]): +# x1, y1 = coords[u] +# x2, y2 = coords[v] +# length += math.hypot(x2 - x1, y2 - y1) +# +# # emit the element +# w = etree.SubElement(walls_parent, "wall", +# length=f"{length:.6g}", +# c1=str(c1), c2=str(c2), +# n1=str(ordered[0]), n2=str(ordered[-1]), +# wall_type="normal", +# viz_flux="0" +# ) +# # ─── Add the transporter tags ─────────────────────────────────── +# etree.SubElement(w, "transporters1") +# etree.SubElement(w, "transporters2") +# +# new_walls.append(w) +# +# # 4) assign sequential indices and refresh the count +# for idx, w in enumerate(new_walls): +# w.set("index", str(idx)) +# walls_parent.set("n", str(len(new_walls))) +# +# +# # ────────────────────────────────────────────────────────────────────────── +# # FINAL SORT: reorder tags by c1, then reindex & recount +# # ────────────────────────────────────────────────────────────────────────── +# walls_parent = doc.root.find("walls") +# +# # 1) snapshot and sort by integer c1 +# orig_walls = list(walls_parent.findall("wall")) +# sorted_walls = sorted(orig_walls, key=lambda w: int(w.get("c1", 0))) +# +# # 2) remove all originals +# for w in orig_walls: +# walls_parent.remove(w) +# +# # 3) append back in sorted order +# for w in sorted_walls: +# walls_parent.append(w) +# +# # 4) reassign sequential index and refresh count +# for idx, w in enumerate(walls_parent.findall("wall")): +# w.set("index", str(idx)) +# walls_parent.set("n", str(len(walls_parent.findall("wall")))) +# +# +# +# +# # ──────────────────────────────────────────────────────────────────────────── +# # REINDEX NODES BY FIRST APPEARANCE IN CELLS → new 0..M-1 ordering +# # ──────────────────────────────────────────────────────────────────────────── +# from lxml import etree +# +# # 1) build mapping old_nr → new_nr by scanning cells +# mapping: dict[int,int] = {} +# next_id = 0 +# for cell in doc.cells.cells: +# for old_nr in cell.vertices: +# if old_nr not in mapping: +# mapping[old_nr] = next_id +# next_id += 1 +# +# # print(f"mapping: {mapping}") +# # 2) any nodes not in any cell (e.g. orphan or boundary_poly) come last +# for n in doc.nodes.nodes: +# old_nr = n.nr +# if old_nr not in mapping: +# mapping[old_nr] = next_id +# next_id += 1 +# +# # 3) reorder & rename elements under +# nodes_parent = doc.root.find("nodes") +# orig_nodes = {int(elem.get("nr")): elem for elem in nodes_parent.findall("node")} +# +# # clear existing +# for elem in list(nodes_parent.getchildren()): +# nodes_parent.remove(elem) +# +# # append back in new order +# for old_nr, new_nr in sorted(mapping.items(), key=lambda kv: kv[1]): +# elem = orig_nodes[old_nr] +# elem.set("nr", str(new_nr)) +# elem.tail = "\n " +# nodes_parent.append(elem) +# +# # 4) rebuild coords and doc.nodes.nodes list +# new_coords = {} +# new_node_list = [] +# for elem in nodes_parent.findall("node"): +# nr = int(elem.get("nr")) +# x, y = float(elem.get("x")), float(elem.get("y")) +# sam = elem.get("sam") == "true" +# boundary = elem.get("boundary") == "true" +# fixed = elem.get("fixed") == "true" +# new_coords[nr] = (x, y) +# new_node_list.append(Node(nr, x, y, sam, boundary, fixed, elem)) +# coords.clear(); coords.update(new_coords) +# doc.nodes.nodes[:] = new_node_list +# +# # 5) remap every cell’s membership list (Python + XML) +# for cell in doc.cells.cells: +# old_verts = cell.vertices +# new_verts = [mapping[old] for old in old_verts] +# cell.vertices = new_verts +# # update XML +# for n_elem in cell.elem.findall("node"): +# old = int(n_elem.get("n")) +# n_elem.set("n", str(mapping[old])) +# +# # 6) remap every wall’s endpoints n1/n2 +# walls_parent = doc.root.find("walls") +# for w in walls_parent.findall("wall"): +# for attr in ("n1", "n2"): +# old = int(w.get(attr)) +# w.set(attr, str(mapping[old])) +# +# +# +# # ──────────────────────────────────────────────────────────────────────────── +# # RESET CHILDREN TO THE REFINED BOUNDARY LOOP +# # ──────────────────────────────────────────────────────────────────────────── +# +# # 1) find the boundary_polygon element +# poly = doc.cells.elem.find("boundary_polygon") +# if poly is None: +# raise RuntimeError("No found under .") +# +# # 2) collect all nodes flagged boundary="true" +# b_nodes = [n for n in doc.nodes.nodes if n.boundary] +# +# # 3) sort them CCW around tissue centre (tx,ty from before) +# def angle_about_center(node): +# x, y = node.x, node.y +# return math.atan2(y - ty, x - tx) +# +# b_nodes.sort(key=angle_about_center) +# +# # 4) wipe existing children and append fresh entries +# for ch in list(poly.getchildren()): +# poly.remove(ch) +# +# tail = "\n " # matches the indent in your file +# for n in b_nodes: +# elem = etree.SubElement(poly, "node", n=str(n.nr)) +# elem.tail = tail +# +# # reposition the boundary polygon +# cells_elem = doc.root.find("cells") +# poly = cells_elem.find("boundary_polygon") +# if poly is not None: +# cells_elem.remove(poly) +# cells_elem.append(poly) +# +# +# # ▶︎ 1) map each cell to its incident walls +# cell2walls: dict[int, list[int]] = defaultdict(list) +# walls_parent = doc.root.find("walls") +# +# for w in walls_parent.findall("wall"): +# idx = int(w.get("index")) +# c1 = int(w.get("c1")) +# c2 = int(w.get("c2")) +# cell2walls[c1].append(idx) +# cell2walls[c2].append(idx) +# +# # ▶︎ 2) rewrite each cell’s children +# for cell in doc.cells.cells: +# ci = int(cell.elem.get("index")) +# # remove all existing tags +# for w_elem in cell.elem.findall("wall"): +# cell.elem.remove(w_elem) +# +# # append new ones in sorted order +# for widx in sorted(cell2walls.get(ci, [])): +# we = etree.SubElement(cell.elem, "wall", w=str(widx)) +# we.tail = "\n " # match your cell indentation # -# ──────────────────────────────────────────────────────────────────────────── -# RESET CHILDREN TO THE REFINED BOUNDARY LOOP -# ──────────────────────────────────────────────────────────────────────────── - -# 1) find the boundary_polygon element -poly = doc.cells.elem.find("boundary_polygon") -if poly is None: - raise RuntimeError("No found under .") - -# 2) collect all nodes flagged boundary="true" -b_nodes = [n for n in doc.nodes.nodes if n.boundary] - -# 3) sort them CCW around tissue centre (tx,ty from before) -def angle_about_center(node): - x, y = node.x, node.y - return math.atan2(y - ty, x - tx) - -b_nodes.sort(key=angle_about_center) - -# 4) wipe existing children and append fresh entries -for ch in list(poly.getchildren()): - poly.remove(ch) - -tail = "\n " # matches the indent in your file -for n in b_nodes: - elem = etree.SubElement(poly, "node", n=str(n.nr)) - elem.tail = tail - -# reposition the boundary polygon -cells_elem = doc.root.find("cells") -poly = cells_elem.find("boundary_polygon") -if poly is not None: - cells_elem.remove(poly) - cells_elem.append(poly) - - -# ──────────────────────────────────────────────────────────────────────────── -# REBUILD WALLS AS CONTIGUOUS SEGMENTS BETWEEN CELL PAIRS -# ──────────────────────────────────────────────────────────────────────────── - - -# 1) locate and clear the existing walls -walls_parent = doc.root.find("walls") -for w in list(walls_parent.getchildren()): - walls_parent.remove(w) - -# 2) collect every undirected edge → the two cells sharing it -edge2cells: dict[tuple[int,int], list[int]] = {} -for c in doc.cells.cells: - ci = int(c.elem.get("index")) - verts = c.vertices - for a, b in zip(verts, verts[1:] + verts[:1]): - key = tuple(sorted((a, b))) - edge2cells.setdefault(key, []).append(ci) - -# 3) group edges by the pair of cells (interior walls only) -pair2edges: dict[tuple[int,int], list[tuple[int,int]]] = {} -for edge, cells in edge2cells.items(): - if len(cells) == 2: - pair2edges.setdefault(tuple(sorted(cells)), []).append(edge) - -new_walls = [] - -for (c1, c2), edges in pair2edges.items(): - # build adjacency for this wall - adj: dict[int, list[int]] = defaultdict(list) - for u, v in edges: - adj[u].append(v) - adj[v].append(u) - - # find endpoints (degree == 1) - endpoints = [n for n, nbrs in adj.items() if len(nbrs) == 1] - if len(endpoints) == 2: - start, end = endpoints - else: - # fallback: pick the first edge’s nodes - start, end = edges[0] - - # traverse from start to end - ordered = [start] - prev, curr = None, start - while curr != end: - nbrs = adj[curr] - # pick the neighbor that isn’t the previous node - nxt = nbrs[0] if nbrs[0] != prev else nbrs[1] - ordered.append(nxt) - prev, curr = curr, nxt - - # compute total wall length - length = 0.0 - for u, v in zip(ordered, ordered[1:]): - x1, y1 = coords[u] - x2, y2 = coords[v] - length += math.hypot(x2 - x1, y2 - y1) - - # emit the element - w = etree.SubElement(walls_parent, "wall", - length=f"{length:.6g}", - c1=str(c1), c2=str(c2), - n1=str(ordered[0]), n2=str(ordered[-1]), - wall_type="normal", - viz_flux="0" - ) - # ─── Add the transporter tags ─────────────────────────────────── - etree.SubElement(w, "transporters1") - etree.SubElement(w, "transporters2") - - new_walls.append(w) - -# 4) assign sequential indices and refresh the count -for idx, w in enumerate(new_walls): - w.set("index", str(idx)) -walls_parent.set("n", str(len(new_walls))) - - -# ────────────────────────────────────────────────────────────────────────── -# FINAL SORT: reorder tags by c1, then reindex & recount -# ────────────────────────────────────────────────────────────────────────── -walls_parent = doc.root.find("walls") - -# 1) snapshot and sort by integer c1 -orig_walls = list(walls_parent.findall("wall")) -sorted_walls = sorted(orig_walls, key=lambda w: int(w.get("c1", 0))) - -# 2) remove all originals -for w in orig_walls: - walls_parent.remove(w) - -# 3) append back in sorted order -for w in sorted_walls: - walls_parent.append(w) - -# 4) reassign sequential index and refresh count -for idx, w in enumerate(walls_parent.findall("wall")): - w.set("index", str(idx)) -walls_parent.set("n", str(len(walls_parent.findall("wall")))) - - - - -# ──────────────────────────────────────────────────────────────────────────── -# REINDEX NODES BY FIRST APPEARANCE IN CELLS → new 0..M-1 ordering -# ──────────────────────────────────────────────────────────────────────────── -from lxml import etree - -# 1) build mapping old_nr → new_nr by scanning cells -mapping: dict[int,int] = {} -next_id = 0 -for cell in doc.cells.cells: - for old_nr in cell.vertices: - if old_nr not in mapping: - mapping[old_nr] = next_id - next_id += 1 - -# print(f"mapping: {mapping}") -# 2) any nodes not in any cell (e.g. orphan or boundary_poly) come last -for n in doc.nodes.nodes: - old_nr = n.nr - if old_nr not in mapping: - mapping[old_nr] = next_id - next_id += 1 - -# 3) reorder & rename elements under -nodes_parent = doc.root.find("nodes") -orig_nodes = {int(elem.get("nr")): elem for elem in nodes_parent.findall("node")} - -# clear existing -for elem in list(nodes_parent.getchildren()): - nodes_parent.remove(elem) - -# append back in new order -for old_nr, new_nr in sorted(mapping.items(), key=lambda kv: kv[1]): - elem = orig_nodes[old_nr] - elem.set("nr", str(new_nr)) - elem.tail = "\n " - nodes_parent.append(elem) - -# 4) rebuild coords and doc.nodes.nodes list -new_coords = {} -new_node_list = [] -for elem in nodes_parent.findall("node"): - nr = int(elem.get("nr")) - x, y = float(elem.get("x")), float(elem.get("y")) - sam = elem.get("sam") == "true" - boundary = elem.get("boundary") == "true" - fixed = elem.get("fixed") == "true" - new_coords[nr] = (x, y) - new_node_list.append(Node(nr, x, y, sam, boundary, fixed, elem)) -coords.clear(); coords.update(new_coords) -doc.nodes.nodes[:] = new_node_list - -# 5) remap every cell’s membership list (Python + XML) -for cell in doc.cells.cells: - old_verts = cell.vertices - new_verts = [mapping[old] for old in old_verts] - cell.vertices = new_verts - # update XML - for n_elem in cell.elem.findall("node"): - old = int(n_elem.get("n")) - n_elem.set("n", str(mapping[old])) - -# 6) remap every wall’s endpoints n1/n2 -walls_parent = doc.root.find("walls") -for w in walls_parent.findall("wall"): - for attr in ("n1", "n2"): - old = int(w.get(attr)) - w.set(attr, str(mapping[old])) - - - -# ──────────────────────────────────────────────────────────────────────────── -# RESET CHILDREN TO THE REFINED BOUNDARY LOOP -# ──────────────────────────────────────────────────────────────────────────── - -# 1) find the boundary_polygon element -poly = doc.cells.elem.find("boundary_polygon") -if poly is None: - raise RuntimeError("No found under .") - -# 2) collect all nodes flagged boundary="true" -b_nodes = [n for n in doc.nodes.nodes if n.boundary] - -# 3) sort them CCW around tissue centre (tx,ty from before) -def angle_about_center(node): - x, y = node.x, node.y - return math.atan2(y - ty, x - tx) - -b_nodes.sort(key=angle_about_center) - -# 4) wipe existing children and append fresh entries -for ch in list(poly.getchildren()): - poly.remove(ch) - -tail = "\n " # matches the indent in your file -for n in b_nodes: - elem = etree.SubElement(poly, "node", n=str(n.nr)) - elem.tail = tail - -# reposition the boundary polygon -cells_elem = doc.root.find("cells") -poly = cells_elem.find("boundary_polygon") -if poly is not None: - cells_elem.remove(poly) - cells_elem.append(poly) - - -# ▶︎ 1) map each cell to its incident walls -cell2walls: dict[int, list[int]] = defaultdict(list) -walls_parent = doc.root.find("walls") - -for w in walls_parent.findall("wall"): - idx = int(w.get("index")) - c1 = int(w.get("c1")) - c2 = int(w.get("c2")) - cell2walls[c1].append(idx) - cell2walls[c2].append(idx) - -# ▶︎ 2) rewrite each cell’s children -for cell in doc.cells.cells: - ci = int(cell.elem.get("index")) - # remove all existing tags - for w_elem in cell.elem.findall("wall"): - cell.elem.remove(w_elem) - - # append new ones in sorted order - for widx in sorted(cell2walls.get(ci, [])): - we = etree.SubElement(cell.elem, "wall", w=str(widx)) - we.tail = "\n " # match your cell indentation - -# ── housekeeping and save ──────────────────────────────────────────────── -objectify.deannotate(doc.root, cleanup_namespaces=True) -etree.indent(doc.tree, space=" ") -doc.save(output_xml) +# # ── housekeeping and save ──────────────────────────────────────────────── +# objectify.deannotate(doc.root, cleanup_namespaces=True) +# etree.indent(doc.tree, space=" ") +# doc.save(output_xml) diff --git a/src/GUI/GUI.pro b/src/GUI/GUI.pro index 9063c85..6625e60 100644 --- a/src/GUI/GUI.pro +++ b/src/GUI/GUI.pro @@ -21,6 +21,8 @@ CONFIG += release CONFIG += debug +QMAKE_CXXFLAGS_DEBUG += -g -O0 +QMAKE_LFLAGS += -rdynamic CONFIG += qt #CONFIG -= app_bundle CONFIG+=sdk_no_version_check diff --git a/src/GUI/VirtualLeaf.cpp b/src/GUI/VirtualLeaf.cpp index 4ba2b3e..0a71cf8 100755 --- a/src/GUI/VirtualLeaf.cpp +++ b/src/GUI/VirtualLeaf.cpp @@ -185,7 +185,7 @@ void MainBase::Plot(int resize_stride) PNGname.width(6); PNGname << count << ".png"; // Write high-res PNG snapshot every plot step - Save(PNGname.str().c_str(), "PNG", 1024, 768); + Save(PNGname.str().c_str(), "PNG", 3072, 3072); //768 //} } diff --git a/src/GUI/cell.cpp b/src/GUI/cell.cpp index a8efe35..3de05e5 100755 --- a/src/GUI/cell.cpp +++ b/src/GUI/cell.cpp @@ -20,7 +20,6 @@ */ #include - #include #include "pi.h" #include "cell.h" @@ -32,6 +31,17 @@ #include "nodeitem.h" #include "qcanvasarrow.h" #include "parameter.h" +//#define QDEBUG + +// Division type enumeration +// enum DivisionType { +// NO_DIVISION = 0, +// RANDOM_DIVISION = 1, +// MAX_STRESS_AXIS = 2, +// SHORT_AXIS = 3, +// LONG_AXIS = 4, +// PERP_STRESS = 5 +// }; static const std::string _module_id("$Id$"); @@ -59,7 +69,7 @@ Cell::Cell(const Cell &src) : CellBase(src) bool Cell::Cmp(Cell *c) const { return this->Index() < c->Index(); } bool Cell::Eq(Cell *c) const { return this->Index() == c->Index(); } -Cell Cell::operator=(const Cell &src) +Cell Cell::operator=(const Cell &src) { CellBase::operator=(src); m=src.m; @@ -67,7 +77,7 @@ Cell Cell::operator=(const Cell &src) } //Cell(void) : CellBase() {} -void Cell::DivideOverAxis(Vector axis) +void Cell::DivideOverAxis(Vector axis) { // Build a wall // -> find the position of the wall @@ -75,28 +85,33 @@ void Cell::DivideOverAxis(Vector axis) // better look for intersection with a simple line intersection algorithm as below? // this leads to some exceptions: e.g. dividing a horizontal rectangle. // leaving it like this for the time being - +#ifdef QDEBUG + qDebug() << "Dividing cell " << Index() << Qt::endl; + qDebug() << "Number of walls: " << walls.size() << Qt::endl; +#endif if (dead) return; - Vector centroid=Centroid(); - double prev_cross_z=(axis * (centroid - *(nodes.back()) ) ).z ; + Vector centroid = Centroid(); + double prev_cross_z = (axis * (centroid - *(nodes.back()))).z; ItList new_node_locations; for (list::iterator i=nodes.begin(); i!=nodes.end(); i++) { - // cross product to detect position of division Vector cross = axis * (centroid - *(*i)); - if (cross.z * prev_cross_z < 0 ) { + if (cross.z * prev_cross_z < 0) { new_node_locations.push_back(i); - - } - prev_cross_z=cross.z; + } + prev_cross_z = cross.z; } DivideWalls(new_node_locations, centroid, centroid+axis); + #ifdef QDEBUG + qDebug() << "Dividing cell Finish" << Index() << Qt::endl; + qDebug() << "Number of walls: " << walls.size() << Qt::endl; +#endif } double Cell::MeanArea(void) @@ -109,13 +124,13 @@ void Cell::Apoptose(void) { // First kill walls #ifdef QDEBUG - qDebug() << "This is cell " << Index() << endl; - qDebug() << "Number of walls: " << walls.size() << endl; + qDebug() << "This is cell " << Index() << Qt::endl; + qDebug() << "Number of walls: " << walls.size() << Qt::endl; #endif for (list::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; + << (*w)->c1->Index() << ", c2 = " << (*w)->c2->Index() << Qt::endl; #endif } for (list::iterator w=walls.begin(); w!=walls.end(); w++) { @@ -128,7 +143,7 @@ void Cell::Apoptose(void) if ((*w)->c1 == this) { // invert wall? - (*w)->c1 = (*w)->c2; + (*w)->c1 = (*w)->c2; (*w)->c2 = m->boundary_polygon; Node *n1 = (*w)->n1; @@ -141,7 +156,7 @@ void Cell::Apoptose(void) #ifdef QDEBUG if (illegal_flag && (*w)->c1==(*w)->c2) { - qDebug() << "I created an illegal wall." << endl; + qDebug() << "I created an illegal wall." << Qt::endl; } #endif @@ -149,22 +164,22 @@ void Cell::Apoptose(void) ((*w)->C1() == (*w)->C2() ) ){ // kill wall #ifdef QDEBUG - qDebug() << "Killing wall." << endl; + qDebug() << "Killing wall." << Qt::endl; #endif (*w)->Kill(); #ifdef QDEBUG if ((*w)) { - qDebug() << "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() << Qt::endl; } #endif (*w)=0; } else { #ifdef QDEBUG - qDebug() << "Not killing wall." << endl; - qDebug() << "Wall " << (*w)->Index() << " says: c1 = " - << (*w)->c1->Index() << ", c2 = " << (*w)->c2->Index() << endl; + qDebug() << "Not killing wall." << Qt::endl; + qDebug() << "Wall " << (*w)->Index() << " says: c1 = " + << (*w)->c1->Index() << ", c2 = " << (*w)->c2->Index() << Qt::endl; #endif } } @@ -200,7 +215,7 @@ void Cell::Apoptose(void) no.MarkDead(); } else { // register node with outside world - if (find_if( no.owners.begin(), no.owners.end(), + if (find_if( no.owners.begin(), no.owners.end(), [this](auto neighbor){return neighbor.CellEquals(m->boundary_polygon->Index());} ) == no.owners.end() ) { tmp.cell = m->boundary_polygon; no.owners.push_back(tmp); @@ -216,12 +231,12 @@ void Cell::ConstructConnections(void) { // Tie up the nodes of this cell, assuming they are correctly ordered - //cerr << "Constructing connections of cell " << index << endl; + //cerr << "Constructing connections of cell " << index << Qt::endl; for (list::iterator i=nodes.begin(); i!=nodes.end(); i++) { - //cerr << "Connecting node " << *i << endl; - //cerr << "Node " << *i << endl << " = " << *(*i) << endl; + //cerr << "Connecting node " << *i << Qt::endl; + //cerr << "Node " << *i << Qt::endl << " = " << *(*i) << Qt::endl; // 1. Tidy up existing connections (which are part of this cell) if ((*i)->owners.size()>0) { list::iterator neighb_with_this_cell= @@ -229,7 +244,7 @@ void Cell::ConstructConnections(void) find_if((*i)->owners.begin(), (*i)->owners.end(), [this](auto neighbor){return neighbor.CellEquals(this->Index());}); - if (neighb_with_this_cell!=(*i)->owners.end()) + if (neighb_with_this_cell!=(*i)->owners.end()) (*i)->owners.erase(neighb_with_this_cell); } @@ -262,7 +277,7 @@ bool Cell::DivideOverGivenLine(const Vector v1, const Vector v2, bool fix_cellwa ItList new_node_locations; #ifdef QDEBUG - qDebug() << "Cell " << Index() << " is doing DivideOverGivenLine" << endl; + qDebug() << "Cell " << Index() << " is doing DivideOverGivenLine" << Qt::endl; #endif for (list::iterator i=nodes.begin(); i!=nodes.end(); i++) { @@ -274,12 +289,12 @@ bool Cell::DivideOverGivenLine(const Vector v1, const Vector v2, bool fix_cellwa } Vector v4 = *(*nb); - double denominator = + double denominator = (v4.y - v3.y)*(v2.x - v1.x) - (v4.x - v3.x)*(v2.y - v1.y); - double ua = + double ua = ((v4.x - v3.x)*(v1.y - v3.y) - (v4.y - v3.y)*(v1.x -v3.x))/denominator; - double ub = + double ub = ((v2.x - v1.x)*(v1.y-v3.y) - (v2.y- v1.y)*(v1.x - v3.x))/denominator; @@ -289,30 +304,30 @@ bool Cell::DivideOverGivenLine(const Vector v1, const Vector v2, bool fix_cellwa // 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) { - qDebug() << "Line does not intersect with two edges of Cell " << Index() << endl; - qDebug() << "new_node_locations.size() = " << new_node_locations.size() << endl; + if (new_node_locations.size()<2) { + qDebug() << "Line does not intersect with two edges of Cell " << Index() << Qt::endl; + qDebug() << "new_node_locations.size() = " << new_node_locations.size() << Qt::endl; return false; } ItList::iterator i = new_node_locations.begin(); list< Node *>::iterator j; - qDebug() << "-------------------------------" << endl; + qDebug() << "-------------------------------" << Qt::endl; qDebug() << "Location of new nodes: " << (**i)->Index() << " and "; ++i; - j = *i; + j = *i; if (j==nodes.begin()) j=nodes.end(); j--; - qDebug() << (*j)->Index() << endl; - qDebug() << "-------------------------------" << endl; + qDebug() << (*j)->Index() << Qt::endl; + qDebug() << "-------------------------------" << Qt::endl; if ( **new_node_locations.begin() == *j ) { - qDebug() << "Rejecting proposed division (cutting off zero area)." << endl; + qDebug() << "Rejecting proposed division (cutting off zero area)." << Qt::endl; return false; } #endif @@ -467,10 +482,9 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto ParentInfo parent_info; parent_info.polarization = ReduceCellAndWalls( PINdir ); parent_info.polarization.Normalise(); - parent_info.PINmembrane = SumTransporters(1); +// parent_info.PINmembrane = SumTransporters(1); parent_info.PINendosome = Chemical(1); - - //cerr << "Parent polarization before division: " << parent_info.polarization << endl; +// cerr << "Parent polarization before division: " << parent_info.polarization << Qt::endl; // Step 1: create a daughter cell Cell *daughter=m->AddCell(new Cell()); @@ -502,7 +516,7 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto // 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; + cerr << "Warning in Cell::Division: division of non-convex cells not fully implemented" << Qt::endl; // Reject the daughter cell and decrement the amount of cells // again. We can do this here because it is the last cell added. @@ -512,9 +526,9 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto // get totally messed up...! (e.g. the indices used in Nodes::cells) #ifdef QDEBUG - qDebug() << "new_node_locations.size() = " << new_node_locations.size() <index = " << daughter->index << endl; - qDebug() << "cells.size() = " << m->cells.size() << endl; + qDebug() << "new_node_locations.size() = " << new_node_locations.size() <index = " << daughter->index << Qt::endl; + qDebug() << "cells.size() = " << m->cells.size() << Qt::endl; #endif m->cells.pop_back(); @@ -553,14 +567,14 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto list::iterator nb=*i; if (nb == nodes.begin()) { nb = nodes.end(); - } + } nb--; - Vector v4=*( *nb ); + Vector v4=*( *nb ); - double denominator = + double denominator = (v4.y - v3.y)*(v2.x - v1.x) - (v4.x - v3.x)*(v2.y - v1.y); - double ua = + double ua = ((v4.x - v3.x)*(v1.y - v3.y) - (v4.y - v3.y)*(v1.x -v3.x))/denominator; double intersec_x = v1.x + ua*(v2.x-v1.x); @@ -589,8 +603,8 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto new_node_flag[nnc]=1; new_node[nnc] = *(**i); new_node_ind[nnc] = **i; - //cerr << **i << endl ; - } else + //cerr << **i << Qt::endl ; + } else if ( (*(*nb) - *n).Norm() < collapse_node_threshold * elem_length ) { new_node_flag[nnc]=2; new_node[nnc] = *(*nb); @@ -609,7 +623,7 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto Cell *neighbor_cell=0; // we need this to split up the "Wall" objects. - // for both divided edges: + // for both divided edges: // insert its new node into all cells that own the divided edge // but only if it really is a new node: if (new_node_flag[i]!=0) { @@ -622,14 +636,14 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto boundary = SAM; daughter->boundary = SAM; boundary_touched_flag = true; - */ + */ } } else { // (Construct a list of all owners:) // really construct the new node (if this is a new node) - new_node_ind[i] = + new_node_ind[i] = m->AddNode(new Node (new_node[i]) ); @@ -667,10 +681,10 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto ((m->findNextBoundaryNode(div_edges[i].first))->Index() == div_edges[i].second->Index())){ // The boundary proceeds from first to second. #ifdef QDEBUG - qDebug() << "Index of the first node: " << div_edges[i].first->Index() << endl; - qDebug() << "Index of the second node: " << div_edges[i].second->Index() << endl; - qDebug() << "Boundary proceeds from: " << div_edges[i].first->Index() - << "to: " << (m->findNextBoundaryNode(div_edges[i].first))->Index() << endl << endl; + qDebug() << "Index of the first node: " << div_edges[i].first->Index() << Qt::endl; + qDebug() << "Index of the second node: " << div_edges[i].second->Index() << Qt::endl; + qDebug() << "Boundary proceeds from: " << div_edges[i].first->Index() + << "to: " << (m->findNextBoundaryNode(div_edges[i].first))->Index() << Qt::endl << Qt::endl; #endif new_node_ind[i]->SetBoundary(); @@ -695,7 +709,7 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto } else { // insert before second node, so leave ins_pos as it is, // that is: incremented - m->boundary_polygon->nodes.insert(ins_pos, new_node_ind[i]); + m->boundary_polygon->nodes.insert(ins_pos, new_node_ind[i]); // .. set the neighbors of the new node ... } } @@ -713,24 +727,24 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto back_inserter(owners)); - // find first non-self duplicate in the owners: + // find first non-self duplicate in the owners: // cells owning the same two nodes // share an edge with me owners.sort( [](auto neighbor_a, auto neighbor_b){return neighbor_a.Cmp(neighbor_b);} ); -#ifdef QDEBUG +#ifdef QDEBUG list unique_owners; copy(owners.begin(), owners.end(), back_inserter(unique_owners)); unique_owners.unique( mem_fn( &Neighbor::Eq ) ); - qDebug() << "The dividing edge nodes: " << div_edges[i].first->Index() + qDebug() << "The dividing edge nodes: " << div_edges[i].first->Index() << " and " << div_edges[i].second->Index() << " are owned by cells: "; // spit out each owners' cell index foreach(Neighbor neighbor, unique_owners){ qDebug() << neighbor.cell->Index() << " "; } - qDebug() << endl; + qDebug() << Qt::endl; #endif // Search through the sorted list of edge node owners looking for duplicate pairs. Each pair represents an actual edge owner. @@ -740,15 +754,15 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto it = adjacent_find(it, owners.end(), neighbor_cell_eq); if (it == owners.end()) break; // bail if reach the end of the list #ifdef QDEBUG - qDebug() << "Considering: " << it->cell->Index() << " as a possible edge owner." << endl; + qDebug() << "Considering: " << it->cell->Index() << " as a possible edge owner." << Qt::endl; #endif if (it->cell->Index() != this->Index()) { #ifdef QDEBUG - qDebug() << "Adding: " << it->cell->Index() << " to the list of edge owners." << endl; + qDebug() << "Adding: " << it->cell->Index() << " to the list of edge owners." << Qt::endl; #endif edge_owners.push_back(*it); } - } + } if (edge_owners.size() > 1){ // Remove the boundary polygon - if its there @@ -756,21 +770,21 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto if ((it = find_if (edge_owners.begin(), edge_owners.end(), [](auto neighbor){return neighbor.CellEquals(-1);})) != edge_owners.end()) { #ifdef QDEBUG - qDebug() << "deleting: " << it->cell->Index() << " from the list of edge owners." << endl; + qDebug() << "deleting: " << it->cell->Index() << " from the list of edge owners." << Qt::endl; #endif edge_owners.erase(it); } } #ifdef QDEBUG - qDebug() << "The edge owners list has: " << edge_owners.size() << " elements" << endl; + qDebug() << "The edge owners list has: " << edge_owners.size() << " elements" << Qt::endl; #endif // Since the list should always contain exactly one element, pass it on as an iterator list::iterator c = (edge_owners.size() != 0) ? edge_owners.begin() : edge_owners.end(); // (can we have more than one neighboring cell here??) - if (c!=owners.end()) { + if (c!=owners.end()) { neighbor_cell = c->cell; if (c->cell == NULL) { cout << "error"; @@ -811,7 +825,7 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto back_inserter(owners)); - // find first non-self duplicate in the owners: + // find first non-self duplicate in the owners: // cells owning the same two nodes // share an edge with me owners.sort( mem_fn ( &Neighbor::Cmp ) ); @@ -824,14 +838,14 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto if (c!=owners.end()) neighbor_cell = c->cell; - else + else neighbor_cell = 0; } if (neighbor_cell /* && !neighbor_cell->BoundaryPolP() */) { - //cerr << "Cell " << index << " says: neighboring cell is " << neighbor_cell->index << endl; +// cerr << "Cell " << index << " says: neighboring cell is " << neighbor_cell->index << Qt::endl; /*************** 1. Find the correct wall element ********************/ @@ -846,9 +860,9 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto if (w == walls.end()) { #ifdef QDEBUG - qDebug() << "Whoops, wall element not found...!" << endl; - qDebug() << "Cell ID: " << neighbor_cell->Index() << endl; - qDebug() << "My cell ID: " << Index() << endl; + qDebug() << "Whoops, wall element not found...!" << Qt::endl; + qDebug() << "Cell ID: " << neighbor_cell->Index() << Qt::endl; + qDebug() << "My cell ID: " << Index() << Qt::endl; #endif } else { @@ -863,14 +877,14 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto // over the two daughter walls (*w)->SetLength(); // make sure we've got the current length orig_length[i] = (*w)->Length(); - //cerr << "Original length is " << orig_length[i] << endl; + //cerr << "Original length is " << orig_length[i] << Qt::endl; if ((*w)->c1 == this ) { - // cerr << "Cell " << (*w)->c1->Index() << " splits up wall " << *(*w) << ", into: " << endl; + // cerr << "Cell " << (*w)->c1->Index() << " splits up wall " << *(*w) << ", into: " << Qt::endl; new_wall = new Wall( (*w)->n1, new_node_ind[i], this, neighbor_cell); (*w)->n1 = new_node_ind[i]; - // cerr << "wall " << *(*w) << ", and new wall " << *new_wall << endl; + // cerr << "wall " << *(*w) << ", and new wall " << *new_wall << Qt::endl; } else { new_wall = new Wall( (*w)->n1, new_node_ind[i], neighbor_cell, this); @@ -892,10 +906,10 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto } } AddWall(new_wall); - // cerr << "Building new wall: this=" << Index() << ", neighbor_cell = " << neighbor_cell->Index() << endl; + // cerr << "Building new wall: this=" << Index() << ", neighbor_cell = " << neighbor_cell->Index() << Qt::endl; neighbor_cell->AddWall( new_wall); - //cerr << "Existing wall: c1 = " << (*w)->c1->Index() << ", neighbor_cell = " << (*w)->c2->Index() << endl; + //cerr << "Existing wall: c1 = " << (*w)->c1->Index() << ", neighbor_cell = " << (*w)->c2->Index() << Qt::endl; // Remember the addresses of the new walls div_wall[2*i+0] = *w; @@ -920,12 +934,12 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto start=new_node_locations.front(); - //cerr << "*new_node_locations.front() = " << *new_node_locations.front() << endl; + //cerr << "*new_node_locations.front() = " << *new_node_locations.front() << Qt::endl; if (new_node_flag[0]==1) { start++; if (start==nodes.end()) start=nodes.begin(); - } + } stop=new_node_locations.back(); if (new_node_flag[1]==2) { @@ -944,9 +958,8 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto (*i)->owners.end(), [this](auto neighbor){return neighbor.CellEquals(this->Index());}); if (neighb_with_this_cell==(*i)->owners.end()) { - #ifdef QDEBUG - qDebug() << "not found" << endl; + qDebug() << "not found" << Qt::endl; #endif abort(); } @@ -986,7 +999,7 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto new_nodes_parent.push_back( *i ); i++; - if (i==nodes.end()) + if (i==nodes.end()) i = nodes.begin(); }; } @@ -1057,8 +1070,8 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto // move the new nodes to the parent nodes.clear(); - copy( new_nodes_parent.begin(), - new_nodes_parent.end(), + copy( new_nodes_parent.begin(), + new_nodes_parent.end(), back_inserter(nodes) ); @@ -1068,7 +1081,7 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto if (boundary_touched_flag) { m->boundary_polygon->ConstructConnections(); - } + } // collecting neighbors of divided cell list broken_neighbors; @@ -1096,18 +1109,18 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto daughter->AddWall( wall ); - //cerr << "Correct walls of cell " << Index() << " and daughter " << daughter->Index() << endl; + //cerr << "Correct walls of cell " << Index() << " and daughter " << daughter->Index() << Qt::endl; // Move Walls to daughter cell list copy_walls = walls; for (list::iterator w = copy_walls.begin(); w!=copy_walls.end(); w++) { - //cerr << "Doing wall, before: " << **w << endl; + //cerr << "Doing wall, before: " << **w << Qt::endl; // checks the nodes of the wall and gives it away if appropriate (*w)->CorrectWall ( ); - //cerr << "and after: " << **w << endl; + //cerr << "and after: " << **w << Qt::endl; } @@ -1119,7 +1132,7 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto } } - //cerr << "Cell " << index << " has been dividing, and gave birth to Cell " << daughter->index << endl; + //cerr << "Cell " << index << " has been dividing, and gave birth to Cell " << daughter->index << Qt::endl; // now reconstruct neighbor list for all "broken" neighbors @@ -1169,7 +1182,7 @@ void Cell::DivideWalls(ItList new_node_locations, const Vector from, const Vecto daughter->div_counter=(++div_counter); } - +// void Cell::findBeforeAfter(Node * node, Node ** before, Node**after) { for (list::iterator i=this->nodes.begin(); i!=this->nodes.end(); i++) { list::const_iterator next=i; @@ -1316,7 +1329,7 @@ double Cell::Displace(double dx, double dy, double dh) // Displace whole cell, add resulting energy to dh, // and accept displacement if energetically favorable - // + // // Method is called if a "fixed" node is displaced // Warning: length constraint not yet CORRECTLY implemented for this function @@ -1343,7 +1356,7 @@ double Cell::Displace(double dx, double dy, double dh) if (n->getCell()!=this) { length_edges.push_back( pair (*i, n->nb1) ); length_edges.push_back( pair (*i, n->nb2) ); - old_length += + old_length += DSQR(Node::target_length-(*(*i)-*(n->nb1)).Norm())+ DSQR(Node::target_length-(*(*i)-*(n->nb2)).Norm()); } @@ -1383,10 +1396,10 @@ double Cell::Displace(double dx, double dy, double dh) list::const_iterator nb_it = neighbors.begin(); for (vector::const_iterator ar_it = cellareas.begin(); ar_it!=cellareas.end(); ( ar_it++, nb_it++) ) { ((Cell *)(*nb_it))->area = *ar_it; - (*nb_it)->SetIntegrals(); + (*nb_it)->SetIntegrals(); } - //cerr << endl; + //cerr << Qt::endl; } else { @@ -1412,7 +1425,7 @@ double Cell::Energy(void) const for (list::const_iterator i=nodes.begin(); i!=nodes.end(); i++) { for (list::const_iterator n=(*i)->owners.begin(); n!=(*i)->owners.end(); n++) { if (n->getCell()==this) { - length_contribution += + length_contribution += DSQR(Node::target_length-(*(*i)-*(n->nb1)).Norm()) + DSQR(Node::target_length-(*(*i)-*(n->nb2)).Norm()); } @@ -1451,37 +1464,37 @@ bool Cell::SelfIntersect(void) for (list::const_iterator i=nodes.begin(); i!=nodes.end(); i++) { - list::const_iterator j=i; + list::const_iterator j=i; ++j; - for (; j!=nodes.end(); j++) + for (; j!=nodes.end(); j++) { - + Vector v1 = *(*i); list::const_iterator nb=i; nb++; if (nb == nodes.end()) { nb = nodes.begin(); - } + } Vector v2 = *(*nb); Vector v3 = *(*j); nb=j; nb++; if (nb == nodes.end()) { nb = nodes.begin(); - } - Vector v4=*( *nb ); + } + Vector v4=*( *nb ); - double denominator = + double denominator = (v4.y - v3.y)*(v2.x - v1.x) - (v4.x - v3.x)*(v2.y - v1.y); - double ua = + double ua = ((v4.x - v3.x)*(v1.y - v3.y) - (v4.y - v3.y)*(v1.x -v3.x))/denominator; - double ub = + double ub = ((v2.x - v1.x)*(v1.y-v3.y) - (v2.y- v1.y)*(v1.x - v3.x))/denominator; if ( ( TINY < ua && ua < 1.-TINY ) && ( TINY < ub && ub < 1.-TINY ) ) { - //cerr << "ua = " << ua << ", ub = " << ub << endl; + //cerr << "ua = " << ua << ", ub = " << ub << Qt::endl; return true; } } @@ -1495,7 +1508,7 @@ bool Cell::SelfIntersect(void) bool Cell::MoveSelfIntersectsP(Node *moving_node_ind, Vector new_pos) { - // Check whether the polygon will self-intersect if moving_node_ind + // Check whether the polygon will self-intersect if moving_node_ind // were displaced to new_pos // Compare the two new edges against each other edge @@ -1515,9 +1528,9 @@ bool Cell::MoveSelfIntersectsP(Node *moving_node_ind, Vector new_pos) nb++; if (nb == nodes.end()) { nb = nodes.begin(); - } + } - neighbor_of_moving_node[0]=*(*nb); + neighbor_of_moving_node[0]=*(*nb); nb=moving_node_ind_pos; if (nb == nodes.begin()) { @@ -1525,7 +1538,7 @@ bool Cell::MoveSelfIntersectsP(Node *moving_node_ind, Vector new_pos) } nb--; - neighbor_of_moving_node[1]=*( *nb ); + neighbor_of_moving_node[1]=*( *nb ); for (list::const_iterator i=nodes.begin(); i!=nodes.end(); i++) { @@ -1534,7 +1547,7 @@ bool Cell::MoveSelfIntersectsP(Node *moving_node_ind, Vector new_pos) nb++; if (nb == nodes.end()) { nb = nodes.begin(); - } + } if (*i == moving_node_ind || *nb == moving_node_ind) { // do not compare to self continue; @@ -1543,16 +1556,16 @@ bool Cell::MoveSelfIntersectsP(Node *moving_node_ind, Vector new_pos) Vector v3 = *(*i); Vector v4 = *(*nb); - double denominator = + double denominator = (v4.y - v3.y)*(neighbor_of_moving_node[j].x - new_pos.x) - (v4.x - v3.x)*(neighbor_of_moving_node[j].y - new_pos.y); - double ua = + double ua = ((v4.x - v3.x)*(new_pos.y - v3.y) - (v4.y - v3.y)*(new_pos.x -v3.x))/denominator; - double ub = + double ub = ((neighbor_of_moving_node[j].x - new_pos.x)*(new_pos.y-v3.y) - (neighbor_of_moving_node[j].y- new_pos.y)*(new_pos.x - v3.x))/denominator; if ( ( TINY < ua && ua < 1.-TINY ) && ( TINY < ub && ub < 1.-TINY ) ) { - //cerr << "ua = " << ua << ", ub = " << ub << endl; + //cerr << "ua = " << ua << ", ub = " << ub << Qt::endl; return true; } } @@ -1566,40 +1579,40 @@ bool Cell::MoveSelfIntersectsP(Node *moving_node_ind, Vector new_pos) bool Cell::MoveSelfIntersectsP(Node *moving_node_ind, Vector new_pos) { - + // Check whether the polygon will self-intersect if moving_node_ind // were displaced to new_pos - + // Compare the two new edges against each other edge - + // O(2*N) - + // method used for segment intersection: // http://astronomy.swin.edu.au/~pbourke/geometry/lineline2d/ - + Vector neighbor_of_moving_node[2]; - + //cerr << "list::const_iterator moving_node_ind_pos = find (nodes.begin(),nodes.end(),moving_node_ind);\n"; list::const_iterator moving_node_ind_pos = find (nodes.begin(),nodes.end(),moving_node_ind); - + list::const_iterator nb = moving_node_ind_pos; //cerr << "Done\n"; nb++; if (nb == nodes.end()) { nb = nodes.begin(); } - + neighbor_of_moving_node[0]=*(*nb); - + nb=moving_node_ind_pos; if (nb == nodes.begin()) { nb = nodes.end(); } nb--; - + neighbor_of_moving_node[1]=*( *nb ); - - + + for (list::const_iterator i=nodes.begin(); i!=nodes.end(); i++) { for (int j=0;j<2;j++) { // loop over the two neighbors of moving node list::const_iterator nb=i; @@ -1611,13 +1624,13 @@ bool Cell::MoveSelfIntersectsP(Node *moving_node_ind, Vector new_pos) // do not compare to self continue; } - + Vector v3 = *(*i); Vector v4 = *(*nb); - + double denominator = (v4.y - v3.y)*(neighbor_of_moving_node[j].x - new_pos.x) - (v4.x - v3.x)*(neighbor_of_moving_node[j].y - new_pos.y); - + // double ua = // ((v4.x - v3.x)*(new_pos.y - v3.y) - (v4.y - v3.y)*(new_pos.x -v3.x))/denominator; // double ub = @@ -1625,23 +1638,23 @@ bool Cell::MoveSelfIntersectsP(Node *moving_node_ind, Vector new_pos) double numera = ((v4.x - v3.x)*(new_pos.y - v3.y) - (v4.y - v3.y)*(new_pos.x -v3.x)); double numerb = ((neighbor_of_moving_node[j].x - new_pos.x)*(new_pos.y-v3.y) - (neighbor_of_moving_node[j].y- new_pos.y)*(new_pos.x - v3.x)); - + // Are the wall elements coincident? if (fabs(numera) < TINY && fabs(numerb) < TINY && fabs(denominator) < TINY) { return true; } - + // Are the wall elements parallel? if (fabs(denominator) < TINY) { continue; } double ua = numera / denominator; double ub = numerb / denominator; - - + + //if ( ( TINY < ua && ua < 1.-TINY ) && ( TINY < ub && ub < 1.-TINY ) ) { if ( ( 0 < ua && ua < 1. ) && ( 0 < ub && ub < 1.) ) { - //cerr << "ua = " << ua << ", ub = " << ub << endl; + //cerr << "ua = " << ua << ", ub = " << ub << Qt::endl; return true; } } @@ -1654,84 +1667,84 @@ bool Cell::MoveSelfIntersectsP(Node *moving_node_ind, Vector new_pos) bool Cell::LinePieceIntersectsP(const Vector n1, const Vector n2) const { - + // Check whether the polygon will self-intersect if moving_node_ind // were displaced to new_pos - + // Compare the two new edges against each other edge - + // O(2*N) - + // method used for segment intersection: // http://astronomy.swin.edu.au/~pbourke/geometry/lineline2d/ - + /*Vector neighbor_of_moving_node[2]; - + //cerr << "list::const_iterator moving_node_ind_pos = find (nodes.begin(),nodes.end(),moving_node_ind);\n"; list::const_iterator moving_node_ind_pos = find (nodes.begin(),nodes.end(),moving_node_ind); - + list::const_iterator nb = moving_node_ind_pos; //cerr << "Done\n"; nb++; if (nb == nodes.end()) { nb = nodes.begin(); } - + neighbor_of_moving_node[0]=*(*nb); - + nb=moving_node_ind_pos; if (nb == nodes.begin()) { nb = nodes.end(); } nb--; - + neighbor_of_moving_node[1]=*( *nb ); */ - + for (list::const_iterator i=nodes.begin(); i!=nodes.end(); i++) { list::const_iterator nb=i; nb++; if (nb == nodes.end()) { nb = nodes.begin(); } - + /* if (*i == moving_node_ind || *nb == moving_node_ind) { // do not compare to self continue; }*/ - + Vector v3 = *(*i); Vector v4 = *(*nb); - + double denominator = (v4.y - v3.y)*(n1.x - n2.x) - (v4.x - v3.x)*(n1.y - n2.y); - + /* double ua = ((v4.x - v3.x)*(new_pos.y - v3.y) - (v4.y - v3.y)*(new_pos.x -v3.x))/denominator; double ub = ((neighbor_of_moving_node[j].x - new_pos.x)*(new_pos.y-v3.y) - (neighbor_of_moving_node[j].y- new_pos.y)*(new_pos.x - v3.x))/denominator;*/ double numera = ((v4.x - v3.x)*(n1.y - v3.y) - (v4.y - v3.y)*(n1.x -v3.x)); double numerb = ((n2.x - n1.x)*(n1.y-v3.y) - (n2.y- n1.y)*(n1.x - v3.x)); - + /* Are the wall elements coincident? */ if (fabs(numera) < TINY && fabs(numerb) < TINY && fabs(denominator) < TINY) { return true; } - + /* Are the wall elements parallel? */ if (fabs(denominator) < TINY) { continue; } double ua = numera / denominator; double ub = numerb / denominator; - - + + //if ( ( TINY < ua && ua < 1.-TINY ) && ( TINY < ub && ub < 1.-TINY ) ) { if ( ( 0 < ua && ua < 1. ) && ( 0 < ub && ub < 1.) ) { - //cerr << "ua = " << ua << ", ub = " << ub << endl; + //cerr << "ua = " << ua << ", ub = " << ub << Qt::endl; return true; } - + } return false; } @@ -1744,7 +1757,7 @@ bool Cell::IntersectsWithLineP(const Vector v1, const Vector v2) // Compare the line against each edge // method used: http://astronomy.swin.edu.au/~pbourke/geometry/lineline2d/ - for (list::const_iterator i=nodes.begin(); i!=nodes.end(); i++) + for (list::const_iterator i=nodes.begin(); i!=nodes.end(); i++) { Vector v3 = *(*i); list::const_iterator nb=i; @@ -1754,12 +1767,12 @@ bool Cell::IntersectsWithLineP(const Vector v1, const Vector v2) } Vector v4 = *(*nb); - double denominator = + double denominator = (v4.y - v3.y)*(v2.x - v1.x) - (v4.x - v3.x)*(v2.y - v1.y); - double ua = + double ua = ((v4.x - v3.x)*(v1.y - v3.y) - (v4.y - v3.y)*(v1.x -v3.x))/denominator; - double ub = + double ub = ((v2.x - v1.x)*(v1.y-v3.y) - (v2.y- v1.y)*(v1.x - v3.x))/denominator; if ( ( TINY < ua && ua < 1.-TINY ) && ( TINY < ub && ub < 1.-TINY ) ) { @@ -1802,7 +1815,7 @@ void Cell::ConstructWalls(void) // previous one in list list::const_iterator nb = (--corner_points.end()); - // loop over list, + // loop over list, for (list::const_iterator i=corner_points.begin(); i!=corner_points.end(); ( i++, nb++) ) { if (nb==corner_points.end()) nb=corner_points.begin(); @@ -1828,13 +1841,13 @@ void Cell::ConstructWalls(void) for (list::const_iterator j=owning_cells.begin(); j!=owning_cells.end(); ( j++, prevj++) ) { if (prevj==owning_cells.end()) prevj=owning_cells.begin(); - if (*j==*prevj) + if (*j==*prevj) duplicates.push_back(*j); } if (duplicates.size()==3) { // ignore cell boundary (this occurs only after the first division, I think) vector::iterator dup_it = find_if(duplicates.begin(),duplicates.end(),mem_fn(&Cell::BoundaryPolP) ); - if (dup_it!=duplicates.end()) + if (dup_it!=duplicates.end()) duplicates.erase(dup_it); else { return; @@ -1907,12 +1920,12 @@ void Cell::Flux(double *flux, double *D) #ifdef QDEBUG if ((*i)->c1!=this) { - qDebug() << "Warning, bad cells boundary: " << (*i)->c1->Index() << ", " << index << endl; + qDebug() << "Warning, bad cells boundary: " << (*i)->c1->Index() << ", " << index << Qt::endl; } #endif flux[c] += phi; - } + } } } @@ -1927,9 +1940,9 @@ void Cell::Draw(QGraphicsScene *c, bool showStiffness, QString tooltip) // Draw the cell on a QCanvas object - if (DeadP()) { + if (DeadP()) { #ifdef QDEBUG - qDebug() << "Cell " << index << " not drawn, because dead." << endl; + qDebug() << "Cell " << index << " not drawn, because dead." << Qt::endl; #endif return; } @@ -2052,7 +2065,7 @@ void Cell::DrawNodes(QGraphicsScene *c) const { item ->setPos(((offset[0]+i->x)*factor), ((offset[1]+i->y)*factor) ); c->addItem(item); item->show(); - + } } @@ -2063,19 +2076,19 @@ void Cell::DrawIndex(QGraphicsScene *c) const { // Draw any text in the cell's center void Cell::DrawText(QGraphicsScene *c, const QString &text) const { - + Vector centroid = Centroid(); QGraphicsSimpleTextItem *ctext = new QGraphicsSimpleTextItem ( text, 0); // ctext->setPen( QPen(QColor(par.textcolor)) ); ctext->setBrush( QBrush(QColor(par.textcolor)) ); ctext->setZValue(20); ctext->setFont( QFont( "Helvetica", par.cellnumsize, QFont::Normal) ); - + ctext ->setPos(((offset[0]+centroid.x)*factor), ((offset[1]+centroid.y)*factor) ); c->addItem(ctext); ctext->show(); - + } @@ -2085,7 +2098,7 @@ void Cell::DrawAxis(QGraphicsScene *c) const { double width; Length(&long_axis, &width); - //cerr << "Length is " << length << endl; + //cerr << "Length is " << length << Qt::endl; long_axis.Normalise(); Vector short_axis=long_axis.Perp2D(); @@ -2100,13 +2113,13 @@ void Cell::DrawAxis(QGraphicsScene *c) const { line->setZValue(2); line->setLine( ( (offset[0]+from.x)*factor ), - ( (offset[1]+from.y)*factor ), + ( (offset[1]+from.y)*factor ), ( (offset[0]+to.x)*factor ), ( (offset[1]+to.y)*factor ) ); line->setZValue(10); c->addItem(line); line->show(); - + } void Cell::DrawStrain(QGraphicsScene *c) const { @@ -2135,7 +2148,7 @@ void Cell::DrawFluxes(QGraphicsScene *c, double arrowsize) arrow->setZValue(2); arrow->setLine( ( (offset[0]+from.x)*factor ), - ( (offset[1]+from.y)*factor ), + ( (offset[1]+from.y)*factor ), ( (offset[0]+to.x)*factor ), ( (offset[1]+to.y)*factor ) ); arrow->setZValue(10); @@ -2183,22 +2196,22 @@ void Cell::SetWallLengths(void) // Now, walk to the second node of the edge in the list of nodes for (list::const_iterator n=++first_node_edge; n!=second_node_edge_plus_1; ++n ) { if (n==nodes.end()) - n=nodes.begin(); /* wrap around */ - list::const_iterator prev_n = n; + n=nodes.begin(); /* wrap around */ + list::const_iterator prev_n = n; if (prev_n==nodes.begin()) prev_n=nodes.end(); --prev_n; - // Note that Node derives from a Vector, so we can do vector calculus as defined in vector.h - sum_length += (*(*prev_n) - *(*n)).Norm(); + // Note that Node derives from a Vector, so we can do vector calculus as defined in vector.h + sum_length += (*(*prev_n) - *(*n)).Norm(); - //cerr << "Node " << *prev_n << " to " << *n << ", cumulative length = " << sum_length << endl; + //cerr << "Node " << *prev_n << " to " << *n << ", cumulative length = " << sum_length << Qt::endl; } // We got the total length of the Wall now, store it: (*de)->length = sum_length; - //cerr << endl; + //cerr << Qt::endl; // goto next de } } @@ -2241,7 +2254,7 @@ void Cell::AddWall( Wall *w ) // if necessary, we could try later inserting it at the correct position #ifdef QDEBUG if (w->c1 == w->c2 ){ - qDebug() << "Wall between identical cells: " << w->c1->Index()<< endl; + qDebug() << "Wall between identical cells: " << w->c1->Index()<< Qt::endl; } #endif @@ -2267,7 +2280,7 @@ list::iterator Cell::RemoveWall( Wall *w ) void Cell::EmitValues(double t) { - // cerr << "Attempting to emit " << t << ", " << chem[0] << ", " << chem[1] << endl; + // cerr << "Attempting to emit " << t << ", " << chem[0] << ", " << chem[1] << Qt::endl; emit ChemMonValue(t, chem); } @@ -2307,4 +2320,108 @@ double Cell::elastic_limit() { return this->m->elastic_limit; } + + +Vector Cell::CalculateDivisionPlane() +{ + Vector div_vec; + + switch (division_type) { + case NO_DIVISION: + // No division, return empty vector + return Vector(0, 0, 0); + + case RANDOM_DIVISION: + // Random division vector + div_vec = Vector(RANDOM() - 0.5, RANDOM() - 0.5, 0); + div_vec.Normalise(); + return div_vec; + + case MAX_STRESS_AXIS: { + // Calculate stress tensor for this cell + // Matrix stress = CalculateStressTensor(); + // Find eigenvector corresponding to maximum eigenvalue + // Vector max_stress_axis = stress.GetEigenvectorOfMaxEigenvalue(); + Vector max_stress_axis(0, 0, 0); // Properly initialize the vector + return max_stress_axis; + } + + case SHORT_AXIS: { + // Use the short axis of the cell for division + Vector long_axis; + double width; + Length(&long_axis, &width); + return long_axis.Perp2D(); // Perpendicular to long axis = short axis + } + + case LONG_AXIS: { + // Use the long axis of the cell for division + Vector long_axis; + double width; + Length(&long_axis, &width); + return long_axis; + } + + case PERP_STRESS: { + // Calculate stress tensor for this cell + // Matrix stress = CalculateStressTensor(); + // // Find eigenvector corresponding to maximum eigenvalue + // Vector max_stress_axis = stress.GetEigenvectorOfMaxEigenvalue(); + // Return perpendicular vector + Vector max_stress_axis(0, 0, 0); // Properly initialize the vector + return max_stress_axis.Perp2D(); + } + + default: + // Default to random division + div_vec = Vector(RANDOM() - 0.5, RANDOM() - 0.5, 0); + div_vec.Normalise(); + return div_vec; + } +} + +// Matrix Cell::CalculateStressTensor() +// { +// // Initialize stress tensor +// Matrix stress(2,2); +// +// // Calculate stress for each wall element +// for (list::const_iterator i=nodes.begin(); i!=nodes.end(); i++) { +// list::const_iterator next = i; +// next++; +// if (next == nodes.end()) { +// next = nodes.begin(); +// } +// +// // Calculate wall element vector +// Vector wall_vec = *(*next) - *(*i); +// double length = wall_vec.Norm(); +// wall_vec.Normalise(); +// +// // Get wall stiffness and strain +// WallElementInfo element; +// fillWallElementInfo(&element, *i, *next); +// double stiffness = element.stiffness(); +// if (std::isnan(stiffness)) { +// stiffness = 1.0; +// } +// +// double rest_length = element.restLength(); +// if (std::isnan(rest_length) || rest_length <= 0) { +// rest_length = length; +// } +// +// double strain = (length - rest_length) / rest_length; +// double tension = stiffness * strain; +// +// // Add contribution to stress tensor +// stress(0,0) += tension * wall_vec.x * wall_vec.x; +// stress(0,1) += tension * wall_vec.x * wall_vec.y; +// stress(1,0) += tension * wall_vec.y * wall_vec.x; +// stress(1,1) += tension * wall_vec.y * wall_vec.y; +// } +// +// return stress; +// } + /* finis */ diff --git a/src/GUI/cell.h b/src/GUI/cell.h index 2851ebd..737292b 100755 --- a/src/GUI/cell.h +++ b/src/GUI/cell.h @@ -34,6 +34,8 @@ #include "warning.h" #include "cellbase.h" #include "Neighbor.h" +#include "random.h" +#include "pi.h" //#include "cell.h" #include @@ -94,11 +96,71 @@ class Cell : public CellBase // divide over the line (if line and cell intersect) bool DivideOverGivenLine(const Vector v1, const Vector v2, bool wall_fixed = false, NodeSet *node_set = 0); - void Divide(void) { // Divide cell over short axis - - Vector long_axis; - Length(&long_axis); - DivideOverAxis(long_axis.Perp2D()); + void Divide(void) { // Divide cell based on division_type + std::cout << "Cell " << index << ": Starting division process" << std::endl; + Vector axis; + Length(&axis); // Get the long axis + std::cout << "Cell " << index << ": Long axis = (" << axis.x << ", " << axis.y << ", " << axis.z << ")" << std::endl; + + switch (division_type) { + case NO_DIVISION: + std::cout << "Cell " << index << ": Division type = NO_DIVISION, skipping" << std::endl; + return; + case RANDOM_DIVISION: + { + std::cout << "Cell " << index << ": Division type = RANDOM_DIVISION" << std::endl; + // Random angle between 0 and π + double orientation = Pi*RANDOM(); + Vector divAxis(sin(orientation), cos(orientation), 0.); + std::cout << "Cell " << index << ": Random division axis = (" << divAxis.x << ", " << divAxis.y << ", " << divAxis.z << "), orientation = " << orientation << std::endl; + DivideOverAxis(divAxis); + } + break; + case MAX_STRESS_AXIS: + std::cout << "Cell " << index << ": Division type = MAX_STRESS_AXIS" << std::endl; + // Calculate principal stress axis and divide along it + { + Vector stressAxis = CalculateDivisionPlane(); + std::cout << "Cell " << index << ": Stress division axis = (" << stressAxis.x << ", " << stressAxis.y << ", " << stressAxis.z << ")" << std::endl; + DivideOverAxis(stressAxis); + } + break; + case SHORT_AXIS: + std::cout << "Cell " << index << ": Division type = SHORT_AXIS" << std::endl; + // Divide over short axis (perpendicular to long axis) + { + Vector shortAxis = axis.Perp2D(); + std::cout << "Cell " << index << ": Short axis = (" << shortAxis.x << ", " << shortAxis.y << ", " << shortAxis.z << ")" << std::endl; + DivideOverAxis(shortAxis); + } + break; + case LONG_AXIS: + std::cout << "Cell " << index << ": Division type = LONG_AXIS" << std::endl; + // Divide over long axis + std::cout << "Cell " << index << ": Using long axis for division" << std::endl; + DivideOverAxis(axis); + break; + case PERP_STRESS: + std::cout << "Cell " << index << ": Division type = PERP_STRESS" << std::endl; + // Divide perpendicular to principal stress + { + Vector stress_axis = CalculateDivisionPlane(); + Vector perpStressAxis = stress_axis.Perp2D(); + std::cout << "Cell " << index << ": Perpendicular stress axis = (" << perpStressAxis.x << ", " << perpStressAxis.y << ", " << perpStressAxis.z << ")" << std::endl; + DivideOverAxis(perpStressAxis); + } + break; + default: + std::cout << "Cell " << index << ": Division type = UNKNOWN (" << division_type << "), defaulting to SHORT_AXIS" << std::endl; + // Default to short axis division + { + Vector shortAxis = axis.Perp2D(); + std::cout << "Cell " << index << ": Default short axis = (" << shortAxis.x << ", " << shortAxis.y << ", " << shortAxis.z << ")" << std::endl; + DivideOverAxis(shortAxis); + } + break; + } + std::cout << "Cell " << index << ": Division complete" << std::endl; } //void CheckForGFDrivenDivision(void); @@ -179,6 +241,7 @@ class Cell : public CellBase void findBeforeAfter(Node * node, Node ** before, Node**after); Cell* findOtherCell(Cell*other, Node * node, Node * node2); Cell* findNeighbourCellOnDivide(Cell* daughter,Node* node,Node * before1,Node * after1 ,Node * before2,Node * after2); + Vector CalculateDivisionPlane(); }; diff --git a/src/GUI/mesh.cpp b/src/GUI/mesh.cpp index feb81a1..811c130 100755 --- a/src/GUI/mesh.cpp +++ b/src/GUI/mesh.cpp @@ -50,6 +50,7 @@ #include static const std::string _module_id("$Id$"); +int Mesh::cell_to_debug = 1000; extern Parameter par; @@ -654,6 +655,7 @@ double getStiffness(CellBase* c,NodeBase* n1) { } void Mesh::RemodelWallElement(vector & curves,CellBase* c,Node* w0,Node* w1,Node* w2,Node* w3,Node* w4) { +// qDebug() << "DisplaceNodes - elastic_modulus: " << elastic_modulus; Node * o0; Node * o1; @@ -1102,7 +1104,12 @@ double Mesh::DisplaceNodes(void) { double cell_w = c.GetWallStiffness(); w1 = w1*cell_w; w2 = w2*cell_w; - + // Debug output for cell #28 + if (c.Index() == cell_to_debug) { + qDebug() << "Cell: "<< cell_to_debug <<" - Wall Stiffness Debug:"; + qDebug() << " Base stiffness:" << cell_w; + qDebug() << " w1:" << w1 << " w2:" << w2; + } double w_w1 = 1; double w_w2 = 1; @@ -1110,26 +1117,50 @@ double Mesh::DisplaceNodes(void) { double bl_plus_1 = 0.0; if (activateWallStiffnessHamiltonian()) { - calculateWallStiffness(&c, *i, &w_w1, &w_w2, &bl_minus_1, &bl_plus_1); + calculateWallStiffness(&c, *i, &w_w1, &w_w2, &bl_minus_1, &bl_plus_1); +} +if (bl_minus_1>0 && bl_plus_1>0) { + w1 = cell_w * (w_w1); + w2 = cell_w * (w_w2); + //check if wall elements are defined and pick the appropriate length_dh + + double old_length_dh = length_dh; + double term1 = elastic_modulus * w1 * bl_minus_1 * (DSQR(new_l1/bl_minus_1 - 1) - DSQR(old_l1/bl_minus_1 - 1)); + double term2 = elastic_modulus * w2 * bl_plus_1 * (DSQR(new_l2/bl_plus_1 - 1) - DSQR(old_l2/bl_plus_1 - 1)); + length_dh += term1 + term2; + + if (c.Index() == cell_to_debug) { + std::cout << "Debug [Cell " << c.index + << "]: Wall elastic terms - term1: " << term1 << ", term2: " << term2 + << ", length_dh delta: " << (length_dh - old_length_dh) + << "\n w1: " << w1 << ", w2: " << w2 + << "\n elastic modulus: " << elastic_modulus + << "\n bl_minus_1: " << bl_minus_1 << ", bl_plus_1: " << bl_plus_1 + << "\n new_l1: " << new_l1 << ", old_l1: " << old_l1 + << "\n new_l2: " << new_l2 << ", old_l2: " << old_l2 + << "\n length_dh: " << length_dh + << std::endl; } - if (bl_minus_1>0 && bl_plus_1>0) { - w1 = cell_w * (w_w1); - w2 = cell_w * (w_w2); - //check if wall elements are defined and pick the appropriate length_dh - - length_dh += - elastic_modulus * w1 * - bl_minus_1 *(DSQR(new_l1/bl_minus_1 - 1)-DSQR(old_l1/bl_minus_1 - 1)) + - elastic_modulus * w2 * - bl_plus_1 *(DSQR(new_l2/bl_plus_1 - 1)-DSQR(old_l2/bl_plus_1 - 1)); +} +else { + double old_length_dh = length_dh; + double term1 = 2 * Node::target_length * (w1 * (old_l1 - new_l1) + w2 * (old_l2 - new_l2)); + double term2 = w1 * (DSQR(new_l1) - DSQR(old_l1)) + w2 * (DSQR(new_l2) - DSQR(old_l2)); + length_dh += term1 + term2; + + if (c.Index() == cell_to_debug) { + std::cout << "Debug [Cell " << c.index + << "]: Default elastic terms - term1: " << term1 << ", term2: " << term2 + << ", length_dh delta: " << (length_dh - old_length_dh) + << "\n w1: " << w1 << ", w2: " << w2 + << "\n elastic modulus: " << elastic_modulus + << "\n target_length: " << Node::target_length + << "\n new_l1: " << new_l1 << ", old_l1: " << old_l1 + << "\n new_l2: " << new_l2 << ", old_l2: " << old_l2 + << "\n length_dh: " << length_dh + << std::endl; } - else { - length_dh +=2*Node::target_length * ( - w1*(old_l1 - new_l1) + - w2*(old_l2 - new_l2) ) + - w1*(DSQR(new_l1) - DSQR(old_l1)) + - w2*(DSQR(new_l2) - DSQR(old_l2)); - } +} // cout << node << "\t" << bl_minus_1 << "\t" << bl_plus_1 << "\t" << w_w1 << "\t" << w_w2 << "\n"; } @@ -1198,36 +1229,85 @@ void Mesh::WallRelaxation(void) { } } -void extractWallData(WallElementInfo* wallElementInfo,double *w,double* bl){ +void extractWallData(WallElementInfo* wallElementInfo, double *w, double *bl){ double stiffness=.0; double base_length=.0; + int cell_to_debug = 1000; // Set the cell index to debug + + bool debugCell = (wallElementInfo->getCell()->Index() == cell_to_debug); + + if (debugCell) { + qDebug() << "extractWallData called with wallElementInfo:" << wallElementInfo; + } + if (wallElementInfo->hasWallElement()) { stiffness = wallElementInfo->getWallElement()->getStiffness(); base_length = wallElementInfo->getBaseLength(); + if (debugCell) { + qDebug() << " Has WallElement - Stiffness:" << stiffness << "Base Length:" << base_length; + } } else { stiffness = wallElementInfo->getCell()->GetWallStiffness(); + if (debugCell) { + qDebug() << " No WallElement - Using cell wall stiffness:" << stiffness; + } } + + double old_w = *w; + double old_bl = *bl; if (!std::isnan(stiffness)){ (*w) += stiffness; (*bl) += base_length; + if (debugCell) { + qDebug() << " Updated values - w:" << old_w << "->" << *w << "bl:" << old_bl << "->" << *bl; + } + } else if (debugCell) { + qDebug() << " Skipped update due to NaN stiffness"; } } - void Mesh::calculateWallStiffness(CellBase* c, Node* node, double *w_p1,double *w_p2, double* bl_minus_1, double* bl_plus_1) { - c->LoopWallElements([node,w_p1,w_p2,bl_minus_1,bl_plus_1](auto wallElementInfo){ - int points = 0; - if (wallElementInfo->isTo(node)) { + bool debugCell = (c->Index() == cell_to_debug); + + if (debugCell) { + qDebug() << "calculateWallStiffness called for Cell 1 and Node" << node->Index(); + qDebug() << " Initial values - w_p1:" << *w_p1 << "w_p2:" << *w_p2 + << "bl_minus_1:" << *bl_minus_1 << "bl_plus_1:" << *bl_plus_1; + } + + c->LoopWallElements([node,w_p1,w_p2,bl_minus_1,bl_plus_1,debugCell](auto wallElementInfo){ + int points = 0; + if (wallElementInfo->isTo(node)) { + if (debugCell) { + qDebug() << " Found wall element TO node" << node->Index() << "- Before extraction w_p1:" << *w_p1 << "bl_minus_1:" << *bl_minus_1; + } extractWallData(wallElementInfo,w_p1,bl_minus_1); + if (debugCell) { + qDebug() << " After extraction w_p1:" << *w_p1 << "bl_minus_1:" << *bl_minus_1; + } points++; - } else if (wallElementInfo->isFrom(node)) { + } else if (wallElementInfo->isFrom(node)) { + if (debugCell) { + qDebug() << " Found wall element FROM node" << node->Index() << "- Before extraction w_p2:" << *w_p2 << "bl_plus_1:" << *bl_plus_1; + } extractWallData(wallElementInfo,w_p2,bl_plus_1); + if (debugCell) { + qDebug() << " After extraction w_p2:" << *w_p2 << "bl_plus_1:" << *bl_plus_1; + } points++; } - if (points == 2) { + if (points == 2) { + if (debugCell) { + qDebug() << " Found both connections, stopping loop"; + } //stop the loop, as we do not need to go further. - wallElementInfo->stopLoop(); - } - }); + wallElementInfo->stopLoop(); + } + }); + + if (debugCell) { + qDebug() << " Final values - w_p1:" << *w_p1 << "w_p2:" << *w_p2 + << "bl_minus_1:" << *bl_minus_1 << "bl_plus_1:" << *bl_plus_1; + } } diff --git a/src/GUI/mesh.h b/src/GUI/mesh.h index 17b42aa..fdb89c8 100755 --- a/src/GUI/mesh.h +++ b/src/GUI/mesh.h @@ -86,7 +86,7 @@ class Mesh { friend class Node; friend class FigureEditor; - public: +public: Mesh(void) { // Make sure the reserved value is large enough if a cell is added // in "Divide" when the capacity is insufficient, "cells" might be @@ -333,7 +333,6 @@ class Mesh { } return sum/(double)NCells(); } - void SetBaseArea(void); int NCells(void) const { return cells.size(); @@ -466,6 +465,8 @@ class Mesh { double time; SimPluginInterface *plugin; + static int cell_to_debug; + // Private member functions double CellSpecificStiffnessOneSide(Node *nb,set &nodeown); void AddNodeToCell(Cell *c, Node *n, Node *nb1 , Node *nb2); diff --git a/src/Library/cellbase.h b/src/Library/cellbase.h index 8f55efc..401e596 100755 --- a/src/Library/cellbase.h +++ b/src/Library/cellbase.h @@ -44,6 +44,18 @@ //#include "wallelementinfo.h" + +// Division type enumeration +enum DivisionType { + NO_DIVISION, + RANDOM_DIVISION, + MAX_STRESS_AXIS, + SHORT_AXIS, + LONG_AXIS, + PERP_STRESS +}; + + extern Parameter par; using namespace std; @@ -248,6 +260,9 @@ class CellBase : public QObject, public Vector virtual void InsertWall( WallBase *w ); virtual CellBase* getOtherWallElementSide(NodeBase * spikeEnd,NodeBase * over); virtual double elastic_limit(); + void SetDivisionType(DivisionType type) { division_type = type; } + DivisionType GetDivisionType() const { return division_type; } + DivisionType division_type; QList getWalls(void) { QList wall_list; diff --git a/src/Models/Cambium/Makefile b/src/Models/Cambium/Makefile index b7a3fbd..69ca93e 100644 --- a/src/Models/Cambium/Makefile +++ b/src/Models/Cambium/Makefile @@ -1111,7 +1111,7 @@ moc_cambium.cpp: cambium.h \ /home/ardati/anaconda3/include/qt/QtGui/QColor \ moc_predefs.h \ /home/ardati/anaconda3/bin/moc - /home/ardati/anaconda3/bin/moc $(DEFINES) --include /home/ardati/PycharmProjects/VirtualLeaf2021/src/Models/Cambium/moc_predefs.h -I/home/ardati/anaconda3/mkspecs/linux-g++ -I/home/ardati/PycharmProjects/VirtualLeaf2021/src/Models/Cambium -I/home/ardati/PycharmProjects/VirtualLeaf2021/src/Library -I/home/ardati/PycharmProjects/VirtualLeaf2021/src/GUI -I/home/ardati/PycharmProjects/VirtualLeaf2021/include -I/home/ardati/anaconda3/include/qt -I/home/ardati/anaconda3/include/qt/QtWidgets -I/home/ardati/anaconda3/include/qt/QtGui -I/home/ardati/anaconda3/include/qt/QtXml -I/home/ardati/anaconda3/include/qt/QtCore -I/usr/include/c++/11 -I/usr/include/x86_64-linux-gnu/c++/11 -I/usr/include/c++/11/backward -I/usr/lib/gcc/x86_64-linux-gnu/11/include -I/usr/local/include -I/usr/include/x86_64-linux-gnu -I/usr/include cambium.h -o moc_cambium.cpp + /home/ardati/anaconda3/bin/moc $(DEFINES) --include /home/ardati/PycharmProjects/VirtualLeaf2021/src/Models/Cambium/moc_predefs.h -I/home/ardati/anaconda3/mkspecs/linux-g++ -I/home/ardati/PycharmProjects/VirtualLeaf2021/src/Models/Cambium -I/home/ardati/PycharmProjects/VirtualLeaf2021/src/Library -I/home/ardati/PycharmProjects/VirtualLeaf2021/src/GUI -I/home/ardati/PycharmProjects/VirtualLeaf2021/include -I/home/ardati/anaconda3/include/qt -I/home/ardati/anaconda3/include/qt/QtWidgets -I/home/ardati/anaconda3/include/qt/QtGui -I/home/ardati/anaconda3/include/qt/QtXml -I/home/ardati/anaconda3/include/qt/QtCore -I/usr/local/hdf5/include -I. -I/usr/include/c++/11 -I/usr/include/x86_64-linux-gnu/c++/11 -I/usr/include/c++/11/backward -I/usr/lib/gcc/x86_64-linux-gnu/11/include -I/usr/local/include -I/usr/include/x86_64-linux-gnu -I/usr/include cambium.h -o moc_cambium.cpp compiler_moc_objc_header_make_all: compiler_moc_objc_header_clean: diff --git a/src/Models/Cambium/Makefile.cambium b/src/Models/Cambium/Makefile.cambium deleted file mode 100644 index 6964f3d..0000000 --- a/src/Models/Cambium/Makefile.cambium +++ /dev/null @@ -1,1010 +0,0 @@ -############################################################################# -# Makefile for building: libcambium.dylib -# Generated by qmake (3.1) (Qt 5.12.1) -# Project: cambium.pro -# Template: lib -# Command: /opt/Qt/5.12.1/clang_64/bin/qmake -o Makefile.cambium cambium.pro -############################################################################# - -MAKEFILE = Makefile.cambium - -EQ = = - -####### Compiler, tools and options - -CC = /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -CXX = /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -DEFINES = -DQTGRAPHICS -DQT_NO_DEBUG -DQT_PLUGIN -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -CFLAGS = -pipe -O2 $(EXPORT_ARCH_ARGS) -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -mmacosx-version-min=10.12 -Wall -W -fPIC $(DEFINES) -CXXFLAGS = -pipe -stdlib=libc++ -Wno-write-strings -Wno-unused-parameter -fPIC -I/usr/include/libxml2 -O2 -std=gnu++11 $(EXPORT_ARCH_ARGS) -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -mmacosx-version-min=10.12 -Wall -W -fPIC $(DEFINES) -INCPATH = -I. -I../../Library -I../../GUI -I/opt/Qt/5.12.1/clang_64/lib/QtWidgets.framework/Headers -I/opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers -I/opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers -I. -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/Applications/Xcode10.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/OpenGL.framework/Headers -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/Applications/Xcode10.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/AGL.framework/Headers/ -I/opt/Qt/5.12.1/clang_64/mkspecs/macx-clang -F/opt/Qt/5.12.1/clang_64/lib -QMAKE = /opt/Qt/5.12.1/clang_64/bin/qmake -DEL_FILE = rm -f -CHK_DIR_EXISTS= test -d -MKDIR = mkdir -p -COPY = cp -f -COPY_FILE = cp -f -COPY_DIR = cp -f -R -INSTALL_FILE = install -m 644 -p -INSTALL_PROGRAM = install -m 755 -p -INSTALL_DIR = cp -f -R -QINSTALL = /opt/Qt/5.12.1/clang_64/bin/qmake -install qinstall -QINSTALL_PROGRAM = /opt/Qt/5.12.1/clang_64/bin/qmake -install qinstall -exe -DEL_FILE = rm -f -SYMLINK = ln -f -s -DEL_DIR = rmdir -MOVE = mv -f -TAR = tar -cf -COMPRESS = gzip -9f -DISTNAME = cambium1.0.0 -DISTDIR = /Users/roel/Documents/GitHub/VirtualLeaf/src/Models/cambium/.tmp/cambium1.0.0 -LINK = /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -LFLAGS = -stdlib=libc++ -fPIC -headerpad_max_install_names $(EXPORT_ARCH_ARGS) -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -mmacosx-version-min=10.12 -Wl,-rpath,@executable_path/Frameworks -Wl,-rpath,/opt/Qt/5.12.1/clang_64/lib -single_module -dynamiclib -LIBS = $(SUBLIBS) -F/opt/Qt/5.12.1/clang_64/lib -L../../../lib -lvleaf -framework QtWidgets -framework QtGui -framework QtCore -framework DiskArbitration -framework IOKit -framework OpenGL -framework AGL -AR = /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar cq -RANLIB = /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib -s -SED = sed -STRIP = strip - -####### Output directory - -OBJECTS_DIR = ./ - -####### Files - -SOURCES = cambium.cpp moc_cambium.cpp -OBJECTS = cambium.o \ - moc_cambium.o -DIST = /opt/Qt/5.12.1/clang_64/mkspecs/features/spec_pre.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/qdevice.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/device_config.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/common/unix.conf \ - /opt/Qt/5.12.1/clang_64/mkspecs/common/mac.conf \ - /opt/Qt/5.12.1/clang_64/mkspecs/common/macx.conf \ - /opt/Qt/5.12.1/clang_64/mkspecs/common/sanitize.conf \ - /opt/Qt/5.12.1/clang_64/mkspecs/common/gcc-base.conf \ - /opt/Qt/5.12.1/clang_64/mkspecs/common/gcc-base-mac.conf \ - /opt/Qt/5.12.1/clang_64/mkspecs/common/clang.conf \ - /opt/Qt/5.12.1/clang_64/mkspecs/common/clang-mac.conf \ - /opt/Qt/5.12.1/clang_64/mkspecs/qconfig.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3danimation.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3danimation_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dcore.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dcore_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dextras.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dextras_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dinput.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dinput_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dlogic.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dlogic_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquick.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquick_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickanimation.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickanimation_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickextras.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickextras_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickinput.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickinput_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickrender.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickrender_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickscene2d.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickscene2d_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3drender.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3drender_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_accessibility_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_bluetooth.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_bluetooth_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_bootstrap_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_charts.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_charts_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_clipboard_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_concurrent.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_concurrent_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_core.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_core_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_datavisualization.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_datavisualization_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_dbus.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_dbus_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_designer.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_designer_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_designercomponents_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_devicediscovery_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_edid_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_eventdispatcher_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_fb_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_fontdatabase_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_gamepad.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_gamepad_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_graphics_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_gui.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_gui_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_help.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_help_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_location.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_location_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_macextras.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_macextras_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_multimedia.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_multimedia_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_multimediawidgets.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_multimediawidgets_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_network.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_network_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_networkauth.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_networkauth_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_nfc.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_nfc_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_opengl.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_opengl_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_openglextensions.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_openglextensions_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_packetprotocol_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_platformcompositor_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_positioning.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_positioning_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_positioningquick.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_positioningquick_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_printsupport.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_printsupport_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_purchasing.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_purchasing_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_qml.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_qml_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_qmldebug_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_qmldevtools_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_qmltest.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_qmltest_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_qtmultimediaquicktools_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quick.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quick_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quickcontrols2.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quickcontrols2_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quickparticles_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quickshapes_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quicktemplates2_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quickwidgets.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quickwidgets_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_remoteobjects.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_remoteobjects_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_repparser.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_repparser_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_script.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_script_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_scripttools.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_scripttools_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_scxml.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_scxml_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_sensors.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_sensors_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_serialbus.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_serialbus_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_serialport.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_serialport_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_service_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_sql.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_sql_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_svg.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_svg_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_testlib.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_testlib_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_texttospeech.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_texttospeech_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_theme_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_uiplugin.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_uitools.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_uitools_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_virtualkeyboard.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_virtualkeyboard_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webchannel.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webchannel_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webengine.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webengine_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webenginecore.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webenginecore_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webenginecoreheaders_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webenginewidgets.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webenginewidgets_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_websockets.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_websockets_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webview.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webview_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_widgets.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_widgets_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_xml.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_xml_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_xmlpatterns.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_xmlpatterns_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_zlib_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/qt_functions.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/qt_config.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/macx-clang/qmake.conf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/spec_post.prf \ - ../../.qmake.stash \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/exclusive_builds.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/mac/sdk.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/toolchain.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/mac/toolchain.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/default_pre.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/mac/default_pre.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/resolve_config.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/default_post.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/mac/default_post.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/mac/objective_c.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/mac/mac.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/warn_on.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/qt.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/resources.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/moc.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/unix/opengl.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/uic.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/unix/thread.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/qmake_use.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/file_copies.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/mac/rez.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/mac/asset_catalogs.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/testcase_targets.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/exceptions.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/yacc.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/lex.prf \ - cambium.pro cambium.h cambium.cpp -QMAKE_TARGET = cambium -DESTDIR = ../../../bin/models/ -TARGET = libcambium.dylib -TARGETD = libcambium.dylib - -####### Custom Variables -EXPORT_VALID_ARCHS = x86_64 -EXPORT_ACTIVE_ARCHS = $(filter $(EXPORT_VALID_ARCHS), $(ARCHS)) -EXPORT_ARCH_ARGS = $(foreach arch, $(if $(EXPORT_ACTIVE_ARCHS), $(EXPORT_ACTIVE_ARCHS), $(EXPORT_VALID_ARCHS)), -arch $(arch)) -EXPORT__PRO_FILE_ = /Users/roel/Documents/GitHub/VirtualLeaf/src/Models/cambium/cambium.pro - - -first: all -####### Build rules - -../../../bin/models/libcambium.dylib: $(OBJECTS) $(SUBLIBS) $(OBJCOMP) - @test -d ../../../bin/models/ || mkdir -p ../../../bin/models/ - -$(DEL_FILE) $(TARGET) - $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS) $(OBJCOMP) - -$(MOVE) $(TARGET) ../../../bin/models/$(TARGET) - - - -Makefile.cambium: cambium.pro /opt/Qt/5.12.1/clang_64/mkspecs/macx-clang/qmake.conf /opt/Qt/5.12.1/clang_64/mkspecs/features/spec_pre.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/qdevice.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/device_config.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/common/unix.conf \ - /opt/Qt/5.12.1/clang_64/mkspecs/common/mac.conf \ - /opt/Qt/5.12.1/clang_64/mkspecs/common/macx.conf \ - /opt/Qt/5.12.1/clang_64/mkspecs/common/sanitize.conf \ - /opt/Qt/5.12.1/clang_64/mkspecs/common/gcc-base.conf \ - /opt/Qt/5.12.1/clang_64/mkspecs/common/gcc-base-mac.conf \ - /opt/Qt/5.12.1/clang_64/mkspecs/common/clang.conf \ - /opt/Qt/5.12.1/clang_64/mkspecs/common/clang-mac.conf \ - /opt/Qt/5.12.1/clang_64/mkspecs/qconfig.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3danimation.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3danimation_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dcore.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dcore_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dextras.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dextras_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dinput.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dinput_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dlogic.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dlogic_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquick.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquick_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickanimation.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickanimation_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickextras.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickextras_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickinput.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickinput_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickrender.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickrender_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickscene2d.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickscene2d_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3drender.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3drender_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_accessibility_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_bluetooth.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_bluetooth_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_bootstrap_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_charts.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_charts_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_clipboard_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_concurrent.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_concurrent_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_core.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_core_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_datavisualization.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_datavisualization_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_dbus.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_dbus_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_designer.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_designer_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_designercomponents_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_devicediscovery_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_edid_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_eventdispatcher_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_fb_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_fontdatabase_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_gamepad.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_gamepad_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_graphics_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_gui.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_gui_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_help.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_help_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_location.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_location_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_macextras.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_macextras_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_multimedia.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_multimedia_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_multimediawidgets.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_multimediawidgets_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_network.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_network_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_networkauth.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_networkauth_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_nfc.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_nfc_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_opengl.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_opengl_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_openglextensions.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_openglextensions_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_packetprotocol_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_platformcompositor_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_positioning.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_positioning_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_positioningquick.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_positioningquick_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_printsupport.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_printsupport_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_purchasing.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_purchasing_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_qml.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_qml_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_qmldebug_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_qmldevtools_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_qmltest.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_qmltest_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_qtmultimediaquicktools_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quick.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quick_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quickcontrols2.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quickcontrols2_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quickparticles_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quickshapes_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quicktemplates2_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quickwidgets.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quickwidgets_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_remoteobjects.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_remoteobjects_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_repparser.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_repparser_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_script.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_script_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_scripttools.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_scripttools_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_scxml.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_scxml_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_sensors.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_sensors_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_serialbus.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_serialbus_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_serialport.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_serialport_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_service_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_sql.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_sql_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_svg.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_svg_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_testlib.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_testlib_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_texttospeech.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_texttospeech_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_theme_support_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_uiplugin.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_uitools.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_uitools_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_virtualkeyboard.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_virtualkeyboard_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webchannel.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webchannel_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webengine.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webengine_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webenginecore.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webenginecore_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webenginecoreheaders_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webenginewidgets.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webenginewidgets_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_websockets.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_websockets_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webview.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webview_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_widgets.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_widgets_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_xml.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_xml_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_xmlpatterns.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_xmlpatterns_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_zlib_private.pri \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/qt_functions.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/qt_config.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/macx-clang/qmake.conf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/spec_post.prf \ - ../../.qmake.stash \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/exclusive_builds.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/mac/sdk.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/toolchain.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/mac/toolchain.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/default_pre.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/mac/default_pre.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/resolve_config.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/default_post.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/mac/default_post.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/mac/objective_c.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/mac/mac.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/warn_on.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/qt.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/resources.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/moc.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/unix/opengl.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/uic.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/unix/thread.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/qmake_use.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/file_copies.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/mac/rez.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/mac/asset_catalogs.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/testcase_targets.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/exceptions.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/yacc.prf \ - /opt/Qt/5.12.1/clang_64/mkspecs/features/lex.prf \ - cambium.pro \ - /opt/Qt/5.12.1/clang_64/lib/QtWidgets.framework/QtWidgets.prl \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/QtGui.prl \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/QtCore.prl - $(QMAKE) -o Makefile.cambium cambium.pro -/opt/Qt/5.12.1/clang_64/mkspecs/features/spec_pre.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/qdevice.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/features/device_config.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/common/unix.conf: -/opt/Qt/5.12.1/clang_64/mkspecs/common/mac.conf: -/opt/Qt/5.12.1/clang_64/mkspecs/common/macx.conf: -/opt/Qt/5.12.1/clang_64/mkspecs/common/sanitize.conf: -/opt/Qt/5.12.1/clang_64/mkspecs/common/gcc-base.conf: -/opt/Qt/5.12.1/clang_64/mkspecs/common/gcc-base-mac.conf: -/opt/Qt/5.12.1/clang_64/mkspecs/common/clang.conf: -/opt/Qt/5.12.1/clang_64/mkspecs/common/clang-mac.conf: -/opt/Qt/5.12.1/clang_64/mkspecs/qconfig.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3danimation.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3danimation_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dcore.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dcore_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dextras.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dextras_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dinput.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dinput_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dlogic.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dlogic_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquick.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquick_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickanimation.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickanimation_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickextras.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickextras_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickinput.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickinput_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickrender.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickrender_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickscene2d.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3dquickscene2d_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3drender.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_3drender_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_accessibility_support_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_bluetooth.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_bluetooth_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_bootstrap_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_charts.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_charts_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_clipboard_support_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_concurrent.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_concurrent_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_core.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_core_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_datavisualization.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_datavisualization_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_dbus.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_dbus_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_designer.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_designer_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_designercomponents_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_devicediscovery_support_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_edid_support_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_eventdispatcher_support_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_fb_support_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_fontdatabase_support_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_gamepad.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_gamepad_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_graphics_support_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_gui.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_gui_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_help.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_help_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_location.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_location_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_macextras.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_macextras_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_multimedia.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_multimedia_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_multimediawidgets.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_multimediawidgets_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_network.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_network_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_networkauth.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_networkauth_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_nfc.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_nfc_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_opengl.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_opengl_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_openglextensions.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_openglextensions_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_packetprotocol_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_platformcompositor_support_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_positioning.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_positioning_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_positioningquick.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_positioningquick_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_printsupport.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_printsupport_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_purchasing.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_purchasing_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_qml.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_qml_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_qmldebug_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_qmldevtools_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_qmltest.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_qmltest_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_qtmultimediaquicktools_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quick.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quick_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quickcontrols2.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quickcontrols2_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quickparticles_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quickshapes_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quicktemplates2_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quickwidgets.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_quickwidgets_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_remoteobjects.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_remoteobjects_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_repparser.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_repparser_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_script.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_script_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_scripttools.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_scripttools_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_scxml.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_scxml_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_sensors.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_sensors_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_serialbus.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_serialbus_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_serialport.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_serialport_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_service_support_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_sql.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_sql_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_svg.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_svg_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_testlib.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_testlib_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_texttospeech.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_texttospeech_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_theme_support_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_uiplugin.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_uitools.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_uitools_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_virtualkeyboard.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_virtualkeyboard_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webchannel.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webchannel_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webengine.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webengine_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webenginecore.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webenginecore_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webenginecoreheaders_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webenginewidgets.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webenginewidgets_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_websockets.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_websockets_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webview.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_webview_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_widgets.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_widgets_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_xml.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_xml_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_xmlpatterns.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_xmlpatterns_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/modules/qt_lib_zlib_private.pri: -/opt/Qt/5.12.1/clang_64/mkspecs/features/qt_functions.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/qt_config.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/macx-clang/qmake.conf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/spec_post.prf: -../../.qmake.stash: -/opt/Qt/5.12.1/clang_64/mkspecs/features/exclusive_builds.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/mac/sdk.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/toolchain.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/mac/toolchain.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/default_pre.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/mac/default_pre.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/resolve_config.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/default_post.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/mac/default_post.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/mac/objective_c.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/mac/mac.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/warn_on.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/qt.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/resources.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/moc.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/unix/opengl.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/uic.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/unix/thread.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/qmake_use.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/file_copies.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/mac/rez.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/mac/asset_catalogs.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/testcase_targets.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/exceptions.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/yacc.prf: -/opt/Qt/5.12.1/clang_64/mkspecs/features/lex.prf: -cambium.pro: -/opt/Qt/5.12.1/clang_64/lib/QtWidgets.framework/QtWidgets.prl: -/opt/Qt/5.12.1/clang_64/lib/QtGui.framework/QtGui.prl: -/opt/Qt/5.12.1/clang_64/lib/QtCore.framework/QtCore.prl: -qmake: FORCE - @$(QMAKE) -o Makefile.cambium cambium.pro - -qmake_all: FORCE - - -all: Makefile.cambium ../../../bin/models/libcambium.dylib - -dist: distdir FORCE - (cd `dirname $(DISTDIR)` && $(TAR) $(DISTNAME).tar $(DISTNAME) && $(COMPRESS) $(DISTNAME).tar) && $(MOVE) `dirname $(DISTDIR)`/$(DISTNAME).tar.gz . && $(DEL_FILE) -r $(DISTDIR) - -distdir: FORCE - @test -d $(DISTDIR) || mkdir -p $(DISTDIR) - $(COPY_FILE) --parents $(DIST) $(DISTDIR)/ - $(COPY_FILE) --parents /opt/Qt/5.12.1/clang_64/mkspecs/features/data/dummy.cpp $(DISTDIR)/ - $(COPY_FILE) --parents cambium.h $(DISTDIR)/ - $(COPY_FILE) --parents cambium.cpp $(DISTDIR)/ - - -clean: compiler_clean - -$(DEL_FILE) $(OBJECTS) - -$(DEL_FILE) *~ core *.core - - -distclean: clean - -$(DEL_FILE) ../../../bin/models/$(TARGET) - -$(DEL_FILE) Makefile.cambium - - -####### Sub-libraries - -xcodeproj: - @$(QMAKE) -spec macx-xcode $(EXPORT__PRO_FILE_) - -mocclean: compiler_moc_header_clean compiler_moc_objc_header_clean compiler_moc_source_clean - -mocables: compiler_moc_header_make_all compiler_moc_objc_header_make_all compiler_moc_source_make_all - -check: first - -benchmark: first - -compiler_rcc_make_all: -compiler_rcc_clean: -compiler_moc_predefs_make_all: moc_predefs.h -compiler_moc_predefs_clean: - -$(DEL_FILE) moc_predefs.h -moc_predefs.h: /opt/Qt/5.12.1/clang_64/mkspecs/features/data/dummy.cpp - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -pipe -stdlib=libc++ -Wno-write-strings -Wno-unused-parameter -fPIC -I/usr/include/libxml2 -O2 -std=gnu++11 $(EXPORT_ARCH_ARGS) -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -mmacosx-version-min=10.12 -Wall -W -dM -E -o moc_predefs.h /opt/Qt/5.12.1/clang_64/mkspecs/features/data/dummy.cpp - -compiler_moc_header_make_all: moc_cambium.cpp -compiler_moc_header_clean: - -$(DEL_FILE) moc_cambium.cpp -moc_cambium.cpp: cambium.h \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/QObject \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/qobject.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/QtGui \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtguiglobal.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qabstracttextdocumentlayout.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qaccessible.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qaccessiblebridge.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qaccessibleobject.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qaccessibleplugin.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qbackingstore.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qbitmap.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qbrush.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qclipboard.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qcolor.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qcursor.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qdesktopservices.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qdrag.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qevent.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qfont.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qfontdatabase.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qfontinfo.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qfontmetrics.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qgenericmatrix.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qgenericplugin.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qgenericpluginfactory.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qglyphrun.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qguiapplication.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qicon.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qiconengine.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qiconengineplugin.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qimage.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qimageiohandler.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qimagereader.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qimagewriter.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qinputmethod.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qkeysequence.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qmatrix.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qmatrix4x4.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qmovie.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qoffscreensurface.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopengl.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglbuffer.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglcontext.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopengldebug.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglextrafunctions.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglframebufferobject.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglfunctions.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglpaintdevice.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglpixeltransferoptions.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglshaderprogram.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopengltexture.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopengltextureblitter.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopengltimerquery.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglversionfunctions.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglvertexarrayobject.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglwindow.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpagedpaintdevice.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpagelayout.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpagesize.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpaintdevice.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpaintdevicewindow.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpaintengine.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpainter.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpainterpath.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpalette.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpdfwriter.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpen.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpicture.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpictureformatplugin.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpixelformat.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpixmap.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpixmapcache.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpolygon.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qquaternion.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qrasterwindow.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qrawfont.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qregion.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qrgb.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qrgba64.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qscreen.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qsessionmanager.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qstandarditemmodel.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qstatictext.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qstylehints.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qsurface.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qsurfaceformat.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qsyntaxhighlighter.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtextcursor.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtextdocument.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtextdocumentfragment.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtextdocumentwriter.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtextformat.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtextlayout.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtextlist.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtextobject.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtextoption.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtexttable.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtouchdevice.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtransform.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qvalidator.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qvector2d.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qvector3d.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qvector4d.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qwindow.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qwindowdefs.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtguiversion.h \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/QString \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/qstring.h \ - ../../Library/simplugin.h \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/QtPlugin \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/qplugin.h \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/QMetaType \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/qmetatype.h \ - ../../Library/cellbase.h \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/QDebug \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/qdebug.h \ - ../../Library/vector.h \ - ../../GUI/sqr.h \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/QPointF \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/qpoint.h \ - ../../Library/parameter.h \ - ../../GUI/wall.h \ - ../../Library/wallbase.h \ - /opt/Qt/5.12.1/clang_64/lib/QtWidgets.framework/Headers/QGraphicsScene \ - /opt/Qt/5.12.1/clang_64/lib/QtWidgets.framework/Headers/qgraphicsscene.h \ - ../../Library/warning.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/QColor \ - moc_predefs.h \ - /opt/Qt/5.12.1/clang_64/bin/moc - /opt/Qt/5.12.1/clang_64/bin/moc $(DEFINES) --include /Users/roel/Documents/GitHub/VirtualLeaf/src/Models/cambium/moc_predefs.h -I/opt/Qt/5.12.1/clang_64/mkspecs/macx-clang -I/Users/roel/Documents/GitHub/VirtualLeaf/src/Models/cambium -I/Users/roel/Documents/GitHub/VirtualLeaf/src/Library -I/Users/roel/Documents/GitHub/VirtualLeaf/src/GUI -I/opt/Qt/5.12.1/clang_64/lib/QtWidgets.framework/Headers -I/opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers -I/opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1 -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/10.0.0/include -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include -F/opt/Qt/5.12.1/clang_64/lib cambium.h -o moc_cambium.cpp - -compiler_moc_objc_header_make_all: -compiler_moc_objc_header_clean: -compiler_moc_source_make_all: -compiler_moc_source_clean: -compiler_uic_make_all: -compiler_uic_clean: -compiler_rez_source_make_all: -compiler_rez_source_clean: -compiler_yacc_decl_make_all: -compiler_yacc_decl_clean: -compiler_yacc_impl_make_all: -compiler_yacc_impl_clean: -compiler_lex_make_all: -compiler_lex_clean: -compiler_clean: compiler_moc_predefs_clean compiler_moc_header_clean - -####### Compile - -cambium.o: cambium.cpp /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/QObject \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/qobject.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/QtGui \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtguiglobal.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qabstracttextdocumentlayout.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qaccessible.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qaccessiblebridge.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qaccessibleobject.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qaccessibleplugin.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qbackingstore.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qbitmap.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qbrush.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qclipboard.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qcolor.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qcursor.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qdesktopservices.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qdrag.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qevent.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qfont.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qfontdatabase.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qfontinfo.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qfontmetrics.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qgenericmatrix.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qgenericplugin.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qgenericpluginfactory.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qglyphrun.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qguiapplication.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qicon.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qiconengine.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qiconengineplugin.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qimage.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qimageiohandler.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qimagereader.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qimagewriter.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qinputmethod.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qkeysequence.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qmatrix.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qmatrix4x4.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qmovie.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qoffscreensurface.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopengl.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglbuffer.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglcontext.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopengldebug.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglextrafunctions.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglframebufferobject.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglfunctions.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglpaintdevice.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglpixeltransferoptions.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglshaderprogram.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopengltexture.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopengltextureblitter.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopengltimerquery.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglversionfunctions.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglvertexarrayobject.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qopenglwindow.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpagedpaintdevice.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpagelayout.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpagesize.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpaintdevice.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpaintdevicewindow.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpaintengine.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpainter.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpainterpath.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpalette.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpdfwriter.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpen.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpicture.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpictureformatplugin.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpixelformat.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpixmap.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpixmapcache.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qpolygon.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qquaternion.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qrasterwindow.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qrawfont.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qregion.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qrgb.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qrgba64.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qscreen.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qsessionmanager.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qstandarditemmodel.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qstatictext.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qstylehints.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qsurface.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qsurfaceformat.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qsyntaxhighlighter.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtextcursor.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtextdocument.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtextdocumentfragment.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtextdocumentwriter.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtextformat.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtextlayout.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtextlist.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtextobject.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtextoption.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtexttable.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtouchdevice.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtransform.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qvalidator.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qvector2d.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qvector3d.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qvector4d.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qwindow.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qwindowdefs.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/qtguiversion.h \ - ../../Library/parameter.h \ - ../../Library/vector.h \ - ../../GUI/sqr.h \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/QPointF \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/qpoint.h \ - ../../Library/wallbase.h \ - ../../Library/cellbase.h \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/QString \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/qstring.h \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/QDebug \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/qdebug.h \ - ../../GUI/wall.h \ - /opt/Qt/5.12.1/clang_64/lib/QtWidgets.framework/Headers/QGraphicsScene \ - /opt/Qt/5.12.1/clang_64/lib/QtWidgets.framework/Headers/qgraphicsscene.h \ - ../../Library/warning.h \ - cambium.h \ - ../../Library/simplugin.h \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/QtPlugin \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/qplugin.h \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/QMetaType \ - /opt/Qt/5.12.1/clang_64/lib/QtCore.framework/Headers/qmetatype.h \ - /opt/Qt/5.12.1/clang_64/lib/QtGui.framework/Headers/QColor - $(CXX) -c $(CXXFLAGS) $(INCPATH) -o cambium.o cambium.cpp - -moc_cambium.o: moc_cambium.cpp - $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_cambium.o moc_cambium.cpp - -####### Install - -install: FORCE - -uninstall: FORCE - -FORCE: - diff --git a/src/Models/Cambium/cambium.cpp b/src/Models/Cambium/cambium.cpp index 31bdf60..2c320c5 100755 --- a/src/Models/Cambium/cambium.cpp +++ b/src/Models/Cambium/cambium.cpp @@ -271,20 +271,21 @@ void cambium::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *d // } //} -void cambium::CellHouseKeeping(CellBase *c) { // How cells behave after division + +// void cambium::CellHouseKeeping(CellBase *c) { // How cells behave after division +// if (c->Index()==1) { +// c->EnlargeTargetArea(par->cell_expansion_rate); +// } +// } +void cambium::CellHouseKeeping(CellBase *c) { + c->SetDivisionType(MAX_STRESS_AXIS); // Set initial area on first call to this function for each cell static std::set initialized_cells; if (initialized_cells.find(c->Index()) == initialized_cells.end()) { c->SetInitialArea(); initialized_cells.insert(c->Index()); } - - qDebug() << "Cell type: " << c->CellType() << ", Area: " << c->Area() << ", BaseArea: " << c->BaseArea() << "InitialArea" <GetInitialArea(); - // Print wall stiffness for debugging -// if (c->Index() == 28) { // Only print for a specific cell if desired -// PrintWallStiffness(c); -// } -// SetCellTypeProperties(c); + // SetCellTypeProperties(c); // Check if a cambium cell is no longer adjacent to the bark, if not it has to be transformed into a Growing Xylem cell if (c->CellType() == 1) { @@ -327,55 +328,7 @@ void cambium::CellHouseKeeping(CellBase *c) { // How cells behave after division /* If the cell is a bark cell (type 0), we need to slightly enlarge it to prevent excessive stretching, which could cause issues in the simulation. This adjustment ensures stability during runtime. */ c->EnlargeTargetArea(0.5 * par->cell_expansion_rate); -// // Get current area values -// double area = c->Area(); -// double baseArea = c->BaseArea(); -// -// // Use static maps to store growth data for each cell by its index -// static std::map growth_additions; -// static std::map last_growth_step; -// static int current_step = 0; -// -// // Increment step counter each time function is called (simulation step) -// current_step++; -// -// // Initialize growth addition for this cell if not present -// if (growth_additions.find(c->Index()) == growth_additions.end()) { -// growth_additions[c->Index()] = 0.0; -// last_growth_step[c->Index()] = 0; -// } -// -// // Check if we need to increase the growth_addition (every 500 simulation steps) -// if (current_step - last_growth_step[c->Index()] >= 200) { -// -// // Increase growth_addition by 25% of baseArea -// growth_additions[c->Index()] += baseArea * 0.25; -// // Update last growth step -// last_growth_step[c->Index()] = current_step; -// -// if (c->Index() == 28) { -// qDebug() << "Cell 28 - GROWTH UPDATE - Step:" << current_step -// << "New Growth Addition:" << growth_additions[c->Index()]; -// } -// } -// -// // Use effective base area (original baseArea + growth_addition) -// double effective_base_area = baseArea + growth_additions[c->Index()]; -// -// // Maintain effective base area if cell has shrunk -// if (area < effective_base_area) { -// // Gradually increase target area to reach effective base area -// c->EnlargeTargetArea(par->cell_expansion_rate); -// -// if (c->Index() == 28) { -// qDebug() << "Cell 28 - ENLARGING TARGET AREA - Step:" << current_step -// << "Effective base area:" << effective_base_area -// << "Current area:" << area -// << "Target area:" << c->TargetArea() -// << "Rate:" << par->cell_expansion_rate; -// } -// } -} + } } diff --git a/src/Models/Cambium/moc_predefs.h b/src/Models/Cambium/moc_predefs.h index 6f841a0..aacf77f 100644 --- a/src/Models/Cambium/moc_predefs.h +++ b/src/Models/Cambium/moc_predefs.h @@ -65,7 +65,6 @@ #define __linux 1 #define __DEC32_EPSILON__ 1E-6DF #define __FLT_EVAL_METHOD_TS_18661_3__ 0 -#define __OPTIMIZE__ 1 #define __unix 1 #define __UINT32_MAX__ 0xffffffffU #define __GXX_EXPERIMENTAL_CXX0X__ 1 @@ -79,7 +78,6 @@ #define __WCHAR_MIN__ (-__WCHAR_MAX__ - 1) #define __INT64_C(c) c ## L #define __GCC_ATOMIC_POINTER_LOCK_FREE 2 -#define _FORTIFY_SOURCE 2 #define __FLT32X_MANT_DIG__ 53 #define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2 #define __cpp_aligned_new 201606L @@ -194,6 +192,7 @@ #define __FLT32_MIN__ 1.17549435082228750796873653722224568e-38F32 #define __UINT8_TYPE__ unsigned char #define __FLT_DIG__ 6 +#define __NO_INLINE__ 1 #define __DEC_EVAL_METHOD__ 2 #define __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL #define __FLT_MANT_DIG__ 24 @@ -307,6 +306,7 @@ #define __UINTPTR_MAX__ 0xffffffffffffffffUL #define __INT_FAST64_WIDTH__ 64 #define __cpp_decltype 200707L +#define QDEBUG 1 #define __INT_FAST64_MAX__ 0x7fffffffffffffffL #define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1 #define __FLT_NORM_MAX__ 3.40282346638528859811704183484516925e+38F diff --git a/src/Models/Tutorial1A/tutorial1A.cpp b/src/Models/Tutorial1A/tutorial1A.cpp index 970c89d..03458e8 100755 --- a/src/Models/Tutorial1A/tutorial1A.cpp +++ b/src/Models/Tutorial1A/tutorial1A.cpp @@ -53,6 +53,12 @@ void Tutorial1A::SetCellColor(CellBase *c, QColor *color) { void Tutorial1A::CellHouseKeeping(CellBase *c) { // add cell behavioral rules here + cout << "Cell base Area: " << c->BaseArea() << endl; + cout << "Cell current Area: " << c->Area() << endl; + cout << "Cell Target Area: " << c->TargetArea() << endl; + c->SetLambdaLength(100); + + c->EnlargeTargetArea(par->cell_expansion_rate); } diff --git a/src/Models/Tutorial1C/tutorial1C.cpp b/src/Models/Tutorial1C/tutorial1C.cpp index bc88ef8..b349e3a 100755 --- a/src/Models/Tutorial1C/tutorial1C.cpp +++ b/src/Models/Tutorial1C/tutorial1C.cpp @@ -52,12 +52,12 @@ void Tutorial1C::SetCellColor(CellBase *c, QColor *color) { void Tutorial1C::CellHouseKeeping(CellBase *c) { - double stiffness = 2; + double stiffness = 2; double* p_stiffness= &stiffness; c->LoopWallElements([c,p_stiffness](auto wallElementInfo){ wallElementInfo->getWallElement()->setStiffness(*p_stiffness); - (*p_stiffness)+=0.1; + (*p_stiffness)+=0; }); // add cell behavioral rules here c->EnlargeTargetArea(par->cell_expansion_rate); diff --git a/src/VirtualLeaf.pro b/src/VirtualLeaf.pro index 60c4866..863560b 100755 --- a/src/VirtualLeaf.pro +++ b/src/VirtualLeaf.pro @@ -1,8 +1,16 @@ TEMPLATE = subdirs -CONFIG+=ordered + +# Ensure we build in debug (no stripping, full symbols, zero optimization): +CONFIG += ordered debug +QMAKE_CXXFLAGS_DEBUG += -g -O0 + +# On Linux, generate a symbol table for backtrace_symbols() +QMAKE_LFLAGS += -rdynamic + +# C++ standard CONFIG += c++14 -SUBDIRS = \ -Library \ # relative paths -GUI \ -Models +SUBDIRS += \ + Library \ + GUI \ + Models From 91d34141057beb169eadd9fc3d01303a6f77d05f Mon Sep 17 00:00:00 2001 From: ARDATI-Rami Date: Wed, 11 Jun 2025 22:38:36 +0200 Subject: [PATCH 6/9] Add principal stress axis calculation and update simulation parameters: implement CalculatePrincipalStressAxis method, adjust XML parameters for simulation settings, and refine cell division type handling --- .idea/vcs.xml | 6 + data/leaves/cambium.xml | 14 +- data/leaves/lateralRoot.xml | 10669 +++++++++++++++---------------- data/leaves/model_exp_init.xml | 219 + data/leaves/tutorial1_init.xml | 32 +- data/leaves/vleaf2.xml | 2 +- run_in_batch.py | 120 + src/GUI/cell.cpp | 18 +- src/GUI/cell.h | 3 +- src/Library/cellbase.cpp | 85 + src/Library/cellbase.h | 1 + src/Models/Cambium/cambium.cpp | 2 +- virtualleaf_xml_model.py | 5 +- 13 files changed, 5691 insertions(+), 5485 deletions(-) create mode 100644 .idea/vcs.xml create mode 100755 data/leaves/model_exp_init.xml create mode 100644 run_in_batch.py diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/data/leaves/cambium.xml b/data/leaves/cambium.xml index c9e834a..10da674 100644 --- a/data/leaves/cambium.xml +++ b/data/leaves/cambium.xml @@ -7,7 +7,7 @@ - + @@ -106,7 +106,7 @@ - + @@ -161,7 +161,7 @@ - + @@ -1385,8 +1385,6 @@ - - @@ -1888,10 +1886,10 @@ - - + + - + diff --git a/data/leaves/lateralRoot.xml b/data/leaves/lateralRoot.xml index 48c0d1e..5f2d4d1 100644 --- a/data/leaves/lateralRoot.xml +++ b/data/leaves/lateralRoot.xml @@ -1,5448 +1,5227 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/leaves/model_exp_init.xml b/data/leaves/model_exp_init.xml new file mode 100755 index 0000000..57efadf --- /dev/null +++ b/data/leaves/model_exp_init.xml @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/leaves/tutorial1_init.xml b/data/leaves/tutorial1_init.xml index 324bfec..273b7e1 100755 --- a/data/leaves/tutorial1_init.xml +++ b/data/leaves/tutorial1_init.xml @@ -7,14 +7,15 @@ - + - - + + + @@ -36,6 +37,7 @@ + @@ -107,7 +109,7 @@ - + @@ -158,16 +160,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -209,7 +211,7 @@ - + diff --git a/data/leaves/vleaf2.xml b/data/leaves/vleaf2.xml index 2ab2820..4083020 100755 --- a/data/leaves/vleaf2.xml +++ b/data/leaves/vleaf2.xml @@ -107,7 +107,7 @@ - + diff --git a/run_in_batch.py b/run_in_batch.py new file mode 100644 index 0000000..6b28622 --- /dev/null +++ b/run_in_batch.py @@ -0,0 +1,120 @@ +import xml.etree.ElementTree as ET +from pathlib import Path +import subprocess +import numpy as np +import time + +class MyXML: + """Utility to clone a LeafML file and tweak simple entries.""" + + def __init__(self, templatefile: str): + self.tree = ET.parse(templatefile) + self.root = self.tree.getroot() + self.parameters = self.root.find("parameter") + + def set_simple_param(self, name: str, value) -> None: + """Change the ‘val’ attribute of .""" + par = self.parameters.find(f"./par[@name='{name}']") + if par is None: + raise KeyError(f"Parameter '{name}' not found in XML") + par.set("val", str(value)) + def set_setting(self, name: str, value) -> None: + """Change the 'val' attribute of .""" + settings = self.root.find("settings") + if settings is None: + raise KeyError("Settings section not found in XML") + + setting = settings.find(f"./setting[@name='{name}']") + if setting is None: + raise KeyError(f"Setting '{name}' not found in XML") + + # Convert boolean values to lowercase strings (true/false) + setting.set("val", str(value).lower() if isinstance(value, bool) else str(value)) + + def write(self, filename: str) -> None: + """Write a full XML document in UTF‑8.""" + # ① simply pass the *path* to ElementTree; it opens the file in 'wb' + self.tree.write(filename, encoding="utf-8", xml_declaration=True) + + +# ----------------------------------------------------------------------------- +simulation_start_time = time.time() +leaf_in = Path("data/leaves/cambium.xml") +model = "libcambium.so" +# Fixed expansion rate and different elastic modulus values +number_of_runs = np.arange(0,1) +for r in number_of_runs: + # Create unique output names + output_suffix = f"Test_if_stiffness_is_beign_passed_{r}" + datadir = f"/home/ardati/Data_VirtualLeaf/Cambium_{output_suffix}" + leaf_out = leaf_in.with_name(leaf_in.stem + output_suffix + ".xml") + + # Create and modify XML + xml = MyXML(leaf_in) + xml.set_simple_param("maxt", 5000) + xml.set_simple_param("datadir", datadir) + xml.set_simple_param("rseed", 1) #set seed to 1 for reproducibility + xml.set_simple_param("mc_stepsize", 0.2) + xml.set_simple_param("mc_cell_stepsize", 0.1) + xml.set_simple_param("compatibility_level", 1) + xml.set_setting("show_nodes", False) + xml.set_setting("show_node_numbers", False) + xml.set_setting("show_cell_numbers", False) + xml.set_setting("show_cell_centers", False) + + # Write XML file + xml.write(leaf_out) + + # Run simulation + print(f"Running simulation with number {r} and output {leaf_out}") + subprocess.run([ + "./bin/VirtualLeaf", + "-b", + "-l", str(leaf_out), + "-m", model + ], check=True) + + # here i want to ran this bash script in the same directory to animate the pngs + # Animate the PNGs generated in the simulation + animate_script = f"""#!/bin/bash + # Get directory name for the output file name + dir_name=$(basename "$(pwd)") + + # 1. Make numbered links + i=0 + for f in $(ls leaf.[0-9][0-9][0-9][0-9][0-9][0-9].png | sort); do + printf -v link "link_%06d.png" "$i" + ln -s "$f" "$link" + ((i++)) + done + + # 2. Encode + ffmpeg -framerate 25 -i link_%06d.png \\ + -c:v libx264 -crf 18 -preset slow \\ + -pix_fmt yuv420p -movflags +faststart \\ + "$dir_name.mp4" + + # 3. Clean up + rm link_*.png + """ + # Create the script file in the data directory + import os + + script_path = os.path.join(datadir, "animate.sh") + + # Write the script + with open(script_path, 'w') as f: + f.write(animate_script) + + # Make executable + os.chmod(script_path, 0o755) + + # Run the animation script in the data directory + print(f"Animating PNGs in {datadir}") + subprocess.run( + [script_path], + cwd=datadir, # Run in the data directory + check=True + ) + +print(f"This Simulation took {round((time.time() - simulation_start_time) / 60, 2)} minutes.") diff --git a/src/GUI/cell.cpp b/src/GUI/cell.cpp index 3de05e5..18758d5 100755 --- a/src/GUI/cell.cpp +++ b/src/GUI/cell.cpp @@ -2338,12 +2338,10 @@ Vector Cell::CalculateDivisionPlane() return div_vec; case MAX_STRESS_AXIS: { - // Calculate stress tensor for this cell - // Matrix stress = CalculateStressTensor(); - // Find eigenvector corresponding to maximum eigenvalue - // Vector max_stress_axis = stress.GetEigenvectorOfMaxEigenvalue(); - Vector max_stress_axis(0, 0, 0); // Properly initialize the vector - return max_stress_axis; + // Calculate principal stress axis for this cell + Vector max_stress_axis = CalculatePrincipalStressAxis(); + + return max_stress_axis; } case SHORT_AXIS: { @@ -2363,12 +2361,8 @@ Vector Cell::CalculateDivisionPlane() } case PERP_STRESS: { - // Calculate stress tensor for this cell - // Matrix stress = CalculateStressTensor(); - // // Find eigenvector corresponding to maximum eigenvalue - // Vector max_stress_axis = stress.GetEigenvectorOfMaxEigenvalue(); - // Return perpendicular vector - Vector max_stress_axis(0, 0, 0); // Properly initialize the vector + // Calculate principal stress axis and return its perpendicular + Vector max_stress_axis = CalculatePrincipalStressAxis(); return max_stress_axis.Perp2D(); } diff --git a/src/GUI/cell.h b/src/GUI/cell.h index 737292b..878ba3a 100755 --- a/src/GUI/cell.h +++ b/src/GUI/cell.h @@ -144,8 +144,7 @@ class Cell : public CellBase std::cout << "Cell " << index << ": Division type = PERP_STRESS" << std::endl; // Divide perpendicular to principal stress { - Vector stress_axis = CalculateDivisionPlane(); - Vector perpStressAxis = stress_axis.Perp2D(); + Vector perpStressAxis = CalculateDivisionPlane(); std::cout << "Cell " << index << ": Perpendicular stress axis = (" << perpStressAxis.x << ", " << perpStressAxis.y << ", " << perpStressAxis.z << ")" << std::endl; DivideOverAxis(perpStressAxis); } diff --git a/src/Library/cellbase.cpp b/src/Library/cellbase.cpp index 6001b08..a87705c 100755 --- a/src/Library/cellbase.cpp +++ b/src/Library/cellbase.cpp @@ -706,4 +706,89 @@ double CellBase::SetInitialArea(void) { InitialArea = this->CalcArea(); return InitialArea; } +Vector CellBase::CalculatePrincipalStressAxis() { + cout << "CalculatePrincipalStressAxis" << endl; // Calculate cell centroid + Vector centroid(0, 0, 0); + int n = nodes.size(); + for (auto it = nodes.begin(); it != nodes.end(); it++) { + centroid += Vector((*it)->x, (*it)->y, (*it)->z); + } + centroid = centroid * (1.0 / n); + + // Construct stress tensor + double stress_tensor[2][2] = {{0, 0}, {0, 0}}; + + // Calculate stress contribution from each wall + for (auto wall_it = walls.begin(); wall_it != walls.end(); ++wall_it) { + Wall* wall = *wall_it; + Vector wall_vec = Vector(wall->n2->x - wall->n1->x, wall->n2->y - wall->n1->y, wall->n2->z - wall->n1->z); + double wall_length = wall_vec.Norm(); + + if (wall_length > 0) { + // Normalize wall vector + wall_vec = wall_vec * (1.0 / wall_length); + + // Get wall tension (stress) + double wall_stiffness; + if (std::isnan(wall->c1WallStiffness)) { + wall_stiffness = std::max(wall->c1->GetWallStiffness(), wall->c2WallStiffness); + } else if (std::isnan(wall->c2WallStiffness)) { + wall_stiffness = std::max(wall->c2->GetWallStiffness(), wall->c1WallStiffness); + } else { + wall_stiffness = std::max(wall->c1WallStiffness, wall->c2WallStiffness); + } + double wall_length_original = wall_vec.Norm(); + double tension = wall_stiffness * (wall_length - wall_length_original) / wall_length_original; + // Add contribution to stress tensor (outer product) + stress_tensor[0][0] += tension * wall_vec.x * wall_vec.x; + stress_tensor[0][1] += tension * wall_vec.x * wall_vec.y; + stress_tensor[1][0] += tension * wall_vec.y * wall_vec.x; + stress_tensor[1][1] += tension * wall_vec.y * wall_vec.y; + } + } + + // Calculate eigenvalues and eigenvectors to find principal stress + double trace = stress_tensor[0][0] + stress_tensor[1][1]; + double det = stress_tensor[0][0] * stress_tensor[1][1] - stress_tensor[0][1] * stress_tensor[1][0]; + + // Eigenvalues + double lambda1 = (trace + sqrt(trace * trace - 4 * det)) / 2; + double lambda2 = (trace - sqrt(trace * trace - 4 * det)) / 2; + + // Eigenvector for the larger eigenvalue is the principal stress direction + Vector principal_stress; + if (fabs(lambda1) >= fabs(lambda2)) { + // Calculate eigenvector for lambda1 + if (fabs(stress_tensor[0][1]) > 1e-10) { + principal_stress = Vector(stress_tensor[0][1], lambda1 - stress_tensor[0][0], 0); + } else if (fabs(stress_tensor[1][0]) > 1e-10) { + principal_stress = Vector(lambda1 - stress_tensor[1][1], stress_tensor[1][0], 0); + } else { + // Diagonal matrix - eigenvectors are axis-aligned + principal_stress = (fabs(stress_tensor[0][0]) > fabs(stress_tensor[1][1])) ? + Vector(1, 0, 0) : Vector(0, 1, 0); + } + } else { + // Calculate eigenvector for lambda2 + if (fabs(stress_tensor[0][1]) > 1e-10) { + principal_stress = Vector(stress_tensor[0][1], lambda2 - stress_tensor[0][0], 0); + } else if (fabs(stress_tensor[1][0]) > 1e-10) { + principal_stress = Vector(lambda2 - stress_tensor[1][1], stress_tensor[1][0], 0); + } else { + // Diagonal matrix - eigenvectors are axis-aligned + principal_stress = (fabs(stress_tensor[0][0]) < fabs(stress_tensor[1][1])) ? + Vector(1, 0, 0) : Vector(0, 1, 0); + } + } + + // Normalize the principal stress vector + principal_stress.Normalise(); + + std::cout << "Cell " << index << ": Calculated principal stress axis = (" + << principal_stress.x << ", " << principal_stress.y << ", " + << principal_stress.z << ")" << std::endl; + + return principal_stress; +} + /* finis*/ diff --git a/src/Library/cellbase.h b/src/Library/cellbase.h index 401e596..3dc477b 100755 --- a/src/Library/cellbase.h +++ b/src/Library/cellbase.h @@ -263,6 +263,7 @@ class CellBase : public QObject, public Vector void SetDivisionType(DivisionType type) { division_type = type; } DivisionType GetDivisionType() const { return division_type; } DivisionType division_type; + virtual Vector CalculatePrincipalStressAxis(); QList getWalls(void) { QList wall_list; diff --git a/src/Models/Cambium/cambium.cpp b/src/Models/Cambium/cambium.cpp index 2c320c5..ac67b84 100755 --- a/src/Models/Cambium/cambium.cpp +++ b/src/Models/Cambium/cambium.cpp @@ -278,7 +278,7 @@ void cambium::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *d // } // } void cambium::CellHouseKeeping(CellBase *c) { - c->SetDivisionType(MAX_STRESS_AXIS); + c->SetDivisionType(PERP_STRESS); // Set initial area on first call to this function for each cell static std::set initialized_cells; if (initialized_cells.find(c->Index()) == initialized_cells.end()) { diff --git a/virtualleaf_xml_model.py b/virtualleaf_xml_model.py index 71f0d2b..5a6805f 100644 --- a/virtualleaf_xml_model.py +++ b/virtualleaf_xml_model.py @@ -196,7 +196,7 @@ class NodeSection: def __post_init__(self): self.nodes = [ Node( - nr=int(n.attrib["nr"]), + nr=int(n.attrib.get("nr", 0)), x=float(n.attrib["x"]), y=float(n.attrib["y"]), sam=_to_bool(n.attrib.get("sam")), @@ -232,6 +232,9 @@ def area(self) -> float: @property def cell_type(self) -> int: return int(self.attributes.get("cell_type", 0)) + @property + def target_area(self) -> float: + return float(self.attributes.get("target_area", 0.0)) @dataclass From cc68aee4a5c164d0c0eb77fa149f3622ea126179 Mon Sep 17 00:00:00 2001 From: ARDATI-Rami Date: Fri, 27 Jun 2025 17:15:02 +0200 Subject: [PATCH 7/9] Add lambda length getter and update cell division logic: implement GetLambdaLength method, adjust lambda length settings in CellHouseKeeping, and clean up commented code --- Change_XML.py => Example_of_change_XML.py | 0 src/Library/cellbase.h | 2 +- src/Models/Tutorial1A/tutorial1A.cpp | 3 +- src/Models/Tutorial1C/tutorial1C.cpp | 60 ++++++++++++++++++----- src/Models/Tutorial1C/tutorial1C.h | 3 +- 5 files changed, 52 insertions(+), 16 deletions(-) rename Change_XML.py => Example_of_change_XML.py (100%) diff --git a/Change_XML.py b/Example_of_change_XML.py similarity index 100% rename from Change_XML.py rename to Example_of_change_XML.py diff --git a/src/Library/cellbase.h b/src/Library/cellbase.h index 3dc477b..8a56cea 100755 --- a/src/Library/cellbase.h +++ b/src/Library/cellbase.h @@ -220,7 +220,7 @@ class CellBase : public QObject, public Vector inline void SetTargetLength(double tar_l) { target_length=tar_l; } inline void SetLambdaLength(double lambda_length) { lambda_celllength = lambda_length; } - + inline double GetLambdaLength(void) const { return lambda_celllength; } inline double TargetArea(void) { return target_area; } inline double EnlargeTargetArea(double da) { return target_area+=da; } diff --git a/src/Models/Tutorial1A/tutorial1A.cpp b/src/Models/Tutorial1A/tutorial1A.cpp index 03458e8..2e35040 100755 --- a/src/Models/Tutorial1A/tutorial1A.cpp +++ b/src/Models/Tutorial1A/tutorial1A.cpp @@ -56,7 +56,8 @@ void Tutorial1A::CellHouseKeeping(CellBase *c) { cout << "Cell base Area: " << c->BaseArea() << endl; cout << "Cell current Area: " << c->Area() << endl; cout << "Cell Target Area: " << c->TargetArea() << endl; - c->SetLambdaLength(100); + c->SetLambdaLength(1); + cout << "Cell lambda length: " << c->GetLambdaLength() << endl; c->EnlargeTargetArea(par->cell_expansion_rate); diff --git a/src/Models/Tutorial1C/tutorial1C.cpp b/src/Models/Tutorial1C/tutorial1C.cpp index b349e3a..60044a7 100755 --- a/src/Models/Tutorial1C/tutorial1C.cpp +++ b/src/Models/Tutorial1C/tutorial1C.cpp @@ -29,6 +29,8 @@ #include "cellbase.h" #include "tutorial1C.h" +#include "mesh.h" + static const std::string _module_id("$Id$"); QString Tutorial1C::ModelID(void) { @@ -43,6 +45,22 @@ int Tutorial1C::NChem(void) { return 0; } void Tutorial1C::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { // rules to be executed after cell division go here // (e.g., cell differentiation rules) + + // double stiffness = 2; + // double* p_stiffness= &stiffness; + // if (daughter1->AtBoundaryP()) { + // // Apply to both daughter cells + // daughter1->LoopWallElements([p_stiffness](auto wallElementInfo){ + // wallElementInfo->getWallElement()->setStiffness(*p_stiffness); + // (*p_stiffness)+=0.1; + // }); + // } + // if (daughter2->AtBoundaryP()) { + // daughter2->LoopWallElements([p_stiffness](auto wallElementInfo){ + // wallElementInfo->getWallElement()->setStiffness(*p_stiffness); + // (*p_stiffness)+=0.1; + // }); + // } } void Tutorial1C::SetCellColor(CellBase *c, QColor *color) { @@ -50,20 +68,38 @@ void Tutorial1C::SetCellColor(CellBase *c, QColor *color) { } void Tutorial1C::CellHouseKeeping(CellBase *c) { + c->SetDivisionType(SHORT_AXIS); + cout << "Cell " << c->Index() << " at boundary : " << c->AtBoundaryP() << endl; + // Count total cells in the tissue + // int totalCells = CountCells(); + // cout << "Cell " << c->Index() << " at boundary: " << c->AtBoundaryP() + // << ", Total cells: " << totalCells << endl; + // cout << "Cell lambda length: " << c->GetLambdaLength() << endl; + double lambda = 0.1; + double lambda_ext = 0.5; + // Only set high stiffness for boundary cells + if (c->AtBoundaryP()) { + c->SetLambdaLength(lambda_ext); + // double stiffness = 2; + // double* p_stiffness = &stiffness; + // + // c->LoopWallElements([p_stiffness](auto wallElementInfo){ + // wallElementInfo->getWallElement()->setStiffness(*p_stiffness); + // (*p_stiffness)+=0.1; + // }); + } else { + // Set uniform stiffness for non-boundary cells + c->SetLambdaLength(lambda); + // c->LoopWallElements([](auto wallElementInfo){ + // wallElementInfo->getWallElement()->setStiffness(1); + // }); + } - - double stiffness = 2; - double* p_stiffness= &stiffness; - - c->LoopWallElements([c,p_stiffness](auto wallElementInfo){ - wallElementInfo->getWallElement()->setStiffness(*p_stiffness); - (*p_stiffness)+=0; - }); // add cell behavioral rules here - c->EnlargeTargetArea(par->cell_expansion_rate); - if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) { - c->Divide(); - } + c->EnlargeTargetArea(par->cell_expansion_rate); + if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) { + c->Divide(); + } } void Tutorial1C::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { diff --git a/src/Models/Tutorial1C/tutorial1C.h b/src/Models/Tutorial1C/tutorial1C.h index 8596c48..098a784 100755 --- a/src/Models/Tutorial1C/tutorial1C.h +++ b/src/Models/Tutorial1C/tutorial1C.h @@ -31,10 +31,9 @@ class Tutorial1C : public QObject, SimPluginInterface { Q_OBJECT Q_INTERFACES(SimPluginInterface); Q_PLUGIN_METADATA(IID "org.virtualleaf.tutorial1c") - public: virtual QString ModelID(void); - + // Executed after the cellular mechanics steps have equillibrized virtual void CellHouseKeeping (CellBase *c); // Differential equations describing transport of chemicals from cell to cell From b45513374be3a714db153fedf1d56b9ba7decab9 Mon Sep 17 00:00:00 2001 From: ARDATI-Rami Date: Fri, 27 Jun 2025 18:16:57 +0200 Subject: [PATCH 8/9] Add XML configuration files for project setup: create misc.xml and workspace.xml with necessary project components and settings --- .idea/misc.xml | 10 + .idea/workspace.xml | 665 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 675 insertions(+) create mode 100644 .idea/misc.xml create mode 100644 .idea/workspace.xml diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..228bc9f --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..715b01f --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,665 @@ + + + + + + + { + "useNewFormat": true +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { + "lastFilter": { + "state": "OPEN", + "assignee": "ARDATI-Rami" + } +} + { + "selectedUrlAndAccountId": { + "url": "https://github.com/ARDATI-Rami/VirtualLeaf2021.git", + "accountId": "46d9b9c9-fed6-4371-9312-e4b72aadc5ea" + } +} + + + + + + + + + + + { + "associatedIndex": 4 +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PYTHONTEX + + + + + + + + + PDFLATEX + + + EVINCE + + + + false + + + {projectDir}/out + {projectDir}/auxil + false + PDF + TEXLIVE + false + [] + [] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MAKEINDEX + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1744026456349 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +