summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 5464192)
raw | patch | inline | side by side (parent: 5464192)
author | buliabyak <buliabyak@users.sourceforge.net> | |
Fri, 9 Nov 2007 06:16:01 +0000 (06:16 +0000) | ||
committer | buliabyak <buliabyak@users.sourceforge.net> | |
Fri, 9 Nov 2007 06:16:01 +0000 (06:16 +0000) |
src/livarot/Shape.h | patch | blob | history | |
src/livarot/ShapeMisc.cpp | patch | blob | history | |
src/tweak-context.cpp | patch | blob | history |
diff --git a/src/livarot/Shape.h b/src/livarot/Shape.h
index 3c7010bbe97e714922e49b357eebfefac66958d3..d1ba63a54d09dcf18f8dec6cdcdc98a23a6374f8 100644 (file)
--- a/src/livarot/Shape.h
+++ b/src/livarot/Shape.h
struct SweepTreeList;
struct SweepEventQueue;
+enum {
+ tweak_mode_grow,
+ tweak_mode_push,
+ tweak_mode_repel,
+ tweak_mode_roughen
+};
+
/*
* the Shape class (was the Digraph class, as the header says) stores digraphs (no kidding!) of which
* a very interesting kind are polygons.
// the result is NOT a polygon; you need a subsequent call to ConvertToShape to get a real polygon
int MakeOffset(Shape *of, double dec, JoinType join, double miter, bool do_profile=false, double cx = 0, double cy = 0, double radius = 0, NR::Matrix *i2doc = NULL);
- int MakeRepel(Shape *of, double dec, JoinType join, double miter, bool do_profile=false, double cx = 0, double cy = 0, double radius = 0, NR::Matrix *i2doc = NULL);
-
- int MakePush (Shape * a, JoinType join, double miter, bool do_profile, NR::Point c, NR::Point vector, double radius, NR::Matrix *i2doc = NULL);
-
- int MakeJitter (Shape * a, JoinType join, double miter, bool do_profile, NR::Point c, double power, double radius, NR::Matrix *i2doc = NULL);
+ int MakeTweak (int mode, Shape *a, double dec, JoinType join, double miter, bool do_profile, NR::Point c, NR::Point vector, double radius, NR::Matrix *i2doc);
int PtWinding(const NR::Point px) const; // plus rapide
int Winding(const NR::Point px) const;
index 199457a0b86aa91f35c1e488be9b2ccefee4b953..ac59d0544f1eb45505756b85a9e94b6f02bd1707 100644 (file)
@@ -522,20 +522,23 @@ Shape::ConvertToFormeNested (Path * dest, int nbP, Path * *orig, int wildPath,in
MakeSweepDestData (false);
}
-// offsets
-// take each edge, offset it, and make joins with previous at edge start and next at edge end (previous and
-// next being with respect to the clockwise order)
-// you gotta be very careful with the join, as anything but the right one will fuck everything up
-// see PathStroke.cpp for the "right" joins
+
int
-Shape::MakeOffset (Shape * a, double dec, JoinType join, double miter, bool do_profile, double cx, double cy, double radius, NR::Matrix *i2doc)
+Shape::MakeTweak (int mode, Shape *a, double dec, JoinType join, double miter, bool do_profile, NR::Point c, NR::Point vector, double radius, NR::Matrix *i2doc)
{
Reset (0, 0);
MakeBackData(a->_has_back_data);
bool done_something = false;
+
+ double power;
+ if (mode == tweak_mode_push) {
+ power = NR::L2(vector);
+ } else {
+ power = dec;
+ }
- if (dec == 0)
+ if (power == 0)
{
_pts = a->_pts;
if (numberOfPoints() > maxPt)
@@ -553,7 +556,7 @@ Shape::MakeOffset (Shape * a, double dec, JoinType join, double miter, bool do_p
{
maxAr = numberOfEdges();
if (_has_edges_data)
- eData.resize(maxAr);
+ eData.resize(maxAr);
if (_has_sweep_src_data)
swsData.resize(maxAr);
if (_has_sweep_dest_data)
@@ -575,17 +578,13 @@ Shape::MakeOffset (Shape * a, double dec, JoinType join, double miter, bool do_p
for (int i = 0; i < a->numberOfEdges(); i++)
{
- // int stP=a->swsData[i].stPt/*,enP=a->swsData[i].enPt*/;
int stB = -1, enB = -1;
- if (dec > 0)
- {
- stB = a->CycleNextAt (a->getEdge(i).st, i);
- enB = a->CyclePrevAt (a->getEdge(i).en, i);
- }
- else
- {
+ if (power <= 0 || mode == tweak_mode_push || mode == tweak_mode_repel || mode == tweak_mode_roughen) {
stB = a->CyclePrevAt (a->getEdge(i).st, i);
enB = a->CycleNextAt (a->getEdge(i).en, i);
+ } else {
+ stB = a->CycleNextAt (a->getEdge(i).st, i);
+ enB = a->CyclePrevAt (a->getEdge(i).en, i);
}
NR::Point stD, seD, enD;
@@ -605,24 +604,54 @@ Shape::MakeOffset (Shape * a, double dec, JoinType join, double miter, bool do_p
int stNo, enNo;
ptP = a->getPoint(a->getEdge(i).st).x;
- double this_dec;
+ if (mode == tweak_mode_push) {
+ power = 1;
+ }
+
+ NR::Point to_center = ptP * (*i2doc) - c;
+ NR::Point to_center_normalized = (1/NR::L2(to_center)) * to_center;
+
+ double this_power;
if (do_profile && i2doc) {
double alpha = 1;
- double x = (NR::L2(ptP * (*i2doc) - NR::Point(cx,cy))/radius);
+ double x;
+ if (mode == tweak_mode_repel) {
+ x = (NR::L2(to_center)/radius);
+ } else {
+ x = (NR::L2(ptP * (*i2doc) - c)/radius);
+ }
if (x > 1) {
- this_dec = 0;
+ this_power = 0;
} else if (x <= 0) {
- this_dec = dec;
+ if (mode == tweak_mode_repel) {
+ this_power = 0;
+ } else {
+ this_power = power;
+ }
} else {
- this_dec = dec * (0.5 * cos (M_PI * (pow(x, alpha))) + 0.5);
+ this_power = power * (0.5 * cos (M_PI * (pow(x, alpha))) + 0.5);
}
} else {
- this_dec = dec;
+ if (mode == tweak_mode_repel) {
+ this_power = 0;
+ } else {
+ this_power = power;
+ }
}
- if (this_dec != 0)
+ if (this_power != 0)
done_something = true;
+ NR::Point this_vec(0,0);
+ if (mode == tweak_mode_push) {
+ this_vec = this_power * vector;
+ } else if (mode == tweak_mode_repel) {
+ this_vec = this_power * to_center_normalized;
+ } else if (mode == tweak_mode_roughen) {
+ double angle = g_random_double_range(0, 2*M_PI);
+ this_vec = g_random_double_range(0, 1) * this_power * NR::Point(sin(angle), cos(angle));
+ }
+
int usePathID=-1;
int usePieceID=0;
double useT=0.0;
@@ -638,23 +667,28 @@ Shape::MakeOffset (Shape * a, double dec, JoinType join, double miter, bool do_p
useT=0;
}
}
- if (dec > 0)
- {
- Path::DoRightJoin (this, this_dec, join, ptP, stD, seD, miter, stL, seL,
- stNo, enNo,usePathID,usePieceID,useT);
- a->swsData[i].stPt = enNo;
- a->swsData[stB].enPt = stNo;
- }
- else
- {
- Path::DoLeftJoin (this, -this_dec, join, ptP, stD, seD, miter, stL, seL,
- stNo, enNo,usePathID,usePieceID,useT);
- a->swsData[i].stPt = enNo;
- a->swsData[stB].enPt = stNo;
- }
+
+ if (mode == tweak_mode_push || mode == tweak_mode_repel || mode == tweak_mode_roughen) {
+ Path::DoLeftJoin (this, 0, join, ptP+this_vec, stD+this_vec, seD+this_vec, miter, stL, seL,
+ stNo, enNo,usePathID,usePieceID,useT);
+ a->swsData[i].stPt = enNo;
+ a->swsData[stB].enPt = stNo;
+ } else {
+ if (power > 0) {
+ Path::DoRightJoin (this, this_power, join, ptP, stD, seD, miter, stL, seL,
+ stNo, enNo,usePathID,usePieceID,useT);
+ a->swsData[i].stPt = enNo;
+ a->swsData[stB].enPt = stNo;
+ } else {
+ Path::DoLeftJoin (this, -this_power, join, ptP, stD, seD, miter, stL, seL,
+ stNo, enNo,usePathID,usePieceID,useT);
+ a->swsData[i].stPt = enNo;
+ a->swsData[stB].enPt = stNo;
+ }
+ }
}
- if (dec < 0)
+ if (power < 0 || mode == tweak_mode_push || mode == tweak_mode_repel || mode == tweak_mode_roughen)
{
for (int i = 0; i < numberOfEdges(); i++)
Inverse (i);
@@ -679,17 +713,21 @@ Shape::MakeOffset (Shape * a, double dec, JoinType join, double miter, bool do_p
return (done_something? 0 : shape_nothing_to_do);
}
-// pushing
-// modeled after MakeOffset black magic, the only difference being in the DoRight/LeftJoin parameters
+
+// offsets
+// take each edge, offset it, and make joins with previous at edge start and next at edge end (previous and
+// next being with respect to the clockwise order)
+// you gotta be very careful with the join, as anything but the right one will fuck everything up
+// see PathStroke.cpp for the "right" joins
int
-Shape::MakePush (Shape * a, JoinType join, double miter, bool do_profile, NR::Point c, NR::Point vector, double radius, NR::Matrix *i2doc)
+Shape::MakeOffset (Shape * a, double dec, JoinType join, double miter, bool do_profile, double cx, double cy, double radius, NR::Matrix *i2doc)
{
Reset (0, 0);
MakeBackData(a->_has_back_data);
bool done_something = false;
-
- if (NR::L2(vector) == 0)
+
+ if (dec == 0)
{
_pts = a->_pts;
if (numberOfPoints() > maxPt)
@@ -729,143 +767,18 @@ Shape::MakePush (Shape * a, JoinType join, double miter, bool do_profile, NR::Po
for (int i = 0; i < a->numberOfEdges(); i++)
{
+ // int stP=a->swsData[i].stPt/*,enP=a->swsData[i].enPt*/;
int stB = -1, enB = -1;
- stB = a->CyclePrevAt (a->getEdge(i).st, i);
- enB = a->CycleNextAt (a->getEdge(i).en, i);
-
- NR::Point stD, seD, enD;
- double stL, seL, enL;
- stD = a->getEdge(stB).dx;
- seD = a->getEdge(i).dx;
- enD = a->getEdge(enB).dx;
-
- stL = sqrt (dot(stD,stD));
- seL = sqrt (dot(seD,seD));
- enL = sqrt (dot(enD,enD));
- MiscNormalize (stD);
- MiscNormalize (enD);
- MiscNormalize (seD);
-
- NR::Point ptP;
- int stNo, enNo;
- ptP = a->getPoint(a->getEdge(i).st).x;
-
- NR::Point this_vec;
- if (do_profile && i2doc) {
- double alpha = 1;
- double x = (NR::L2(ptP * (*i2doc) - c)/radius);
- if (x > 1) {
- this_vec = NR::Point(0,0);
- } else if (x <= 0) {
- this_vec = vector;
- } else {
- this_vec = (0.5 * cos (M_PI * (pow(x, alpha))) + 0.5) * vector;
- }
- } else {
- this_vec = vector;
- }
-
- if (NR::L2(this_vec) != 0)
- done_something = true;
-
- int usePathID=-1;
- int usePieceID=0;
- double useT=0.0;
- if ( a->_has_back_data ) {
- if ( a->ebData[i].pathID >= 0 && a->ebData[stB].pathID == a->ebData[i].pathID && a->ebData[stB].pieceID == a->ebData[i].pieceID
- && a->ebData[stB].tEn == a->ebData[i].tSt ) {
- usePathID=a->ebData[i].pathID;
- usePieceID=a->ebData[i].pieceID;
- useT=a->ebData[i].tSt;
- } else {
- usePathID=a->ebData[i].pathID;
- usePieceID=0;
- useT=0;
- }
- }
- Path::DoLeftJoin (this, 0, join, ptP+this_vec, stD+this_vec, seD+this_vec, miter, stL, seL,
- stNo, enNo,usePathID,usePieceID,useT);
- a->swsData[i].stPt = enNo;
- a->swsData[stB].enPt = stNo;
- }
-
-
- for (int i = 0; i < numberOfEdges(); i++)
- Inverse (i);
-
- if ( _has_back_data ) {
- for (int i = 0; i < a->numberOfEdges(); i++)
- {
- int nEd=AddEdge (a->swsData[i].stPt, a->swsData[i].enPt);
- ebData[nEd]=a->ebData[i];
- }
- } else {
- for (int i = 0; i < a->numberOfEdges(); i++)
- {
- AddEdge (a->swsData[i].stPt, a->swsData[i].enPt);
- }
- }
-
- a->MakeSweepSrcData (false);
- a->MakeSweepDestData (false);
-
- return (done_something? 0 : shape_nothing_to_do);
-}
-
-
-// attracting/repelling
-// modeled after MakeOffset black magic, the only difference being in the DoRight/LeftJoin parameters
-int
-Shape::MakeRepel (Shape * a, double dec, JoinType join, double miter, bool do_profile, double cx, double cy, double radius, NR::Matrix *i2doc)
-{
- Reset (0, 0);
- MakeBackData(a->_has_back_data);
-
- bool done_something = false;
-
- if (dec == 0)
- {
- _pts = a->_pts;
- if (numberOfPoints() > maxPt)
+ if (dec > 0)
{
- maxPt = numberOfPoints();
- if (_has_points_data) {
- pData.resize(maxPt);
- _point_data_initialised = false;
- _bbox_up_to_date = false;
- }
+ stB = a->CycleNextAt (a->getEdge(i).st, i);
+ enB = a->CyclePrevAt (a->getEdge(i).en, i);
}
-
- _aretes = a->_aretes;
- if (numberOfEdges() > maxAr)
+ else
{
- maxAr = numberOfEdges();
- if (_has_edges_data)
- eData.resize(maxAr);
- if (_has_sweep_src_data)
- swsData.resize(maxAr);
- if (_has_sweep_dest_data)
- swdData.resize(maxAr);
- if (_has_raster_data)
- swrData.resize(maxAr);
- if (_has_back_data)
- ebData.resize(maxAr);
+ stB = a->CyclePrevAt (a->getEdge(i).st, i);
+ enB = a->CycleNextAt (a->getEdge(i).en, i);
}
- return 0;
- }
- if (a->numberOfPoints() <= 1 || a->numberOfEdges() <= 1 || a->type != shape_polygon)
- return shape_input_err;
-
- a->SortEdges ();
-
- a->MakeSweepDestData (true);
- a->MakeSweepSrcData (true);
-
- for (int i = 0; i < a->numberOfEdges(); i++)
- {
- int stB = -1, enB = -1;
- stB = a->CyclePrevAt (a->getEdge(i).st, i);
- enB = a->CycleNextAt (a->getEdge(i).en, i);
NR::Point stD, seD, enD;
double stL, seL, enL;
@@ -884,25 +797,22 @@ Shape::MakeRepel (Shape * a, double dec, JoinType join, double miter, bool do_pr
int stNo, enNo;
ptP = a->getPoint(a->getEdge(i).st).x;
- NR::Point this_vec;
+ double this_dec;
if (do_profile && i2doc) {
double alpha = 1;
- NR::Point c (cx, cy);
- NR::Point to_center = ptP * (*i2doc) - c;
- double x = (NR::L2(to_center)/radius);
+ double x = (NR::L2(ptP * (*i2doc) - NR::Point(cx,cy))/radius);
if (x > 1) {
- this_vec = NR::Point(0,0);
+ this_dec = 0;
} else if (x <= 0) {
- this_vec = NR::Point(0,0);
+ this_dec = dec;
} else {
- this_vec = (1/NR::L2(to_center)) * to_center; // normalize
- this_vec = dec * (0.5 * cos (M_PI * (pow(x, alpha))) + 0.5) * this_vec;
+ this_dec = dec * (0.5 * cos (M_PI * (pow(x, alpha))) + 0.5);
}
} else {
- this_vec = NR::Point(0,0);
+ this_dec = dec;
}
- if (NR::L2(this_vec) != 0)
+ if (this_dec != 0)
done_something = true;
int usePathID=-1;
@@ -920,153 +830,27 @@ Shape::MakeRepel (Shape * a, double dec, JoinType join, double miter, bool do_pr
useT=0;
}
}
- Path::DoLeftJoin (this, 0, join, ptP+this_vec, stD+this_vec, seD+this_vec, miter, stL, seL,
- stNo, enNo,usePathID,usePieceID,useT);
- a->swsData[i].stPt = enNo;
- a->swsData[stB].enPt = stNo;
- }
-
-
- for (int i = 0; i < numberOfEdges(); i++)
- Inverse (i);
-
- if ( _has_back_data ) {
- for (int i = 0; i < a->numberOfEdges(); i++)
+ if (dec > 0)
{
- int nEd=AddEdge (a->swsData[i].stPt, a->swsData[i].enPt);
- ebData[nEd]=a->ebData[i];
+ Path::DoRightJoin (this, this_dec, join, ptP, stD, seD, miter, stL, seL,
+ stNo, enNo,usePathID,usePieceID,useT);
+ a->swsData[i].stPt = enNo;
+ a->swsData[stB].enPt = stNo;
}
- } else {
- for (int i = 0; i < a->numberOfEdges(); i++)
+ else
{
- AddEdge (a->swsData[i].stPt, a->swsData[i].enPt);
+ Path::DoLeftJoin (this, -this_dec, join, ptP, stD, seD, miter, stL, seL,
+ stNo, enNo,usePathID,usePieceID,useT);
+ a->swsData[i].stPt = enNo;
+ a->swsData[stB].enPt = stNo;
}
}
- a->MakeSweepSrcData (false);
- a->MakeSweepDestData (false);
-
- return (done_something? 0 : shape_nothing_to_do);
-}
-
-
-// roughening
-// modeled after MakeOffset black magic, the only difference being in the DoRight/LeftJoin parameters
-int
-Shape::MakeJitter (Shape * a, JoinType join, double miter, bool do_profile, NR::Point c, double power, double radius, NR::Matrix *i2doc)
-{
- Reset (0, 0);
- MakeBackData(a->_has_back_data);
-
- bool done_something = false;
-
- if (power == 0)
- {
- _pts = a->_pts;
- if (numberOfPoints() > maxPt)
- {
- maxPt = numberOfPoints();
- if (_has_points_data) {
- pData.resize(maxPt);
- _point_data_initialised = false;
- _bbox_up_to_date = false;
- }
- }
-
- _aretes = a->_aretes;
- if (numberOfEdges() > maxAr)
- {
- maxAr = numberOfEdges();
- if (_has_edges_data)
- eData.resize(maxAr);
- if (_has_sweep_src_data)
- swsData.resize(maxAr);
- if (_has_sweep_dest_data)
- swdData.resize(maxAr);
- if (_has_raster_data)
- swrData.resize(maxAr);
- if (_has_back_data)
- ebData.resize(maxAr);
- }
-
- return 0;
- }
- if (a->numberOfPoints() <= 1 || a->numberOfEdges() <= 1 || a->type != shape_polygon)
- return shape_input_err;
-
- a->SortEdges ();
-
- a->MakeSweepDestData (true);
- a->MakeSweepSrcData (true);
-
- for (int i = 0; i < a->numberOfEdges(); i++)
+ if (dec < 0)
{
- int stB = -1, enB = -1;
- stB = a->CyclePrevAt (a->getEdge(i).st, i);
- enB = a->CycleNextAt (a->getEdge(i).en, i);
-
- NR::Point stD, seD, enD;
- double stL, seL, enL;
- stD = a->getEdge(stB).dx;
- seD = a->getEdge(i).dx;
- enD = a->getEdge(enB).dx;
-
- stL = sqrt (dot(stD,stD));
- seL = sqrt (dot(seD,seD));
- enL = sqrt (dot(enD,enD));
- MiscNormalize (stD);
- MiscNormalize (enD);
- MiscNormalize (seD);
-
- NR::Point ptP;
- int stNo, enNo;
- ptP = a->getPoint(a->getEdge(i).st).x;
-
- double this_power;
- if (do_profile && i2doc) {
- double alpha = 1;
- double x = (NR::L2(ptP * (*i2doc) - c)/radius);
- if (x > 1) {
- this_power = 0;
- } else if (x <= 0) {
- this_power = power;
- } else {
- this_power = (0.5 * cos (M_PI * (pow(x, alpha))) + 0.5) * power;
- }
- } else {
- this_power = power;
- }
-
- if (this_power != 0)
- done_something = true;
-
- double angle = g_random_double_range(0, 2*M_PI);
- NR::Point this_vec = g_random_double_range(0, 1) * this_power * NR::Point(sin(angle), cos(angle));
-
- int usePathID=-1;
- int usePieceID=0;
- double useT=0.0;
- if ( a->_has_back_data ) {
- if ( a->ebData[i].pathID >= 0 && a->ebData[stB].pathID == a->ebData[i].pathID && a->ebData[stB].pieceID == a->ebData[i].pieceID
- && a->ebData[stB].tEn == a->ebData[i].tSt ) {
- usePathID=a->ebData[i].pathID;
- usePieceID=a->ebData[i].pieceID;
- useT=a->ebData[i].tSt;
- } else {
- usePathID=a->ebData[i].pathID;
- usePieceID=0;
- useT=0;
- }
- }
- Path::DoLeftJoin (this, 0, join, ptP+this_vec, stD+this_vec, seD+this_vec, miter, stL, seL,
- stNo, enNo,usePathID,usePieceID,useT);
- a->swsData[i].stPt = enNo;
- a->swsData[stB].enPt = stNo;
- }
-
-
- for (int i = 0; i < numberOfEdges(); i++)
+ for (int i = 0; i < numberOfEdges(); i++)
Inverse (i);
+ }
if ( _has_back_data ) {
for (int i = 0; i < a->numberOfEdges(); i++)
@@ -1083,11 +867,12 @@ Shape::MakeJitter (Shape * a, JoinType join, double miter, bool do_profile, NR::
a->MakeSweepSrcData (false);
a->MakeSweepDestData (false);
-
+
return (done_something? 0 : shape_nothing_to_do);
}
+
// we found a contour, now reassemble the edges on it, instead of dumping them in the Path "dest" as a
// polyline. since it was a DFS, the precParc and suivParc make a nice doubly-linked list of the edges in
// the contour. the first and last edges of the contour are startBord and curBord
diff --git a/src/tweak-context.cpp b/src/tweak-context.cpp
index b662ca2de56057f79ab84f4bf13393b793129860..4f761d8c321187f374dbf7fede9cd6965e3e9f32 100644 (file)
--- a/src/tweak-context.cpp
+++ b/src/tweak-context.cpp
@@ -400,26 +400,28 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, NR::Poi
bool did_this = false;
NR::Matrix i2doc(sp_item_i2doc_affine(item));
if (mode == TWEAK_MODE_SHRINK || mode == TWEAK_MODE_GROW) {
- if (theShape->MakeOffset(theRes,
+ if (theShape->MakeTweak(tweak_mode_grow, theRes,
mode == TWEAK_MODE_GROW? force : -force,
join_straight, 4.0,
- true, p[NR::X], p[NR::Y], radius, &i2doc) == 0) // 0 means the shape was actually changed
+ true, p, NR::Point(0,0), radius, &i2doc) == 0) // 0 means the shape was actually changed
did_this = true;
} else if (mode == TWEAK_MODE_ATTRACT || mode == TWEAK_MODE_REPEL) {
- if (theShape->MakeRepel(theRes,
+ if (theShape->MakeTweak(tweak_mode_repel, theRes,
mode == TWEAK_MODE_REPEL? force : -force,
join_straight, 4.0,
- true, p[NR::X], p[NR::Y], radius, &i2doc) == 0)
+ true, p, NR::Point(0,0), radius, &i2doc) == 0)
did_this = true;
} else if (mode == TWEAK_MODE_PUSH) {
- if (theShape->MakePush(theRes,
+ if (theShape->MakeTweak(tweak_mode_push, theRes,
+ 0,
join_straight, 4.0,
true, p, force*2*vector, radius, &i2doc) == 0)
did_this = true;
} else if (mode == TWEAK_MODE_ROUGHEN) {
- if (theShape->MakeJitter(theRes,
+ if (theShape->MakeTweak(tweak_mode_roughen, theRes,
+ force,
join_straight, 4.0,
- true, p, force, radius, &i2doc) == 0)
+ true, p, NR::Point(0,0), radius, &i2doc) == 0)
did_this = true;
}