[SCM] Gerris Flow Solver branch, upstream, updated. b3aa46814a06c9cb2912790b23916ffb44f1f203

Stephane Popinet s.popinet at niwa.co.nz
Fri May 15 02:52:28 UTC 2009


The following commit has been merged in the upstream branch:
commit 5813f96206646b44681c9060113929bfc2fb03b4
Author: Stephane Popinet <s.popinet at niwa.co.nz>
Date:   Mon Aug 15 14:04:26 2005 +1000

    New functions gfs_domain_cell_traverse_condition, gfs_domain_cell_point_distance2
    
    And also ftt_cell_box. gfs_domain_cell_traverse_condition is used
    as a generic replacement for gfs_domain_cell_traverse_box.
    
    darcs-hash:20050815040426-fbd8f-36a9d5725c200c03a516a132fd28ac6caf0fc822.gz

diff --git a/src/domain.c b/src/domain.c
index ff0a08f..3b2cd19 100644
--- a/src/domain.c
+++ b/src/domain.c
@@ -807,6 +807,66 @@ void gfs_domain_cell_traverse_box (GfsDomain * domain,
 			 (GtsFunc) box_traverse_box, datum);
 }
 
+static void box_traverse_condition (GfsBox * box, gpointer * datum)
+{
+  FttTraverseType * order = datum[0];
+  FttTraverseFlags * flags = datum[1];
+  gint * max_depth = datum[2];
+  FttCellTraverseFunc func = (FttCellTraverseFunc) datum[3];
+  gpointer data = datum[4];
+  gboolean (* condition) (FttCell *, gpointer) = datum[5];
+  gpointer cdata = datum[6];
+
+  ftt_cell_traverse_condition (box->root, *order, *flags, *max_depth, func, data,
+			       condition, cdata);
+}
+
+/**
+ * gfs_domain_cell_traverse_condition:
+ * @domain: a #GfsDomain.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @max_depth: the maximum depth of the traversal. Cells below this
+ * depth will not be traversed. If @max_depth is -1 all cells in the
+ * tree are visited.
+ * @func: the function to call for each visited #FttCell.
+ * @data: user data to pass to @func.
+ * @condition: the condition.
+ * @cdata: user data to pass to @condition.
+ *
+ * Traverses the cell trees of @domain. Calls the given function for
+ * each cell visited.
+ *
+ * Traversal of any branch of the tree is stopped whenever @condition
+ * is not verified.
+ */
+void gfs_domain_cell_traverse_condition (GfsDomain * domain,
+					 FttTraverseType order,
+					 FttTraverseFlags flags,
+					 gint max_depth,
+					 FttCellTraverseFunc func,
+					 gpointer data,
+					 gboolean (* condition) (FttCell *, gpointer),
+					 gpointer cdata)
+{
+  gpointer datum[7];
+
+  datum[0] = &order;
+  datum[1] = &flags;
+  datum[2] = &max_depth;
+  datum[3] = func;
+  datum[4] = data;
+  datum[5] = condition;
+  datum[6] = cdata;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (func != NULL);
+  g_return_if_fail (condition != NULL);
+
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_traverse_condition, datum);
+}
+
 static void traverse_mixed (GfsBox * box, gpointer * datum)
 {
   FttCellTraverseFunc func = (FttCellTraverseFunc) datum[0];
@@ -1762,6 +1822,73 @@ FttCell * gfs_domain_locate (GfsDomain * domain,
   return cell;
 }
 
+static void box_distance2 (GfsBox * box, GPtrArray * a)
+{
+  g_ptr_array_add (a, box);
+}
+
+static void bubble_sort (GPtrArray * a, gdouble * d)
+{
+  guint i, j;
+
+  for (i = 0; i < a->len - 1; i++)
+    for (j = 0; j < a->len - 1 - i; j++)
+      if (d[j+1] < d[j]) {
+	gdouble tmp = d[j];
+	gpointer data = a->pdata[j];
+	d[j] = d[j+1];
+	d[j+1] = tmp;
+	a->pdata[j] = a->pdata[j+1];
+	a->pdata[j+1] = data;
+      }
+}
+
+/**
+ * gfs_domain_cell_point_distance2:
+ * @domain: a #GfsDomain.
+ * @p: a #GtsPoint.
+ * @distance2: the squared distance function.
+ * @data: user data to pass to @distance2.
+ * @closest: where to return the closest cell or %NULL.
+ *
+ * For non-leafs cells @distance2 must return a lower-bound for the
+ * minimum distance (using for example ftt_cell_point_distance2_min()).
+ *
+ * Returns: square of the minimum distance measured according to
+ * @distance2 between @p and a leaf cell of @domain.
+ */
+gdouble gfs_domain_cell_point_distance2 (GfsDomain * domain,
+					 GtsPoint * p,
+					 gdouble (* distance2) (FttCell *, GtsPoint *, gpointer),
+					 gpointer data,
+					 FttCell ** closest)
+{
+  gdouble dmin = G_MAXDOUBLE;
+  GPtrArray * a;
+  gdouble * d;
+  guint i;
+
+  g_return_val_if_fail (domain != NULL, dmin);
+  g_return_val_if_fail (p != NULL, dmin);
+  g_return_val_if_fail (distance2 != NULL, dmin);
+
+  if (closest)
+    *closest = NULL;
+  a = g_ptr_array_new ();
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_distance2, a);
+  d = g_malloc (sizeof (gdouble)*a->len);
+  for (i = 0; i < a->len; i++)
+    d[i] = (* distance2) (GFS_BOX (a->pdata[i])->root, p, data);
+  bubble_sort (a, d);
+  for (i = 0; i < a->len; i++)
+    if (d[i] < dmin)
+      ftt_cell_point_distance2_internal (GFS_BOX (a->pdata[i])->root, p, d[i],
+					 distance2, data, closest, &dmin);
+  g_free (d);
+  g_ptr_array_free (a, TRUE);
+  return dmin;
+}
+
 /**
  * gfs_domain_advect_point:
  * @domain: a #GfsDomain.
diff --git a/src/domain.h b/src/domain.h
index e9607f5..8003d6e 100644
--- a/src/domain.h
+++ b/src/domain.h
@@ -91,6 +91,14 @@ void         gfs_domain_cell_traverse         (GfsDomain * domain,
 					       gint max_depth,
 					       FttCellTraverseFunc func,
 					       gpointer data);
+void         gfs_domain_cell_traverse_condition (GfsDomain * domain,
+						 FttTraverseType order,
+						 FttTraverseFlags flags,
+						 gint max_depth,
+						 FttCellTraverseFunc func,
+						 gpointer data,
+						 gboolean (* condition) (FttCell *, gpointer),
+						 gpointer cdata);
 void         gfs_domain_cell_traverse_box     (GfsDomain * domain,
 					       GtsBBox * box,
 					       FttTraverseType order,
@@ -175,6 +183,13 @@ void         gfs_domain_split                 (GfsDomain * domain,
 FttCell *    gfs_domain_locate                (GfsDomain * domain,
 					       FttVector target,
 					       gint max_depth);
+gdouble      gfs_domain_cell_point_distance2  (GfsDomain * domain,
+					       GtsPoint * p,
+					       gdouble (* distance2) (FttCell *, 
+								      GtsPoint *, 
+								      gpointer),
+					       gpointer data,
+					       FttCell ** closest);
 void         gfs_domain_advect_point          (GfsDomain * domain, 
 					       GtsPoint * p,
 					       gdouble dt);
diff --git a/src/fluid.c b/src/fluid.c
index fcb2194..79b0e2e 100644
--- a/src/fluid.c
+++ b/src/fluid.c
@@ -1833,23 +1833,11 @@ GtsSurface * gfs_cell_is_cut (FttCell * cell, GtsSurface * s)
   GtsSurface * s1 = NULL;
   gpointer data[2];
   GtsBBox bb;
-  FttVector p;
-  gdouble h;
 
   g_return_val_if_fail (cell != NULL, NULL);
   g_return_val_if_fail (s != NULL, NULL);
 
-  h = ftt_cell_size (cell)/1.99999;
-  ftt_cell_pos (cell, &p);
-  bb.x1 = p.x - h; bb.y1 = p.y - h;
-  bb.x2 = p.x + h; bb.y2 = p.y + h; 
-#if FTT_2D
-  bb.z1 = bb.z2 = 0.;
-#elif FTT_2D3
-  bb.z1 = p.z - 1./1.99999; bb.z2 = p.z + 1./1.99999;
-#else  /* 3D */
-  bb.z1 = p.z - h; bb.z2 = p.z + h;
-#endif /* 3D */
+  ftt_cell_bbox (cell, &bb);
   data[0] = &bb;
   data[1] = &s1;
   gts_surface_foreach_face (s, (GtsFunc) face_overlaps_box, data);
