From e030c024710d5aa031ee88ad884eb3a13759ced2 Mon Sep 17 00:00:00 2001 From: lecoanet Date: Fri, 30 Apr 2004 14:16:27 +0000 Subject: Modification of ZnQueryAttribute signature Adaptation for the new global variables Reworking of the class structure The tesselator code has been mostly extracted so that it is available for other purposes as well. It is now in tkZinc.c. The Tesselator is now an application global object. --- generic/Curve.c | 215 +++++++++++--------------------------------------------- 1 file changed, 41 insertions(+), 174 deletions(-) (limited to 'generic') diff --git a/generic/Curve.c b/generic/Curve.c index b896215..ed75c83 100644 --- a/generic/Curve.c +++ b/generic/Curve.c @@ -490,150 +490,29 @@ Query(ZnItem item, int argc __unused, Tcl_Obj *CONST argv[]) { - if (ZnQueryAttribute(item->wi, item, cv_attrs, argv[0]) == TCL_ERROR) { + if (ZnQueryAttribute(item->wi->interp, item, cv_attrs, argv[0]) == TCL_ERROR) { return TCL_ERROR; } return TCL_OK; } - -static void -CurveTessBegin(GLenum type, - void *data) -{ - CurveItem cv = data; - ZnWInfo *wi = ((ZnItem) data)->wi; - - ZnListEmpty(wi->work_pts); - wi->tess_type = type; - if (type == GL_LINE_LOOP) { - cv->outlines.num_contours++; - cv->outlines.contours = ZnRealloc(cv->outlines.contours, - cv->outlines.num_contours * sizeof(ZnContour)); - } - else { - cv->tristrip.num_strips++; - cv->tristrip.strips = ZnRealloc(cv->tristrip.strips, - cv->tristrip.num_strips * sizeof(ZnStrip)); - cv->tristrip.strips[cv->tristrip.num_strips-1].fan = (type==GL_TRIANGLE_FAN); - } - /*printf("Début de fragment de type: %s\n", - (type == GL_TRIANGLE_FAN) ? "FAN" : - (type == GL_TRIANGLE_STRIP) ? "STRIP" : - (type == GL_TRIANGLES) ? "TRIANGLES" : - (type == GL_LINE_LOOP) ? "LINE LOOP" : "");*/ -} -static void -CurveTessVertex(void *vertex_data, - void *data) -{ - CurveItem cv = data; - ZnWInfo *wi = ((ZnItem) data)->wi; - ZnPoint p; - int size; - - p.x = ((GLdouble *) vertex_data)[0]; - p.y = ((GLdouble *) vertex_data)[1]; - /*printf("Sommet en %g %g\n", p.x, p.y);*/ - size = ZnListSize(wi->work_pts); - if ((wi->tess_type == GL_TRIANGLES) && (size == 3)) { - cv->tristrip.strips[cv->tristrip.num_strips-1].num_points = size; - cv->tristrip.strips[cv->tristrip.num_strips-1].points = ZnMalloc(size * sizeof(ZnPoint)); - memcpy(cv->tristrip.strips[cv->tristrip.num_strips-1].points, - ZnListArray(wi->work_pts), size * sizeof(ZnPoint)); - /*printf("Fin de fragment intermediaire %d, num points: %d\n", cv->tristrip.num_strips-1, size);*/ - /* Allocate a new fragment */ - ZnListEmpty(wi->work_pts); - cv->tristrip.num_strips++; - cv->tristrip.strips = ZnRealloc(cv->tristrip.strips, - cv->tristrip.num_strips * sizeof(ZnStrip)); - cv->tristrip.strips[cv->tristrip.num_strips-1].fan = False; - } - ZnListAdd(wi->work_pts, &p, ZnListTail); -} -static void -CurveTessEnd(void *data) -{ - CurveItem cv = data; - ZnWInfo *wi = ((ZnItem) data)->wi; - unsigned int size = ZnListSize(wi->work_pts); - unsigned int num; - - if (wi->tess_type == GL_LINE_LOOP) { - /* Add the last point to close the outline */ - size++; - num = cv->outlines.num_contours; - cv->outlines.contours[num-1].num_points = size; - cv->outlines.contours[num-1].points = ZnMalloc(size * sizeof(ZnPoint)); - memcpy(cv->outlines.contours[num-1].points, - ZnListArray(wi->work_pts), size * sizeof(ZnPoint)); - cv->outlines.contours[num-1].points[size-1] = cv->outlines.contours[num-1].points[0]; - cv->outlines.contours[num-1].cw = !ZnTestCCW(cv->outlines.contours[num-1].points, size); - } - else { - num = cv->tristrip.num_strips; - cv->tristrip.strips[num-1].num_points = size; - cv->tristrip.strips[num-1].points = ZnMalloc(size * sizeof(ZnPoint)); - memcpy(cv->tristrip.strips[num-1].points, - ZnListArray(wi->work_pts), size * sizeof(ZnPoint)); - } - /*printf("Fin de fragment %d, num points: %d\n", num, size);*/ -} -static void -CurveTessCombine(GLdouble coords[3], - void *vertex_data[4] __unused, - GLfloat weight[4] __unused, - void **out_data, - void *data) -{ - ZnWInfo *wi = ((ZnItem) data)->wi; - ZnCombineData *cdata; - - cdata = ZnMalloc(sizeof(ZnCombineData)); - cdata->v[0] = coords[0]; - cdata->v[1] = coords[1]; - cdata->next = wi->tess_combine_list; - wi->tess_combine_list = cdata; - *out_data = &cdata->v; - /*printf("Création d'un nouveau sommet en %g %g\n", - cdata->v[0], cdata->v[1]);*/ -} -static void -CurveTessError(GLenum errno, - void *data __unused) -{ - fprintf(stderr, "Tesselation error in curve item: %d\n", errno); -} - static void UpdateTristrip(CurveItem cv, ZnPoly *poly, ZnBool revert) { - ZnWInfo *wi = ((ZnItem) cv)->wi; ZnCombineData *cdata, *cnext; GLdouble v[3]; unsigned int j, k; int i; /*printf("UpdateTristrips sur %d\n", ((ZnItem) cv)->id);*/ - gluTessCallback(wi->tess, GLU_TESS_BEGIN_DATA, - (_GLUfuncptr) CurveTessBegin); - gluTessCallback(wi->tess, GLU_TESS_VERTEX_DATA, - (_GLUfuncptr) CurveTessVertex); - gluTessCallback(wi->tess, GLU_TESS_END_DATA, - (_GLUfuncptr) CurveTessEnd); - gluTessCallback(wi->tess, GLU_TESS_COMBINE_DATA, - (_GLUfuncptr) CurveTessCombine); - gluTessCallback(wi->tess, GLU_TESS_ERROR_DATA, - (_GLUfuncptr) CurveTessError); - gluTessProperty(wi->tess, GLU_TESS_WINDING_RULE, (GLdouble) cv->fill_rule); - gluTessNormal(wi->tess, 0.0, 0.0, -1.0); + gluTessProperty(ZnTesselator.tess, GLU_TESS_WINDING_RULE, (GLdouble) cv->fill_rule); if (cv->tristrip.num_strips == 0) { - gluTessProperty(wi->tess, GLU_TESS_BOUNDARY_ONLY, (GLdouble) GL_FALSE); - gluTessBeginPolygon(wi->tess, cv); + gluTessProperty(ZnTesselator.tess, GLU_TESS_BOUNDARY_ONLY, (GLdouble) GL_FALSE); + gluTessBeginPolygon(ZnTesselator.tess, &cv->tristrip); /* * We need to take care of the final (after transformation) winding * direction of the polygon in order to have the right tesselation @@ -641,7 +520,7 @@ UpdateTristrip(CurveItem cv, */ if (!revert) { for (j = 0; j < poly->num_contours; j++){ - gluTessBeginContour(wi->tess); + gluTessBeginContour(ZnTesselator.tess); /*printf("Début contour %d num_points %d\n", j, poly->contours[j].num_points);*/ for (k = 0; k < poly->contours[j].num_points; k++) { @@ -649,15 +528,15 @@ UpdateTristrip(CurveItem cv, v[0] = poly->contours[j].points[k].x; v[1] = poly->contours[j].points[k].y; v[2] = 0; - gluTessVertex(wi->tess, v, &poly->contours[j].points[k]); + gluTessVertex(ZnTesselator.tess, v, &poly->contours[j].points[k]); } /*printf("\n");*/ - gluTessEndContour(wi->tess); + gluTessEndContour(ZnTesselator.tess); } } else { for (j = 0; j < poly->num_contours; j++){ - gluTessBeginContour(wi->tess); + gluTessBeginContour(ZnTesselator.tess); /*printf("revert Début contour %d num_points %d\n", j, poly->contours[j].num_points);*/ for (i = (int) (poly->contours[j].num_points-1); i >= 0; i--) { @@ -665,20 +544,20 @@ UpdateTristrip(CurveItem cv, v[0] = poly->contours[j].points[i].x; v[1] = poly->contours[j].points[i].y; v[2] = 0; - gluTessVertex(wi->tess, v, &poly->contours[j].points[i]); + gluTessVertex(ZnTesselator.tess, v, &poly->contours[j].points[i]); } /*printf("\n");*/ - gluTessEndContour(wi->tess); + gluTessEndContour(ZnTesselator.tess); } } - gluTessEndPolygon(wi->tess); - cdata = wi->tess_combine_list; + gluTessEndPolygon(ZnTesselator.tess); + cdata = ZnTesselator.combine_list; while (cdata) { cnext = cdata->next; ZnFree(cdata); cdata = cnext; } - wi->tess_combine_list = NULL; + ZnTesselator.combine_list = NULL; } /*printf("Fin UpdateTristrips sur %d\n", ((ZnItem) cv)->id);*/ } @@ -688,29 +567,17 @@ UpdateOutlines(CurveItem cv, ZnPoly *poly, ZnBool revert) { - ZnWInfo *wi = ((ZnItem) cv)->wi; ZnCombineData *cdata, *cnext; GLdouble v[3]; unsigned int j, k; int i; /*printf("UpdateOutlines sur %d\n", ((ZnItem) cv)->id);*/ - gluTessCallback(wi->tess, GLU_TESS_BEGIN_DATA, - (_GLUfuncptr) CurveTessBegin); - gluTessCallback(wi->tess, GLU_TESS_VERTEX_DATA, - (_GLUfuncptr) CurveTessVertex); - gluTessCallback(wi->tess, GLU_TESS_END_DATA, - (_GLUfuncptr) CurveTessEnd); - gluTessCallback(wi->tess, GLU_TESS_COMBINE_DATA, - (_GLUfuncptr) CurveTessCombine); - gluTessCallback(wi->tess, GLU_TESS_ERROR_DATA, - (_GLUfuncptr) CurveTessError); - gluTessProperty(wi->tess, GLU_TESS_WINDING_RULE, (GLdouble) cv->fill_rule); - gluTessNormal(wi->tess, 0.0, 0.0, -1.0); + gluTessProperty(ZnTesselator.tess, GLU_TESS_WINDING_RULE, (GLdouble) cv->fill_rule); if (cv->outlines.num_contours == 0) { - gluTessProperty(wi->tess, GLU_TESS_BOUNDARY_ONLY, (GLdouble) GL_TRUE); - gluTessBeginPolygon(wi->tess, cv); + gluTessProperty(ZnTesselator.tess, GLU_TESS_BOUNDARY_ONLY, (GLdouble) GL_TRUE); + gluTessBeginPolygon(ZnTesselator.tess, &cv->outlines); /* * We need to take care of the final (after transformation) winding @@ -719,36 +586,36 @@ UpdateOutlines(CurveItem cv, */ if (!revert) { for (j = 0; j < poly->num_contours; j++){ - gluTessBeginContour(wi->tess); + gluTessBeginContour(ZnTesselator.tess); for (k = 0; k < poly->contours[j].num_points; k++) { v[0] = poly->contours[j].points[k].x; v[1] = poly->contours[j].points[k].y; v[2] = 0; - gluTessVertex(wi->tess, v, &poly->contours[j].points[k]); + gluTessVertex(ZnTesselator.tess, v, &poly->contours[j].points[k]); } - gluTessEndContour(wi->tess); + gluTessEndContour(ZnTesselator.tess); } } else { for (j = 0; j < poly->num_contours; j++){ - gluTessBeginContour(wi->tess); + gluTessBeginContour(ZnTesselator.tess); for (i = (int) (poly->contours[j].num_points-1); i >= 0; i--) { v[0] = poly->contours[j].points[i].x; v[1] = poly->contours[j].points[i].y; v[2] = 0; - gluTessVertex(wi->tess, v, &poly->contours[j].points[i]); + gluTessVertex(ZnTesselator.tess, v, &poly->contours[j].points[i]); } - gluTessEndContour(wi->tess); + gluTessEndContour(ZnTesselator.tess); } } - gluTessEndPolygon(wi->tess); - cdata = wi->tess_combine_list; + gluTessEndPolygon(ZnTesselator.tess); + cdata = ZnTesselator.combine_list; while (cdata) { cnext = cdata->next; ZnFree(cdata); cdata = cnext; } - wi->tess_combine_list = NULL; + ZnTesselator.combine_list = NULL; } /*printf("Fin UpdateOutlines sur %d\n", ((ZnItem) cv)->id);*/ } @@ -833,8 +700,8 @@ ComputeCoordinates(ZnItem item, */ if (c1->controls) { segment_start = 0; - ZnListEmpty(wi->work_pts); - ZnListAdd(wi->work_pts, &c2->points[0], ZnListTail); + ZnListEmpty(ZnWorkPoints); + ZnListAdd(ZnWorkPoints, &c2->points[0], ZnListTail); /*printf("moveto %g@%g\n", c2->points[0].x, c2->points[0].y);*/ for (j = 1; j < c1->num_points; j++) { if (!c1->controls[j]) { @@ -846,11 +713,11 @@ ComputeCoordinates(ZnItem item, c2->points[j].x, c2->points[j].y);*/ ZnGetBezierPoints(&c2->points[segment_start], &c2->points[segment_start+1], &c2->points[j-1], - &c2->points[j], wi->work_pts, 0.5); + &c2->points[j], ZnWorkPoints, 0.5); } else { /*printf("lineto %g@%g\n", c2->points[j].x, c2->points[j].y);*/ - ZnListAdd(wi->work_pts, &c2->points[j], ZnListTail); + ZnListAdd(ZnWorkPoints, &c2->points[j], ZnListTail); } segment_start = j; } @@ -863,19 +730,19 @@ ComputeCoordinates(ZnItem item, if (c1->controls[c1->num_points-1]) { ZnGetBezierPoints(&c2->points[segment_start], &c2->points[segment_start+1], &c2->points[c1->num_points-1], - &c2->points[0], wi->work_pts, 0.5); + &c2->points[0], ZnWorkPoints, 0.5); } /* * Replace the original path by the expanded, closing it as * needed (one open contour). */ - num_points =ZnListSize(wi->work_pts); + num_points =ZnListSize(ZnWorkPoints); if (c2->num_points != c1->num_points) { num_points++; } c2->points = ZnRealloc(c2->points, num_points*sizeof(ZnPoint)); - memcpy(c2->points, ZnListArray(wi->work_pts), num_points*sizeof(ZnPoint)); + memcpy(c2->points, ZnListArray(ZnWorkPoints), num_points*sizeof(ZnPoint)); if (c2->num_points != c1->num_points) { c2->points[num_points-1] = c2->points[0]; } @@ -1249,8 +1116,8 @@ Draw(ZnItem item) } } else { - ZnListAssertSize(wi->work_xpts, num_points); - xpoints = ZnListArray(wi->work_xpts); + ZnListAssertSize(ZnWorkXPoints, num_points); + xpoints = ZnListArray(ZnWorkXPoints); for (j = 0; j < num_points; j++) { xpoints[j].x = ZnNearestInt(points[j].x); xpoints[j].y = ZnNearestInt(points[j].y); @@ -1306,8 +1173,8 @@ Draw(ZnItem item) for (j = 0; j < cv->outlines.num_contours; j++) { num_points = cv->outlines.contours[j].num_points; points = cv->outlines.contours[j].points; - ZnListAssertSize(wi->work_xpts, num_points); - xpoints = ZnListArray(wi->work_xpts); + ZnListAssertSize(ZnWorkXPoints, num_points); + xpoints = ZnListArray(ZnWorkXPoints); for (i = 0; i < num_points; i++) { xpoints[i].x = ZnNearestInt(points[i].x); xpoints[i].y = ZnNearestInt(points[i].y); @@ -1356,8 +1223,8 @@ Draw(ZnItem item) for (j = 0; j < cv->outlines.num_contours; j++) { num_points = cv->outlines.contours[j].num_points; points = cv->outlines.contours[j].points; - ZnListAssertSize(wi->work_xpts, num_points); - xpoints = (XPoint *) ZnListArray(wi->work_xpts); + ZnListAssertSize(ZnWorkXPoints, num_points); + xpoints = (XPoint *) ZnListArray(ZnWorkXPoints); for (i = 0; i < num_points; i++) { xpoints[i].x = (short) ZnNearestInt(points[i].x); xpoints[i].y = (short) ZnNearestInt(points[i].y); @@ -2263,11 +2130,11 @@ GetAnchor(ZnItem item, ********************************************************************************** */ static ZnItemClassStruct CURVE_ITEM_CLASS = { - sizeof(CurveItemStruct), - 0, /* num_parts */ - False, /* has_anchors */ "curve", + sizeof(CurveItemStruct), cv_attrs, + 0, /* num_parts */ + 0, /* flags */ -1, Init, Clone, -- cgit v1.1