45 #include <visp3/core/vpConfig.h>
46 #include <visp3/core/vpException.h>
48 #ifndef DOXYGEN_SHOULD_SKIP_THIS
49 #include "vpClipping.h"
58 static void inter(Byte mask, Index v0, Index v1);
59 static void point_4D_3D(Point4f *p4,
int size, Byte *cp, Point3f *p3);
94 static Point4f *point4f;
95 static Index point4f_nbr;
98 static Index *poly0, *poly1;
100 static Index *poly_tmp;
107 void open_clipping(
void)
110 malloc_huge_Bound(&clip);
113 if ((code = (Byte *)malloc(POINT_NBR *
sizeof(Byte))) == NULL ||
114 (point4f = (Point4f *)malloc(POINT_NBR *
sizeof(Point4f))) == NULL
116 || (poly0 = (Index *)malloc(VERTEX_NBR *
sizeof(Index))) == NULL ||
117 (poly1 = (Index *)malloc(VERTEX_NBR *
sizeof(Index))) == NULL) {
118 static char proc_name[] =
"open_clipping";
123 || (poly_tmp = (Index *)malloc(VERTEX_NBR *
sizeof(Index))) == NULL) {
124 static char proc_name[] =
"open_clipping";
135 void close_clipping(
void)
137 free_huge_Bound(&clip);
139 free((
char *)point4f);
144 free((
char *)poly_tmp);
159 static Index clipping(Byte mask, Index vni, Index *pi, Index *po)
169 Index vs = pi[vni - 1];
170 Byte ins = code[vs] & mask;
174 Byte inp = code[vp] & mask;
176 if (ins == IS_INSIDE) {
177 if (inp == IS_INSIDE) {
182 *po++ = point4f_nbr++;
186 if (inp == IS_INSIDE) {
188 *po++ = point4f_nbr++;
211 static Index clipping_Face(Face *fi, Face *fo)
213 Index *flip = poly_tmp;
214 Index *flop = fo->vertex.ptr;
215 Index vn = fi->vertex.nbr;
217 if ((vn = clipping(IS_ABOVE, vn, fi->vertex.ptr, flip)) != 0)
218 if ((vn = clipping(IS_BELOW, vn, flip, flop)) != 0)
219 if ((vn = clipping(IS_RIGHT, vn, flop, flip)) != 0)
220 if ((vn = clipping(IS_LEFT, vn, flip, flop)) != 0)
221 if ((vn = clipping(IS_BACK, vn, flop, flip)) != 0)
222 if ((vn = clipping(IS_FRONT, vn, flip, flop)) != 0) {
226 fo->is_polygonal = fi->is_polygonal;
227 fo->is_visible = fi->is_visible;
229 fo->normal = fi->normal;
248 Bound *clipping_Bound(Bound *bp, Matrix m)
250 Face *fi = bp->face.ptr;
251 Face *fend = fi + bp->face.nbr;
252 Face *fo = clip.face.ptr;
256 point4f_nbr = bp->point.nbr;
257 point_3D_4D(bp->point.ptr, (
int)point4f_nbr, m, point4f);
258 set_Point4f_code(point4f, (
int)point4f_nbr, code);
260 if (!(clip.is_polygonal = bp->is_polygonal))
263 memmove(clip.normal.ptr, bp->normal.ptr, bp->normal.nbr *
sizeof(Vector));
265 for (; fi < fend; fi++) {
266 if (clipping_Face(fi, fo) != 0) {
273 fo->vertex.ptr = (fo - 1)->vertex.ptr + (fo - 1)->vertex.nbr;
277 if (fo == clip.face.ptr)
282 point_4D_3D(point4f, (
int)point4f_nbr, code, clip.point.ptr);
283 clip.type = bp->type;
284 clip.face.nbr = (Index)(fo - clip.face.ptr);
285 clip.point.nbr = point4f_nbr;
287 if (!bp->is_polygonal)
288 clip.normal.nbr = point4f_nbr;
301 static void inter(Byte mask, Index v0, Index v1)
303 Point4f *p = point4f + point4f_nbr;
304 Point4f *p0 = point4f + v0;
305 Point4f *p1 = point4f + v1;
314 t = (p0->w - p0->y) - (p1->w - p1->y);
316 t = (std::fabs(t) <= std::numeric_limits<double>::epsilon()) ? (
float)1.0 : (p0->w - p0->y) / t;
317 PAR_COORD3(*p, t, *p0, *p1);
323 t = (p0->w + p0->y) - (p1->w + p1->y);
325 t = (std::fabs(t) <= std::numeric_limits<double>::epsilon()) ? (
float)1.0 : (p0->w + p0->y) / t;
326 PAR_COORD3(*p, t, *p0, *p1);
332 t = (p0->w - p0->x) - (p1->w - p1->x);
334 t = (std::fabs(t) <= std::numeric_limits<double>::epsilon()) ? (
float)1.0 : (p0->w - p0->x) / t;
335 PAR_COORD3(*p, t, *p0, *p1);
341 t = (p0->w + p0->x) - (p1->w + p1->x);
343 t = (std::fabs(t) <= std::numeric_limits<double>::epsilon()) ? (
float)1.0 : (p0->w + p0->x) / t;
344 PAR_COORD3(*p, t, *p0, *p1);
350 t = (p0->w - p0->z) - (p1->w - p1->z);
352 t = (std::fabs(t) <= std::numeric_limits<double>::epsilon()) ? (
float)1.0 : (p0->w - p0->z) / t;
353 PAR_COORD3(*p, t, *p0, *p1);
361 t = (std::fabs(t) <= std::numeric_limits<double>::epsilon()) ? (
float)1.0 : p0->z / t;
362 p->x = (p1->x - p0->x) * t + p0->x;
363 p->y = (p1->y - p0->y) * t + p0->y;
364 p->w = (p1->w - p0->w) * t + p0->w;
365 p->z = (
float)M_EPSILON;
370 p->w += (float)M_EPSILON;
371 code[point4f_nbr] = where_is_Point4f(p);
373 if (!clip.is_polygonal) {
374 Vector *n0 = clip.normal.ptr + v0;
375 Vector *n1 = clip.normal.ptr + v1;
376 Vector *n = clip.normal.ptr + point4f_nbr;
378 SET_COORD3(*n, (n1->x - n0->x) * t + n0->x, (n1->y - n0->y) * t + n0->y, (n1->z - n0->z) * t + n0->z);
393 static void point_4D_3D(Point4f *p4,
int size, Byte *cp, Point3f *p3)
395 Point4f *pend = p4 + size;
398 for (; p4 < pend; p4++, p3++) {
399 if (*cp++ == IS_INSIDE) {
420 void set_Point4f_code(Point4f *p4,
int size, Byte *cp)
422 Point4f *pend = p4 + size;
425 for (; p4 < pend; p4++, *cp++ = b) {
429 else if (-p4->w > p4->y)
433 else if (-p4->w > p4->x)
437 else if (-0.9 > p4->z)
448 Byte where_is_Point4f(Point4f *p4)
454 else if (-p4->w > p4->y)
458 else if (-p4->w > p4->x)
462 else if (-0.9 > p4->z)
error that can be emitted by ViSP classes.