diff --git a/src/ftt.c b/src/ftt.c
index cccd3c3..916af1f 100644
--- a/src/ftt.c
+++ b/src/ftt.c
@@ -1370,6 +1370,135 @@ void ftt_cell_traverse (FttCell * root,
   }
 }
 
+/**
+ * ftt_cell_traverse_condition:
+ * @root: the root #FttCell of the tree to traverse.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @max_depth: the maximum depth of the traversal. Cells below this
+ * depth will not be traversed. If @max_depth is -1 all cells in the
+ * tree are visited.
+ * @func: the function to call for each visited #FttCell.
+ * @data: user data to pass to @func.
+ * @condition: the condition.
+ * @cdata: user data to pass to @condition.
+ *
+ * Traverses a cell tree starting at the given root #FttCell. Calls
+ * the given function for each cell visited.
+ *
+ * Traversal of any branch of the tree is stopped whenever @condition
+ * is not verified.
+ */
+void ftt_cell_traverse_condition (FttCell * root,
+				  FttTraverseType order,
+				  FttTraverseFlags flags,
+				  gint max_depth,
+				  FttCellTraverseFunc func,
+				  gpointer data,
+				  gboolean (* condition) (FttCell *, gpointer),
+				  gpointer cdata)
+{
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (func != NULL);
+  g_return_if_fail (condition != NULL);
+
+  if ((max_depth >= 0 && ftt_cell_level (root) > max_depth) ||
+      !(* condition) (root, cdata))
+    return;
+
+  if (order == FTT_PRE_ORDER &&
+      (flags == FTT_TRAVERSE_ALL ||
+       ((flags & FTT_TRAVERSE_LEAFS) != 0 && FTT_CELL_IS_LEAF (root)) ||
+       ((flags & FTT_TRAVERSE_NON_LEAFS) != 0 && !FTT_CELL_IS_LEAF (root))))
+    (* func) (root, data);
+  if (!FTT_CELL_IS_LEAF (root)) {
+    struct _FttOct * children = root->children;
+    guint n;
+
+    for (n = 0; n < FTT_CELLS; n++) {
+      FttCell * c = &(children->cell[n]);
+
+      if (!FTT_CELL_IS_DESTROYED (c))
+	ftt_cell_traverse_condition (c, order, flags, max_depth, func, data, condition, cdata);
+    }
+  }
+  if (order == FTT_POST_ORDER &&
+      (flags == FTT_TRAVERSE_ALL ||
+       ((flags & FTT_TRAVERSE_LEAFS) != 0 && FTT_CELL_IS_LEAF (root)) ||
+       ((flags & FTT_TRAVERSE_NON_LEAFS) != 0 && !FTT_CELL_IS_LEAF (root))))
+    (* func) (root, data);
+}
+
+/**
+ * ftt_cell_bbox:
+ * @cell: a #FttCell.
+ * @bb: a #GtsBBox.
+ *
+ * Fills @bb with the bounding box of @cell.
+ */
+void ftt_cell_bbox (const FttCell * cell, GtsBBox * bb)
+{
+  FttVector p;
+  gdouble h;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (bb != NULL);
+  
+  h = ftt_cell_size (cell)/1.99999;
+  ftt_cell_pos (cell, &p);
+  bb->x1 = p.x - h; bb->y1 = p.y - h;
+  bb->x2 = p.x + h; bb->y2 = p.y + h; 
+#if FTT_2D
+  bb->z1 = bb->z2 = 0.;
+#elif FTT_2D3
+  bb->z1 = p.z - 1./1.99999; bb->z2 = p.z + 1./1.99999;
+#else  /* 3D */
+  bb->z1 = p.z - h; bb->z2 = p.z + h;
+#endif /* 3D */
+}
+
+static gboolean cell_is_in_box (FttCell * cell, gpointer data)
+{
+  GtsBBox * box = data;
+  GtsBBox bb;
+
+  ftt_cell_bbox (cell, &bb);
+  return gts_bboxes_are_overlapping (&bb, box);
+}
+
+/**
+ * ftt_cell_traverse_box:
+ * @root: the root #FttCell of the tree to traverse.
+ * @box: a #GtsBBox.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @max_depth: the maximum depth of the traversal. Cells below this
+ * depth will not be traversed. If @max_depth is -1 all cells in the
+ * tree are visited.
+ * @func: the function to call for each visited #FttCell.
+ * @data: user data to pass to @func.
+ *
+ * Traverses a cell tree starting at the given root #FttCell. Calls
+ * the given function for each cell visited. Only the cells partly or
+ * totally contained within @box are visited.  
+ */
+void ftt_cell_traverse_box (FttCell * root,
+			    GtsBBox * box,
+			    FttTraverseType order,
+			    FttTraverseFlags flags,
+			    gint max_depth,
+			    FttCellTraverseFunc func,
+			    gpointer data)
+{
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (box != NULL);
+  g_return_if_fail (func != NULL);
+
+  ftt_cell_traverse_condition (root, order, flags, max_depth, func, data, cell_is_in_box, box);
+}
+
 static void cell_traverse_boundary_pre_order_all (FttCell * cell,
 						  FttDirection d,
 						  gint max_depth,
@@ -1885,6 +2014,117 @@ FttCell * ftt_cell_locate (FttCell * root,
   return NULL;
 }
 
+static void bubble_sort (FttCellChildren * child, gdouble * d)
+{
+  guint i, j;
+
+  for (i = 0; i < FTT_CELLS - 1; i++)
+    for (j = 0; j < FTT_CELLS - 1 - i; j++)
+      if (d[j+1] < d[j]) {
+	gdouble tmp = d[j];
+	FttCell * cell = child->c[j];
+	d[j] = d[j+1];
+	d[j+1] = tmp;
+	child->c[j] = child->c[j+1];
+	child->c[j+1] = cell;
+      }
+}
+
+/**
+ * ftt_cell_point_distance2_min:
+ * @cell: a #FttCell.
+ * @p: a #GtsPoint.
+ * 
+ * Returns: the square of the minimum distance between @cell and @p.
+ */
+gdouble ftt_cell_point_distance2_min (FttCell * cell, GtsPoint * p)
+{
+  GtsBBox bb;
+  gdouble dmin, xd1, xd2, yd1, yd2, zd1, zd2;
+    
+  g_return_val_if_fail (cell != NULL, G_MAXDOUBLE);
+  g_return_val_if_fail (p != NULL, G_MAXDOUBLE);
+
+  ftt_cell_bbox (cell, &bb);
+
+  xd1 = (bb.x1 - p->x)*(bb.x1 - p->x);
+  xd2 = (p->x - bb.x2)*(p->x - bb.x2);
+  yd1 = (bb.y1 - p->y)*(bb.y1 - p->y);
+  yd2 = (p->y - bb.y2)*(p->y - bb.y2);
+  zd1 = (bb.z1 - p->z)*(bb.z1 - p->z);
+  zd2 = (p->z - bb.z2)*(p->z - bb.z2);
+  
+  dmin = p->x < bb.x1 ? xd1 : p->x > bb.x2 ? xd2 : 0.0;
+  dmin += p->y < bb.y1 ? yd1 : p->y > bb.y2 ? yd2 : 0.0;
+  dmin += p->z < bb.z1 ? zd1 : p->z > bb.z2 ? zd2 : 0.0;
+
+  return dmin;
+}
+
+void ftt_cell_point_distance2_internal (FttCell * root,
+					GtsPoint * p,
+					gdouble d,
+					gdouble (* distance2) (FttCell *, GtsPoint *, gpointer),
+					gpointer data,
+					FttCell ** closest,
+					gdouble * dmin)
+{
+  if (FTT_CELL_IS_LEAF (root)) {
+    if (d < *dmin) {
+      *dmin = d;
+      if (closest)
+	*closest = root;
+    }
+  }
+  else {
+    FttCellChildren child;
+    gdouble dc[FTT_CELLS];
+    guint i;
+
+    ftt_cell_children (root, &child);
+    for (i = 0; i < FTT_CELLS; i++)
+      dc[i] = child.c[i] ? (* distance2) (child.c[i], p, data) : G_MAXDOUBLE;
+    bubble_sort (&child, dc);
+    for (i = 0; i < FTT_CELLS; i++)
+      if (dc[i] < *dmin)
+	ftt_cell_point_distance2_internal (child.c[i], p, dc[i], distance2, data, closest, dmin);
+  }
+}
+
+/**
+ * ftt_cell_point_distance2:
+ * @root: a #FttCell.
+ * @p: a #GtsPoint.
+ * @distance2: the squared distance function.
+ * @data: user data to pass to @distance2.
+ * @closest: where to return the closest cell or %NULL.
+ *
+ * For non-leafs cells @distance2 must return a lower-bound for the
+ * minimum distance (using for example ftt_cell_point_distance2_min()).
+ *
+ * Returns: the square of the minimum distance measured according to
+ * @distance2 between @p and a leaf cell of @root.
+ */
+gdouble ftt_cell_point_distance2 (FttCell * root,
+				  GtsPoint * p,
+				  gdouble (* distance2) (FttCell *, GtsPoint *, gpointer),
+				  gpointer data,
+				  FttCell ** closest)
+{
+  gdouble d, dmin = G_MAXDOUBLE;
+
+  g_return_val_if_fail (root != NULL, dmin);
+  g_return_val_if_fail (p != NULL, dmin);
+  g_return_val_if_fail (distance2 != NULL, dmin);
+
+  if (closest)
+    *closest = NULL;
+  d = (* distance2) (root, p, data);
+  if (d < dmin)
+    ftt_cell_point_distance2_internal (root, p, d, distance2, data, closest, &dmin);
+  return dmin;
+}
+
 /**
  * ftt_cell_depth:
  * @root: a #FttCell.
@@ -2468,289 +2708,6 @@ void ftt_face_traverse_boundary (FttCell * root,
 			      datum);
 }
 
-static gboolean cell_is_in_box (FttCell * cell, GtsBBox * box)
-{
-  FttVector p;
-  gdouble h = ftt_cell_size (cell)/2.;
-  GtsBBox bb;
-
-  ftt_cell_pos (cell, &p);
-  bb.x1 = p.x - h;
-  bb.y1 = p.y - h;
-  bb.x2 = p.x + h;
-  bb.y2 = p.y + h;
-#if FTT_2D
-  bb.z1 = bb.z2 = 0.;
-#else /* 3D */
-  bb.z1 = p.z - h;
-  bb.z2 = p.z + h;
-#endif /* 3D */
-  return gts_bboxes_are_overlapping (&bb, box);
-}
-
-static void cell_traverse_box_pre_order_all (FttCell * cell, 
-					     GtsBBox * box,
-					     gint max_depth,
-					     FttCellTraverseFunc func,
-					     gpointer data)
-{
-  FttCell * parent;
-
-  if ((max_depth >= 0 && ftt_cell_level (cell) > max_depth) ||
-      !cell_is_in_box (cell, box))
-    return;
-
-  parent = ftt_cell_parent (cell);
-  (* func) (cell, data);
-  /* check that cell has not been deallocated by @func */
-  g_assert (parent == NULL || parent->children != NULL);
-
-  if (!FTT_CELL_IS_LEAF (cell)) {
-    FttOct * children = cell->children;
-    guint n;
-
-    for (n = 0; n < FTT_CELLS; n++) {
-      FttCell * c = &(children->cell[n]);
-
-      if (!FTT_CELL_IS_DESTROYED (c))
-	cell_traverse_box_pre_order_all (c, box, max_depth, func, data);
-    }
-  }
-}
-
-static void cell_traverse_box_post_order_all (FttCell * cell, 
-					      GtsBBox * box,
-					      gint max_depth,
-					      FttCellTraverseFunc func,
-					      gpointer data)
-{
-  if ((max_depth >= 0 && ftt_cell_level (cell) > max_depth) ||
-      !cell_is_in_box (cell, box))
-    return;
-
-  if (!FTT_CELL_IS_LEAF (cell)) {
-    FttOct * children = cell->children;
-    guint n;
-
-    for (n = 0; n < FTT_CELLS; n++) {
-      FttCell * c = &(children->cell[n]);
-
-      if (!FTT_CELL_IS_DESTROYED (c))
-	cell_traverse_box_post_order_all (c, box, max_depth, func, data);
-    }
-  }
-
-  (* func) (cell, data);
-}
-
-static void cell_traverse_box_leafs (FttCell * cell, 
-				     GtsBBox * box,
-				     gint max_depth,
-				     FttCellTraverseFunc func,
-				     gpointer data)
-{
-  if ((max_depth >= 0 && ftt_cell_level (cell) > max_depth) ||
-      !cell_is_in_box (cell, box))
-    return;
-
-  if (FTT_CELL_IS_LEAF (cell))
-    (* func) (cell, data);
-  else {
-    FttOct * children = cell->children;
-    guint n;
-
-    for (n = 0; n < FTT_CELLS; n++) {
-      FttCell * c = &(children->cell[n]);
-
-      if (!FTT_CELL_IS_DESTROYED (c))
-	cell_traverse_box_leafs (c, box, max_depth, func, data);
-    }
-  }
-}
-
-static void cell_traverse_box_pre_order_nonleafs (FttCell * cell, 
-						  GtsBBox * box,
-						  gint max_depth,
-						  FttCellTraverseFunc func,
-						  gpointer data)
-{
-  if ((max_depth >= 0 && ftt_cell_level (cell) > max_depth) ||
-      !cell_is_in_box (cell, box))
-    return;
-
-  if (!FTT_CELL_IS_LEAF (cell)) {
-    FttCell *  parent = ftt_cell_parent (cell);
-
-    (* func) (cell, data);
-    /* check that cell has not been deallocated by @func */
-    g_assert (parent == NULL || parent->children != NULL);
-    if (!FTT_CELL_IS_LEAF (cell)) {
-      FttOct * children = cell->children;
-      guint n;
-      
-      for (n = 0; n < FTT_CELLS; n++) {
-	FttCell * c = &(children->cell[n]);
-	
-	if (!FTT_CELL_IS_DESTROYED (c))
-	  cell_traverse_box_pre_order_nonleafs (c, box, max_depth, func, data);
-      }
-    }
-  }
-}
-
-static void cell_traverse_box_post_order_nonleafs (FttCell * cell, 
-						   GtsBBox * box,
-						   gint max_depth,
-						   FttCellTraverseFunc func,
-						   gpointer data)
-{
-  if ((max_depth >= 0 && ftt_cell_level (cell) > max_depth) ||
-      !cell_is_in_box (cell, box))
-    return;
-
-  if (!FTT_CELL_IS_LEAF (cell)) {
-    FttOct * children = cell->children;
-    guint n;
-
-    for (n = 0; n < FTT_CELLS; n++) {
-      FttCell * c = &(children->cell[n]);
-
-      if (!FTT_CELL_IS_DESTROYED (c))
-	cell_traverse_box_post_order_nonleafs (c, box, max_depth, func, data);
-    }
-
-    (* func) (cell, data);
-  }
-}
-
-static void cell_traverse_box_level (FttCell * cell, 
-				     GtsBBox * box,
-				     gint max_depth,
-				     FttCellTraverseFunc func,
-				     gpointer data)
-{
-  if (!cell_is_in_box (cell, box))
-    return;
-  if (ftt_cell_level (cell) == max_depth)
-    (* func) (cell, data);
-  else if (!FTT_CELL_IS_LEAF (cell)) {
-    FttOct * children = cell->children;
-    guint n;
-
-    for (n = 0; n < FTT_CELLS; n++) {
-      FttCell * c = &(children->cell[n]);
-
-      if (!FTT_CELL_IS_DESTROYED (c))
-	cell_traverse_box_level (c, box, max_depth, func, data);
-    }
-  }
-}
-
-static void cell_traverse_box_level_leafs (FttCell * cell, 
-					   GtsBBox * box,
-					   gint max_depth,
-					   FttCellTraverseFunc func,
-					   gpointer data)
-{
-  if (!cell_is_in_box (cell, box))
-    return;
-  if (ftt_cell_level (cell) == max_depth || FTT_CELL_IS_LEAF (cell))
-    (* func) (cell, data);
-  else if (!FTT_CELL_IS_LEAF (cell)) {
-    FttOct * children = cell->children;
-    guint n;
-
-    for (n = 0; n < FTT_CELLS; n++) {
-      FttCell * c = &(children->cell[n]);
-
-      if (!FTT_CELL_IS_DESTROYED (c))
-	cell_traverse_box_level_leafs (c, box, max_depth, func, data);
-    }
-  }
-}
-
-static void cell_traverse_box_level_non_leafs (FttCell * cell, 
-					       GtsBBox * box,
-					       gint max_depth,
-					       FttCellTraverseFunc func,
-					       gpointer data)
-{
-  if (!cell_is_in_box (cell, box))
-    return;
-  if (ftt_cell_level (cell) == max_depth && !FTT_CELL_IS_LEAF (cell))
-    (* func) (cell, data);
-  else if (!FTT_CELL_IS_LEAF (cell)) {
-    FttOct * children = cell->children;
-    guint n;
-
-    for (n = 0; n < FTT_CELLS; n++) {
-      FttCell * c = &(children->cell[n]);
-
-      if (!FTT_CELL_IS_DESTROYED (c))
-	cell_traverse_box_level_non_leafs (c, box, max_depth, func, data);
-    }
-  }
-}
-
-/**
- * ftt_cell_traverse_box:
- * @root: the root #FttCell of the tree to traverse.
- * @box: a #GtsBBox.
- * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
- * %FTT_POST_ORDER. 
- * @flags: which types of children are to be visited.
- * @max_depth: the maximum depth of the traversal. Cells below this
- * depth will not be traversed. If @max_depth is -1 all cells in the
- * tree are visited.
- * @func: the function to call for each visited #FttCell.
- * @data: user data to pass to @func.
- *
- * Traverses a cell tree starting at the given root #FttCell. Calls
- * the given function for each cell visited. Only the cells partly or
- * totally contained within @box are visited.  
- */
-void ftt_cell_traverse_box (FttCell * root,
-			    GtsBBox * box,
-			    FttTraverseType order,
-			    FttTraverseFlags flags,
-			    gint max_depth,
-			    FttCellTraverseFunc func,
-			    gpointer data)
-{
-  g_return_if_fail (root != NULL);
-  g_return_if_fail (box != NULL);
-  g_return_if_fail (func != NULL);
-
-  if ((max_depth >= 0 && ftt_cell_level (root) > max_depth) ||
-      !cell_is_in_box (root, box))
-    return;
-
-  if (flags == FTT_TRAVERSE_ALL) {
-    if (order == FTT_PRE_ORDER)
-      cell_traverse_box_pre_order_all (root, box, max_depth, func, data);
-    else
-      cell_traverse_box_post_order_all (root, box, max_depth, func, data);
-  }
-  else if ((flags & FTT_TRAVERSE_LEVEL) != 0) {
-    if ((flags & FTT_TRAVERSE_LEAFS) != 0)
-      cell_traverse_box_level_leafs (root, box, max_depth, func, data);
-    else if ((flags & FTT_TRAVERSE_NON_LEAFS) != 0)
-      cell_traverse_box_level_non_leafs (root, box, max_depth, func, data);
-    else
-      cell_traverse_box_level (root, box, max_depth, func, data);
-  }
-  else if ((flags & FTT_TRAVERSE_LEAFS) != 0)
-    cell_traverse_box_leafs (root, box, max_depth, func, data);
-  else {
-    g_return_if_fail ((flags & FTT_TRAVERSE_NON_LEAFS) != 0);
-
-    if (order == FTT_PRE_ORDER)
-      cell_traverse_box_pre_order_nonleafs (root, box, max_depth, func, data);
-    else
-      cell_traverse_box_post_order_nonleafs (root, box, max_depth, func, data);
-  }
-}
-
 /**
  * ftt_cell_coarsen:
  * @root: a #FttCell root of a cell tree to coarsen.
diff --git a/src/ftt.h b/src/ftt.h
index bef9cef..93a6402 100644
--- a/src/ftt.h
+++ b/src/ftt.h
@@ -671,6 +671,15 @@ void                 ftt_cell_traverse               (FttCell * root,
 						      gint max_depth,
 						      FttCellTraverseFunc func,
 						      gpointer data);
+void                 ftt_cell_traverse_condition     (FttCell * root,
+						      FttTraverseType order,
+						      FttTraverseFlags flags,
+						      gint max_depth,
+						      FttCellTraverseFunc func,
+						      gpointer data,
+						      gboolean (* condition) (FttCell *, 
+									      gpointer),
+						      gpointer cdata);
 void                 ftt_cell_traverse_box           (FttCell * root,
 						      GtsBBox * box,
 						      FttTraverseType order,
@@ -704,6 +713,26 @@ void                 ftt_face_traverse_boundary      (FttCell * root,
 FttCell *            ftt_cell_locate                 (FttCell * root,
 						      FttVector target,
 						      gint max_depth);
+gdouble              ftt_cell_point_distance2_min    (FttCell * cell, 
+						      GtsPoint * p);
+void                 ftt_cell_point_distance2_internal (FttCell * root,
+							GtsPoint * p,
+							gdouble d,
+							gdouble (* distance2) (FttCell *, 
+									       GtsPoint *, 
+									       gpointer),
+							gpointer data,
+							FttCell ** closest,
+							gdouble * dmin);
+gdouble              ftt_cell_point_distance2        (FttCell * root,
+						      GtsPoint * p,
+						      gdouble (* distance2) (FttCell *, 
+									     GtsPoint *, 
+									     gpointer),
+						      gpointer data,
+						      FttCell ** closest);
+void                 ftt_cell_bbox                   (const FttCell * cell, 
+						      GtsBBox * bb);
 typedef void      (* FttCellCopyFunc)                (const FttCell * from,
 						      FttCell * to,
 						      gpointer data);

-- 
Gerris Flow Solver



More information about the debian-science-commits mailing list