Skip to content

Commit 25fe3bd

Browse files
committed
debug
1 parent 60a2fcf commit 25fe3bd

File tree

3 files changed

+290
-57
lines changed

3 files changed

+290
-57
lines changed

liblwgeom/lwgeom_nurbs.c

Lines changed: 179 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -44,24 +44,65 @@ lwnurbs_construct(int32_t srid, GBOX *bbox, uint32_t degree,
4444
/* Basic validation */
4545
if (degree < NURBS_MIN_DEGREE || degree > NURBS_MAX_DEGREE)
4646
{
47-
lwerror("lwnurbs_construct: invalid degree %d", degree);
47+
lwnotice("lwnurbs_construct: invalid degree %d", degree);
4848
return NULL;
4949
}
5050

51-
if (ctrl_pts && ctrl_pts->npoints < NURBS_MIN_POINTS)
51+
if (!ctrl_pts)
5252
{
53-
lwerror("lwnurbs_construct: minimum %d control points required", NURBS_MIN_POINTS);
53+
lwnotice("lwnurbs_construct: ctrl_pts is NULL");
5454
return NULL;
5555
}
5656

57+
if (ctrl_pts->npoints < NURBS_MIN_POINTS)
58+
{
59+
lwnotice("lwnurbs_construct: minimum %d control points required, got %d",
60+
NURBS_MIN_POINTS, ctrl_pts->npoints);
61+
return NULL;
62+
}
63+
64+
/* Validate knots */
65+
uint32_t expected_knots = ctrl_pts->npoints + degree + 1;
66+
if (nknots != expected_knots)
67+
{
68+
lwnotice("lwnurbs_construct: expected %d knots, got %d", expected_knots, nknots);
69+
return NULL;
70+
}
71+
72+
if (!knots)
73+
{
74+
lwnotice("lwnurbs_construct: knots array is NULL");
75+
return NULL;
76+
}
77+
78+
/* Validate weights if provided */
79+
if (weights && nweights != ctrl_pts->npoints)
80+
{
81+
lwnotice("lwnurbs_construct: weights count (%d) doesn't match control points (%d)",
82+
nweights, ctrl_pts->npoints);
83+
return NULL;
84+
}
85+
86+
lwnotice("lwnurbs_construct: creating NURBS with degree=%d, npoints=%d, nknots=%d",
87+
degree, ctrl_pts->npoints, nknots);
88+
5789
result = (LWNURBSCURVE*) lwalloc(sizeof(LWNURBSCURVE));
5890
result->type = NURBSCURVETYPE;
59-
result->flags = ctrl_pts ? ctrl_pts->flags : lwflags(0, 0, 0);
91+
result->flags = ctrl_pts->flags;
6092
FLAGS_SET_BBOX(result->flags, bbox ? 1 : 0);
6193
result->srid = srid;
62-
result->bbox = bbox;
94+
result->bbox = bbox ? gbox_clone(bbox) : NULL;
6395
result->degree = degree;
64-
result->ctrl_pts = ctrl_pts;
96+
97+
/* Clone the control points array */
98+
result->ctrl_pts = ptarray_clone_deep(ctrl_pts);
99+
if (!result->ctrl_pts)
100+
{
101+
lwnotice("lwnurbs_construct: failed to clone control points");
102+
lwfree(result);
103+
return NULL;
104+
}
105+
65106
result->nweights = nweights;
66107
result->nknots = nknots;
67108

@@ -70,23 +111,26 @@ lwnurbs_construct(int32_t srid, GBOX *bbox, uint32_t degree,
70111
{
71112
result->weights = (double*) lwalloc(sizeof(double) * nweights);
72113
memcpy(result->weights, weights, sizeof(double) * nweights);
114+
lwnotice("lwnurbs_construct: copied %d weights", nweights);
73115
}
74116
else
75117
{
76118
result->weights = NULL;
119+
lwnotice("lwnurbs_construct: no weights provided");
77120
}
78121

79-
/* Copy knots if provided */
80-
if (knots && nknots > 0)
81-
{
82-
result->knots = (double*) lwalloc(sizeof(double) * nknots);
83-
memcpy(result->knots, knots, sizeof(double) * nknots);
84-
}
85-
else
86-
{
87-
result->knots = NULL;
88-
}
122+
/* Copy knots */
123+
result->knots = (double*) lwalloc(sizeof(double) * nknots);
124+
memcpy(result->knots, knots, sizeof(double) * nknots);
125+
lwnotice("lwnurbs_construct: copied %d knots", nknots);
126+
127+
/* Debug: print first few knots */
128+
lwnotice("lwnurbs_construct: knots[0]=%g, knots[1]=%g, knots[%d]=%g",
129+
result->knots[0],
130+
nknots > 1 ? result->knots[1] : 0.0,
131+
nknots-1, result->knots[nknots-1]);
89132

133+
lwnotice("lwnurbs_construct: NURBS curve created successfully");
90134
return result;
91135
}
92136

@@ -141,34 +185,71 @@ lwnurbs_release(LWNURBSCURVE *nurbs)
141185
/**
142186
* B-spline basis function implementation (De Boor algorithm)
143187
*/
188+
/* Dans lwgeom_nurbs.c, fonction bspline_basis avec debug */
189+
144190
double
145191
bspline_basis(int i, int p, double t, const double *knots, int nknots)
146192
{
193+
if (!knots || nknots <= 0)
194+
{
195+
lwnotice("bspline_basis: NULL knots or invalid nknots=%d", nknots);
196+
return 0.0;
197+
}
198+
199+
if (i < 0 || i >= nknots - p - 1)
200+
{
201+
lwnotice("bspline_basis: index i=%d out of range [0, %d]", i, nknots - p - 1);
202+
return 0.0;
203+
}
204+
147205
if (p == 0)
148206
{
149207
if (i >= 0 && i < nknots - 1 && t >= knots[i] && t < knots[i + 1])
208+
{
209+
lwnotice("bspline_basis: p=0, i=%d, t=%g in [%g, %g) -> 1.0",
210+
i, t, knots[i], knots[i + 1]);
150211
return 1.0;
212+
}
151213
else if (i == nknots - 2 && fabs(t - knots[nknots - 1]) < NURBS_TOLERANCE)
214+
{
215+
lwnotice("bspline_basis: p=0, i=%d, t=%g at end knot %g -> 1.0",
216+
i, t, knots[nknots - 1]);
152217
return 1.0;
218+
}
153219
else
220+
{
221+
if (i < 3) // Debug
222+
{
223+
lwnotice("bspline_basis: p=0, i=%d, t=%g not in [%g, %g) -> 0.0",
224+
i, t, knots[i], knots[i + 1]);
225+
}
154226
return 0.0;
227+
}
155228
}
156229

157230
double left = 0.0, right = 0.0;
158231

159232
if (i + p < nknots && fabs(knots[i + p] - knots[i]) > NURBS_TOLERANCE)
160233
{
161234
left = (t - knots[i]) / (knots[i + p] - knots[i]) *
162-
bspline_basis(i, p - 1, t, knots, nknots);
235+
bspline_basis(i, p - 1, t, knots, nknots);
163236
}
164237

165238
if (i + p + 1 < nknots && fabs(knots[i + p + 1] - knots[i + 1]) > NURBS_TOLERANCE)
166239
{
167240
right = (knots[i + p + 1] - t) / (knots[i + p + 1] - knots[i + 1]) *
168-
bspline_basis(i + 1, p - 1, t, knots, nknots);
241+
bspline_basis(i + 1, p - 1, t, knots, nknots);
169242
}
170243

171-
return left + right;
244+
double result = left + right;
245+
246+
if (i < 3 && p <= 2) // Debug
247+
{
248+
lwnotice("bspline_basis: i=%d, p=%d, t=%g -> %g (left=%g, right=%g)",
249+
i, p, t, result, left, right);
250+
}
251+
252+
return result;
172253
}
173254

174255
/**
@@ -183,6 +264,20 @@ lwnurbs_interpolate_point(const LWNURBSCURVE *nurbs, double t, POINT4D *pt)
183264
if (nurbs->ctrl_pts->npoints == 0)
184265
return LW_FAILURE;
185266

267+
268+
if (!nurbs->knots || nurbs->nknots == 0)
269+
{
270+
lwnotice("NURBS curve has no knot vector");
271+
return LW_FAILURE;
272+
}
273+
uint32_t expected_knots = nurbs->ctrl_pts->npoints + nurbs->degree + 1;
274+
if (nurbs->nknots != expected_knots)
275+
{
276+
lwnotice("NURBS curve has incorrect number of knots: %d expected, %d found",
277+
expected_knots, nurbs->nknots);
278+
return LW_FAILURE;
279+
}
280+
186281
/* Clamp parameter to [0,1] */
187282
if (t < 0.0) t = 0.0;
188283
if (t > 1.0) t = 1.0;
@@ -198,14 +293,21 @@ lwnurbs_interpolate_point(const LWNURBSCURVE *nurbs, double t, POINT4D *pt)
198293
double weight_sum = 0.0;
199294
POINT4D ctrl_pt;
200295

296+
297+
lwnotice("Evaluating NURBS at t=%g with %d control points, degree %d, %d knots",
298+
t, n, p, nurbs->nknots);
299+
201300
for (uint32_t i = 0; i < n; i++)
202301
{
203302
getPoint4d_p(nurbs->ctrl_pts, i, &ctrl_pt);
204303

205304
double basis = bspline_basis(i, p, t, nurbs->knots, nurbs->nknots);
206305
double weight = (nurbs->weights && i < nurbs->nweights) ? nurbs->weights[i] : 1.0;
207306
double w_basis = weight * basis;
208-
307+
if (i < 3) // Debug only fro first three points
308+
{
309+
lwnotice("Point %d: basis=%g, weight=%g, w_basis=%g", i, basis, weight, w_basis);
310+
}
209311
pt->x += w_basis * ctrl_pt.x;
210312
pt->y += w_basis * ctrl_pt.y;
211313
if (hasz) pt->z += w_basis * ctrl_pt.z;
@@ -214,15 +316,19 @@ lwnurbs_interpolate_point(const LWNURBSCURVE *nurbs, double t, POINT4D *pt)
214316
weight_sum += w_basis;
215317
}
216318

217-
/* Normalize by weight sum for rational curves */
218-
if (weight_sum > NURBS_TOLERANCE)
319+
if (weight_sum <= NURBS_TOLERANCE)
219320
{
220-
pt->x /= weight_sum;
221-
pt->y /= weight_sum;
222-
if (hasz) pt->z /= weight_sum;
223-
if (hasm) pt->m /= weight_sum;
321+
lwnotice("NURBS evaluation failed: weight sum too small (%g)", weight_sum);
322+
return LW_FAILURE;
224323
}
225324

325+
/* Normalize by weight sum for rational curves */
326+
pt->x /= weight_sum;
327+
pt->y /= weight_sum;
328+
if (hasz) pt->z /= weight_sum;
329+
if (hasm) pt->m /= weight_sum;
330+
331+
lwnotice("NURBS evaluated to point (%g, %g)", pt->x, pt->y);
226332
return LW_SUCCESS;
227333
}
228334

