[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] = ℴ
+ 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