@@ -412,21 +518,65 @@ lwnurbs_uniform_knots(uint32_t degree, uint32_t nctrl)
412518
double *
413519
lwnurbs_clamped_knots(uint32_t degree, uint32_t nctrl)
414520
{
521+
if (degree < 1 || nctrl < 2)
522+
{
523+
lwnotice("lwnurbs_clamped_knots: invalid parameters degree=%d, nctrl=%d", degree, nctrl);
524+
return NULL;
525+
}
526+
415527
uint32_t nknots = nctrl + degree + 1;
416528
double *knots = lwalloc(sizeof(double) * nknots);
417529

418-
/* Clamp start */
530+
if (!knots)
531+
{
532+
lwnotice("lwnurbs_clamped_knots: failed to allocate memory for %d knots", nknots);
533+
return NULL;
534+
}
535+
536+
lwnotice("lwnurbs_clamped_knots: generating %d knots for degree=%d, nctrl=%d",
537+
nknots, degree, nctrl);
538+
539+
/* Clamp start: first (degree+1) knots = 0.0 */
419540
for (uint32_t i = 0; i <= degree; i++)
420541
knots[i] = 0.0;
421542

422-
/* Internal knots */
543+
/* Internal knots: linearly spaced between 0 and 1 */
423544
for (uint32_t i = degree + 1; i < nctrl; i++)
545+
{
424546
knots[i] = (double)(i - degree) / (double)(nctrl - degree);
547+
}
425548

426-
/* Clamp end */
549+
/* Clamp end: last (degree+1) knots = 1.0 */
427550
for (uint32_t i = nctrl; i < nknots; i++)
428551
knots[i] = 1.0;
429552

553+
/* Debug: print the knot vector */
554+
lwnotice("lwnurbs_clamped_knots: generated knots:");
555+
for (uint32_t i = 0; i < nknots; i++)
556+
{
557+
if (i < 10 || i >= nknots - 5) // Print first 10 and last 5
558+
{
559+
lwnotice(" knots[%d] = %g", i, knots[i]);
560+
}
561+
else if (i == 10)
562+
{
563+
lwnotice(" ... (%d more knots) ...", nknots - 15);
564+
}
565+
}
566+
567+
/* Validate the knot vector */
568+
for (uint32_t i = 1; i < nknots; i++)
569+
{
570+
if (knots[i] < knots[i-1])
571+
{
572+
lwnotice("lwnurbs_clamped_knots: ERROR - non-monotonic knots at index %d: %g < %g",
573+
i, knots[i], knots[i-1]);
574+
lwfree(knots);
575+
return NULL;
576+
}
577+
}
578+
579+
lwnotice("lwnurbs_clamped_knots: knot vector generated successfully");
430580
return knots;
431581
}
432582

liblwgeom/lwout_wkt.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,7 @@ static void lwgeom_to_wkt_sb(const LWGEOM *geom, stringbuffer_t *sb, int precisi
697697
lwpsurface_to_wkt_sb((LWPSURFACE*)geom, sb, precision, variant);
698698
break;
699699
case NURBSCURVETYPE:
700+
lwnotice("nurbscurve wkt");
700701
lwnurbs_to_wkt_sb((LWNURBSCURVE*)geom, sb, precision, variant);
701702
break;
702703
default:
@@ -753,6 +754,7 @@ lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_o
753754
lwvarlena_t *
754755
lwgeom_to_wkt_varlena(const LWGEOM *geom, uint8_t variant, int precision)
755756
{
757+
lwnotice("varlena %s.", lwtype_name(geom->type));
756758
stringbuffer_t *sb = lwgeom_to_wkt_internal(geom, variant, precision);
757759
if (!sb)
758760
return NULL;

0 commit comments

Comments
 (0)