/* Generate a transformed copy of poly. */ static inline Poly *transform_poly(Transform T, Transform Tdual, Transform TxT, Poly *poly, struct obstack *scratch) { Poly *newp; int i; newp = new_poly(poly->n_vertices, NULL, scratch); for (i = 0; i < poly->n_vertices; i++) { newp->v[i] = obstack_alloc(scratch, sizeof(Vertex)); HPt3Transform(T, &poly->v[i]->pt, &newp->v[i]->pt); if (poly->flags & PL_HASVCOL) { newp->v[i]->vcol = poly->v[i]->vcol; } if (poly->flags & PL_HASVN) { NormalTransform(Tdual, &poly->v[i]->vn, &newp->v[i]->vn); } if (poly->flags & PL_HASST) { TxSTTransform (TxT, &poly->v[i]->st, &newp->v[i]->st); } } if (poly->flags & PL_HASPCOL) { newp->pcol = poly->pcol; } if (poly->flags & PL_HASPN) { NormalTransform(Tdual, &poly->pn, &newp->pn); } newp->flags = poly->flags; return newp; }
/* Split the given polygon -- which must describe a quadrilateral -- * along the diagonal starting at "vertex". Used for splitting * non-flat or concave quadrilaterals. */ static inline void split_quad_poly(int vertex, Poly *poly0, PolyListNode **plist, const void **tagged_app, struct obstack *scratch) { PolyListNode *new_pn; Poly *poly[2]; Poly savedp; Vertex *savedv[4]; int i, v; if (poly0->flags & POLY_SCRATCH) { /* reuse the space */ savedp = *poly0; savedp.v = savedv; memcpy(savedp.v, poly0->v, 4*sizeof(Vertex *)); new_pn = new_poly_list_node(tagged_app, scratch); new_pn->poly = poly[0] = poly0; poly[0]->n_vertices = 3; ListPush(*plist, new_pn); poly0 = &savedp; } for (i = (poly0->flags & POLY_SCRATCH) != 0; i < 2; i++) { new_pn = new_poly_list_node(tagged_app, scratch); new_pn->poly = poly[i] = new_poly(3, NULL, scratch); ListPush(*plist, new_pn); } for (i = 0; i < 2; i++) { poly[i]->pcol = poly0->pcol; poly[i]->pn = poly0->pn; poly[i]->flags |= poly0->flags; } /* copy over vertex information, the _REAL_ poly normal will be * computed later, the need for that is flagged by POLY_SCRATCH. */ v = vertex; for (i = 0; i < 3; i++) { poly[0]->v[i] = poly0->v[v++]; v %= 4; } v = (v - 1 + 4) % 4; for (i = 0; i < 3; i++) { poly[1]->v[i] = poly0->v[v++]; v %= 4; } }
Polygon_2 CollisionDetector::translate_polygon_to(const Polygon_2& poly, const Point_2& new_ref_pt) const { m_translate_helper.resize(0); const Point_2 &ref = *poly.left_vertex(); std::pair<double,double> diff( //Vector_2 diff( CGAL::to_double(ref.x().exact()) - CGAL::to_double(new_ref_pt.x().exact()), CGAL::to_double(ref.y().exact()) - CGAL::to_double(new_ref_pt.y().exact()) ); for (Polygon_2::Vertex_const_iterator it = poly.vertices_begin(), it_end = poly.vertices_end(); it != it_end; ++it) { m_translate_helper.push_back( Point_2(CGAL::to_double(it->x()) + diff.first, CGAL::to_double(it->y()) + diff.second ) ); //translated.push_back( (*it) + diff ); } Polygon_2 new_poly(m_translate_helper.begin(),m_translate_helper.end()); return new_poly; }
polygon *get_healpix_poly(int nside, int hpix) { int nv, nvmax, i, pix_n, pix_e, pix_s, pix_w, ev[1]; vertices *vert; polygon *pixel, *pixelbetter; long double verts_vec[12], verts_vec_n[12], verts_vec_e[12], verts_vec_s[12], verts_vec_w[12], dist_n, dist_w, dist_s, dist_e; vec center, center_n, center_e, center_s, center_w, vertices_vec[4], vertices_vec_n[4], vertices_vec_e[4], vertices_vec_s[4], vertices_vec_w[4]; azel *vertices_azel[8], vertices[8]; for(i=0;i<=7;i++) vertices_azel[i] = &(vertices[i]); if (nside == 0) { pixel=new_poly(0); pixel->weight=1; pixel->pixel=0; return(pixel); } else { healpix_verts(nside, hpix, center, verts_vec); /* north vertex */ for(i=0;i<=2;i++) (vertices_vec[0])[i] = verts_vec[i]; /* east vertex */ for(i=0;i<=2;i++) (vertices_vec[1])[i] = verts_vec[i+3]; /* south vertex */ for(i=0;i<=2;i++) (vertices_vec[2])[i] = verts_vec[i+6]; /* west vertex */ for(i=0;i<=2;i++) (vertices_vec[3])[i] = verts_vec[i+9]; rp_to_azel(vertices_vec[0], vertices_azel[0]); rp_to_azel(vertices_vec[3], vertices_azel[2]); rp_to_azel(vertices_vec[2], vertices_azel[4]); rp_to_azel(vertices_vec[1], vertices_azel[6]); pix_n = 4*hpix + 3; pix_e = 4*hpix + 1; pix_s = 4*hpix; pix_w = 4*hpix + 2; healpix_verts(nside*2, pix_n, center_n, verts_vec_n); healpix_verts(nside*2, pix_e, center_e, verts_vec_e); healpix_verts(nside*2, pix_s, center_s, verts_vec_s); healpix_verts(nside*2, pix_w, center_w, verts_vec_w); /* north vertex of each child pixel */ for(i=0;i<=2;i++){ (vertices_vec_n[0])[i] = verts_vec_n[i]; (vertices_vec_e[0])[i] = verts_vec_e[i]; (vertices_vec_s[0])[i] = verts_vec_s[i]; (vertices_vec_w[0])[i] = verts_vec_w[i]; } /* east vertex of each child pixel */ for(i=0;i<=2;i++){ (vertices_vec_n[1])[i] = verts_vec_n[i+3]; (vertices_vec_e[1])[i] = verts_vec_e[i+3]; (vertices_vec_s[1])[i] = verts_vec_s[i+3]; (vertices_vec_w[1])[i] = verts_vec_w[i+3]; } /* south vertex of each child pixel */ for(i=0;i<=2;i++){ (vertices_vec_n[2])[i] = verts_vec_n[i+6]; (vertices_vec_e[2])[i] = verts_vec_e[i+6]; (vertices_vec_s[2])[i] = verts_vec_s[i+6]; (vertices_vec_w[2])[i] = verts_vec_w[i+6]; } /* west vertex of each child pixel */ for(i=0;i<=2;i++){ (vertices_vec_n[3])[i] = verts_vec_n[i+9]; (vertices_vec_e[3])[i] = verts_vec_e[i+9]; (vertices_vec_s[3])[i] = verts_vec_s[i+9]; (vertices_vec_w[3])[i] = verts_vec_w[i+9]; } rp_to_azel(vertices_vec_n[3], vertices_azel[1]); rp_to_azel(vertices_vec_w[2], vertices_azel[3]); rp_to_azel(vertices_vec_s[1], vertices_azel[5]); rp_to_azel(vertices_vec_e[0], vertices_azel[7]); for(i=0; i<8; i++){ if(vertices[i].az < 0.) vertices[i].az = vertices[i].az + TWOPI; else {}; } for(i=0; i<8; i++){ if(vertices[i].az >= TWOPI) vertices[i].az = vertices[i].az - TWOPI; else {}; } nv=8; nvmax=8; vert=new_vert(nvmax); if(!vert){ fprintf(stderr, "error in get_healpix_poly: failed to allocate memory for 8 vertices\n"); return(0x0); } vert->nv=nv; vert->v=&vertices[0]; pixel=new_poly(4); if(!pixel){ fprintf(stderr, "error in get_healpix_poly: failed to allocate memory for polygon of 4 caps\n"); return(0x0); } ev[0] = 8; edge_to_poly(vert, 2, &ev[0], pixel); pixel->id = (long long)hpix; pixelbetter=new_poly(5); if(!pixelbetter){ fprintf(stderr, "error in get_healpix_poly: failed to allocate memory for polygon of 5 caps\n"); return(0x0); } pixelbetter->np = 5; pixelbetter->npmax = 5; for(i=0; i<=3; i++) { pixelbetter->rp[i][0] = pixel->rp[i][0]; pixelbetter->rp[i][1] = pixel->rp[i][1]; pixelbetter->rp[i][2] = pixel->rp[i][2]; pixelbetter->cm[i] = pixel->cm[i]; } pixelbetter->rp[4][0] = center[0]; pixelbetter->rp[4][1] = center[1]; pixelbetter->rp[4][2] = center[2]; pixelbetter->id = (long long)hpix; dist_n = cmrpirpj(center, vertices_vec[0]); dist_w = cmrpirpj(center, vertices_vec[3]); dist_s = cmrpirpj(center, vertices_vec[2]); dist_e = cmrpirpj(center, vertices_vec[1]); if(dist_n>=dist_w && dist_n>=dist_s && dist_n>=dist_e){ pixelbetter->cm[4] = dist_n+0.000001; } else if(dist_w>=dist_n && dist_w>=dist_s && dist_w>=dist_e){ pixelbetter->cm[4] = dist_w+0.000001; } else if(dist_s>=dist_n && dist_s>=dist_w && dist_s>=dist_e){ pixelbetter->cm[4] = dist_s+0.000001; } else if(dist_e>=dist_n && dist_e>=dist_s && dist_e>=dist_w){ pixelbetter->cm[4] = dist_e+0.000001; } else{ fprintf(stderr, "error in get_healpix_poly: cannot find correct fifth cap\n"); return(0x0); } if(!pixelbetter){ fprintf(stderr, "error in get_healpix_poly: polygon is NULL.\n"); return(0x0); } return(pixelbetter); } }
int pixel_loop(int pix, int n, polygon *input[/*n*/], int out_max, polygon *output[/*out_max*/]){ int *child_pix,children; int i,j,k,m,out,nout; int ier, iprune, np; polygon *pixel; polygon **poly; //allocate memory for work array of polygon pointers poly=(polygon **) malloc(sizeof(polygon *) * n); if(!poly){ fprintf(stderr, "pixel_loop: failed to allocate memory for %d polygon pointers\n",n); return(-1); } // allocate memory for child_pix array if(pix==0 && scheme=='d'){ child_pix=(int *) malloc(sizeof(int) * 117); children=117; if(!child_pix){ fprintf(stderr, "pixel_loop: failed to allocate memory for 117 integers\n"); return(-1); } } else{ child_pix=(int *) malloc(sizeof(int) * 4); children=4; if(!child_pix){ fprintf(stderr, "pixel_loop: failed to allocate memory for %d integers\n", 4); return(-1); } } get_child_pixels(pix, child_pix, scheme); out=0; for(i=0;i<children;i++){ /*get the current child pixel*/ pixel=get_pixel(child_pix[i], scheme); if(!pixel){ fprintf(stderr, "error in pixel_loop: could not get pixel %d\n", child_pix[i]); return(-1); } /*loop through input polygons to find the ones that overlap with current child pixel*/ for(j=0;j<n;j++){ /* skip null polygons */ if (input[j]->np > 0 && input[j]->cm[0] == 0.){ poly[j] = 0x0; continue; } np=input[j]->np+pixel->np; poly[j]=new_poly(np); if(!poly[j]){ fprintf(stderr, "error in pixel_loop: failed to allocate memory for polygon of %d caps\n", np); return(-1); } /*set poly[j] to the intersection of input[j] and current child pixel*/ poly_poly(input[j],pixel,poly[j]); poly[j]->pixel=pixel->pixel; iprune = prune_poly(poly[j], mtol); if (iprune == -1) { fprintf(stderr, "pixelize: failed to prune polygon for pixel %d; continuing ...\n", poly[j]->pixel); //return(-1); } /*if polygon is null, get rid of it*/ if (iprune >= 2) { free_poly(poly[j]); poly[j] = 0x0; } } /*copy down non-null polygons*/ k=0; for(j=0;j<n;j++){ if(poly[j]){ poly[k++]=poly[j]; } } m=k; /*nullify the rest of the array, but don't free, since pointers have been copied above*/ for(j=m;j<n;j++){ poly[j]=0x0; } /*if we're below the max resolution, recursively call pixel_loop on the current child pixel */ if(m>polys_per_pixel && get_res(child_pix[i],scheme)<res_max){ //printf("calling pixel loop for pixel %d with %d polygons\n",child_pix[i],m); nout=pixel_loop(child_pix[i],m,poly,out_max-out,&output[out]); if(nout==-1) return(-1); out+=nout; } else{ for(k=0;k<m;k++){ /* check whether exceeded maximum number of polygons */ if (out >= out_max) { fprintf(stderr, "pixel_loop: total number of polygons exceeded maximum %d\n", NPOLYSMAX); fprintf(stderr, "if you need more space, enlarge NPOLYSMAX in defines.h, and recompile\n"); return(-1); } /*make sure output polygon has enough room */ ier = room_poly(&output[out], poly[k]->np, DNP, 0); if (ier == -1) { fprintf(stderr, "error in pixel_loop: failed to allocate memory for polygon of %d caps\n", poly[i]->np + DNP); return(-1); } /*copy polygon to output array*/ copy_poly(poly[k],output[out]); out++; } } /*free up memory for next child pixel*/ free_poly(pixel); for(j=0;j<n;j++){ free_poly(poly[j]); } } free(child_pix); free(poly); return out; }
void tess_vertex_data(Vertex *v, struct tess_data *data) { /* Here we have to do all the work, depending on what flag * previously has been passed to the begin() callback. */ if (data->vcnt == 0) { /* create a new polygon */ data->p = new_poly(3, NULL, data->scratch); data->p->flags |= data->polyflags; if (data->polyflags & FACET_C) { data->p->pcol = data->trickyp->pcol; } data->p->pn = *data->pn; /* always inherit the normal */ } switch (data->type) { case GL_TRIANGLES: /* the easy case */ /* add the vertex */ data->p->v[data->vcnt] = v; if (++data->vcnt == 3) { /* add the polygon to *data->plistp */ PolyListNode *new_pn; data->vcnt = 0; new_pn = new_poly_list_node(data->tagged_app, data->scratch); new_pn->poly = data->p; data->p = NULL; ListPush(*data->plistp, new_pn); } break; case GL_TRIANGLE_STRIP: /* pairs of triangles, all with the same orientation */ if (data->vcnt > 2) { /* create a new polygon */ data->p = new_poly(3, NULL, data->scratch); data->p->flags |= data->polyflags; if (data->polyflags & FACET_C) { data->p->pcol = data->trickyp->pcol; } data->p->pn = *data->pn; /* always inherit the normal */ data->p->v[0] = data->v[0]; data->p->v[1] = data->v[1]; /* add the vertex */ data->p->v[2] = v; } else { /* add the vertex */ data->p->v[data->vcnt] = v; } if (++data->vcnt > 2) { /* add the polygon to *data->plistp */ PolyListNode *new_pn; if (data->vcnt & 1) { data->v[0] = data->p->v[2]; data->v[1] = data->p->v[1]; } else { data->v[0] = data->p->v[0]; data->v[1] = data->p->v[2]; } new_pn = new_poly_list_node(data->tagged_app, data->scratch); new_pn->poly = data->p; ListPush(*data->plistp, new_pn); } break; case GL_TRIANGLE_FAN: if (data->vcnt > 2) { /* create a new polygon */ data->p = new_poly(3, NULL, data->scratch); data->p->flags |= data->polyflags; if (data->polyflags & FACET_C) { data->p->pcol = data->trickyp->pcol; } data->p->pn = *data->pn; /* always inherit the normal */ data->p->v[0] = data->v[0]; data->p->v[1] = data->v[1]; /* add the vertex */ data->p->v[2] = v; } else { if (data->vcnt == 0) { data->v[0] = v; } data->p->v[data->vcnt] = v; } if (++data->vcnt > 2) { /* add the polygon to *data->plistp */ PolyListNode *new_pn; data->v[1] = data->p->v[2]; new_pn = new_poly_list_node(data->tagged_app, data->scratch); new_pn->poly = data->p; ListPush(*data->plistp, new_pn); } break; default: break; } }
/* Convert a Mesh into linked list of PolyListNodes, subdivide * non-flat or concave quadrilaterals. */ static PolyListNode * MeshToLinkedPolyList(Transform T, Transform Tdual, Transform TxT, const void **tagged_app, PolyListNode **plistp, Mesh *mesh, struct obstack *scratch) { PolyListNode *plist = NULL; Poly *qpoly; int v0 = 1, prev0v = 0; int u0 = 1, prev0u = 0; int u, v, prevu, prevv; int concave; int i; if (!plistp) { plistp = &plist; } MeshComputeNormals(mesh, MESH_N); if(mesh->geomflags & MESH_UWRAP) { v0 = 0, prev0v = mesh->nv-1; } if(mesh->geomflags & MESH_VWRAP) { u0 = 0, prev0u = mesh->nu-1; } #define MESHIDX(u, v, mesh) ((v)*(mesh)->nu + (u)) qpoly = NULL; for(prevv = prev0v, v = v0; v < mesh->nv; prevv = v, v++) { for(prevu = prev0u, u = u0; u < mesh->nu; prevu = u, u++) { /* First try to create a single polygon, if that mesh-cell is * non-flat or concave, then sub-divide it. */ if (!qpoly) { qpoly = new_poly(4, NULL, scratch); for (i = 0; i < 4; i++) { qpoly->v[i] = obstack_alloc(scratch, sizeof(Vertex)); } } if (T && T != TM_IDENTITY) { meshv_to_polyv_trans(T, Tdual, TxT, qpoly->v[0], mesh, MESHIDX(prevu, prevv, mesh)); meshv_to_polyv_trans(T, Tdual, TxT, qpoly->v[1], mesh, MESHIDX(u, prevv, mesh)); meshv_to_polyv_trans(T, Tdual, TxT, qpoly->v[2], mesh, MESHIDX(u, v, mesh)); meshv_to_polyv_trans(T, Tdual, TxT, qpoly->v[3], mesh, MESHIDX(prevu, v, mesh)); } else { meshv_to_polyv(qpoly->v[0], mesh, MESHIDX(prevu, prevv, mesh)); meshv_to_polyv(qpoly->v[1], mesh, MESHIDX(u, prevv, mesh)); meshv_to_polyv(qpoly->v[2], mesh, MESHIDX(u, v, mesh)); meshv_to_polyv(qpoly->v[3], mesh, MESHIDX(prevu, v, mesh)); } if (mesh->geomflags & MESH_C) { qpoly->flags |= PL_HASVCOL; } if (mesh->geomflags & COLOR_ALPHA) { qpoly->flags |= COLOR_ALPHA; } if (mesh->geomflags & MESH_N) { qpoly->flags |= PL_HASVN; } if (mesh->geomflags & MESH_U) { qpoly->flags |= PL_HASST; } PolyNormal(qpoly, &qpoly->pn, mesh->geomflags & VERT_4D, false, &qpoly->flags, &concave); qpoly->flags |= PL_HASPN; if (qpoly->flags & POLY_NOPOLY) { /* polygon is degenerated, we just do NOT draw it, edges are * drawn by other methods. Just do nothing, qpoly will be * re-used for the next quad. */ qpoly->flags = 0; } else if (qpoly->flags & (POLY_CONCAVE|POLY_NONFLAT)) { /* we need to split it */ split_quad_poly(concave, qpoly, plistp, tagged_app, scratch); qpoly = NULL; } else { PolyListNode *new_pn; new_pn = new_poly_list_node(tagged_app, scratch); new_pn->poly = qpoly; ListPush(*plistp, new_pn); qpoly = NULL; } } } #undef MESHIDX return *plistp; }
static PolyListNode * QuadToLinkedPolyList(Transform T, Transform Tdual, Transform TxT, const void **tagged_app, PolyListNode **plistp, Quad *quad, struct obstack *scratch) { PolyListNode *plist = NULL; Poly *qpoly; int i, j, concave; (void)Tdual; (void)TxT; if (!plistp) { plistp = &plist; } if(!(quad->geomflags & QUAD_N)) { QuadComputeNormals(quad); } qpoly = NULL; for (i = 0; i < quad->maxquad; i++) { /* First try to create a single polygon, if that mesh-cell is * non-flat or concave, then sub-divide it. */ if (!qpoly) { qpoly = new_poly(4, NULL, scratch); for (j = 0; j < 4; j++) { qpoly->v[j] = obstack_alloc(scratch, sizeof(Vertex)); } } if (T && T != TM_IDENTITY) { for (j = 0; j < 4; j++) { memset(qpoly->v[j], 0, sizeof(Vertex)); HPt3Transform(T, &quad->p[i][j], &qpoly->v[j]->pt); NormalTransform(T, &quad->n[i][j], &qpoly->v[j]->vn); } } else { for (j = 0; j < 4; j++) { memset(qpoly->v[j], 0, sizeof(Vertex)); qpoly->v[j]->pt = quad->p[i][j]; qpoly->v[j]->vn = quad->n[i][j]; } } qpoly->flags |= PL_HASVN; if (quad->geomflags & QUAD_C) { qpoly->flags |= PL_HASVCOL; for (j = 0; j < 4; j++) { qpoly->v[j]->vcol = quad->c[i][j]; } } if (quad->geomflags & COLOR_ALPHA) { qpoly->flags |= COLOR_ALPHA; } PolyNormal(qpoly, &qpoly->pn, quad->geomflags & VERT_4D, false, &qpoly->flags, &concave); qpoly->flags |= PL_HASPN; if (qpoly->flags & POLY_NOPOLY) { /* degenerated, skip it, but reuse the memory region. */ qpoly->flags = 0; } else if (qpoly->flags & (POLY_CONCAVE|POLY_NONFLAT)) { /* we need to split it */ split_quad_poly(concave, qpoly, plistp, tagged_app, scratch); qpoly = NULL; } else { PolyListNode *new_pn; new_pn = new_poly_list_node(tagged_app, scratch); new_pn->poly = qpoly; ListPush(*plistp, new_pn); qpoly = NULL; } } return *plistp; }
/* Split plnode along plane. We know that plane really intersects * plnode->poly. We also know that plnode->poly is planar and convex. * * Given this assumptions we know that plnode->poly has to be split * into exactly two pieces. */ static inline void SplitPolyNode(PolyListNode *plnode, PolyListNode **front, PolyListNode **back, EdgeIntersection edges[2], struct obstack *scratch) { const void **tagged_app = plnode->tagged_app; Poly *poly = plnode->poly, savedp; VARARRAY(savedv, Vertex *, poly->n_vertices); Vertex *v0, *v1, **vpos; int istart[2], iend[2], i, nv[2]; Vertex *vstart[2], *vend[2]; #if BSPTREE_STATS ++n_tree_polys; #endif vstart[0] = vstart[1] = vend[0] = vend[1] = NULL; istart[0] = istart[1] = iend[0] = iend[1] = -1; /* first point of intersection */ if (fzero(edges[0].scp[0])) { v0 = poly->v[edges[0].v[0]]; if (fpos(edges[0].scp[1])) { istart[0] = edges[0].v[0]; iend[1] = edges[0].v[0]; } else { istart[1] = edges[0].v[0]; iend[0] = edges[0].v[0]; } } else if (fzero(edges[0].scp[1])) { v0 = poly->v[edges[0].v[1]]; if (fpos(edges[0].scp[0])) { istart[1] = edges[0].v[1]; iend[0] = edges[0].v[1]; } else { istart[0] = edges[0].v[1]; iend[1] = edges[0].v[1]; } } else { HPt3Coord mu0, mu1; Vertex *V0 = poly->v[edges[0].v[0]]; Vertex *V1 = poly->v[edges[0].v[1]]; v0 = obstack_alloc(scratch, sizeof(Vertex)); mu0 = edges[0].scp[1]/(edges[0].scp[1]-edges[0].scp[0]); #if 0 mu1 = edges[0].scp[0]/(edges[0].scp[0]-edges[0].scp[1]); #else mu1 = 1.0 - mu0; #endif /* Use denormalized variant; otherwise textures may come out wrong * because the homogeneous divisor is used for perspective * corrections. */ if (poly->flags & VERT_ST) { v0->st.s = mu0 * V0->st.s + mu1 * V1->st.s; v0->st.t = mu0 * V0->st.t + mu1 * V1->st.t; HPt3LinSumDenorm(mu0, &V0->pt, mu1, &V1->pt, &v0->pt); } else { HPt3LinSum(mu0, &V0->pt, mu1, &V1->pt, &v0->pt); } if (!finite(v0->pt.x + v0->pt.y + v0->pt.z)){ abort(); } if (poly->flags & VERT_C) { CoLinSum(mu0, &V0->vcol, mu1, &V1->vcol, &v0->vcol); } if (true || (poly->flags & VERT_N)) { /* The averaged vertex normals do not have an orientation, so * try to orient them w.r.t. the polygon normal before computing * the linear combination. */ if (Pt3Dot(&V0->vn, &poly->pn)*Pt3Dot(&V1->vn, &poly->pn) < 0) { Pt3Comb(-mu0, &V0->vn, mu1, &V1->vn, &v0->vn); } else { Pt3Comb(mu0, &V0->vn, mu1, &V1->vn, &v0->vn); } Pt3Unit(&v0->vn); } if (fpos(edges[0].scp[0])) { vstart[1] = vend[0] = v0; istart[1] = edges[0].v[1]; iend[0] = edges[0].v[0]; } else { vstart[0] = vend[1] = v0; istart[0] = edges[0].v[1]; iend[1] = edges[0].v[0]; } } /* second point of intersection */ if (fzero(edges[1].scp[0])) { v1 = poly->v[edges[1].v[0]]; if (fpos(edges[1].scp[1])) { istart[0] = edges[1].v[0]; iend[1] = edges[1].v[0]; } else { istart[1] = edges[1].v[0]; iend[0] = edges[1].v[0]; } } else if (fzero(edges[1].scp[1])) { v1 = poly->v[edges[1].v[1]]; if (fpos(edges[1].scp[0])) { istart[1] = edges[1].v[1]; iend[0] = edges[1].v[1]; } else { istart[0] = edges[1].v[1]; iend[1] = edges[1].v[1]; } } else { HPt3Coord mu0, mu1; Vertex *V0 = poly->v[edges[1].v[0]]; Vertex *V1 = poly->v[edges[1].v[1]]; v1 = obstack_alloc(scratch, sizeof(Vertex)); mu0 = edges[1].scp[1]/(edges[1].scp[1]-edges[1].scp[0]); #if 0 mu1 = edges[1].scp[0]/(edges[1].scp[0]-edges[1].scp[1]); #else mu1 = 1.0 - mu0; #endif if (poly->flags & VERT_ST) { v1->st.s = mu0 * V0->st.s + mu1 * V1->st.s; v1->st.t = mu0 * V0->st.t + mu1 * V1->st.t; HPt3LinSumDenorm(mu0, &V0->pt, mu1, &V1->pt, &v1->pt); } else { HPt3LinSum(mu0, &V0->pt, mu1, &V1->pt, &v1->pt); } if (!finite(v1->pt.x + v1->pt.y + v1->pt.z)) abort(); if (poly->flags & VERT_C) { CoLinSum(mu0, &V0->vcol, mu1, &V1->vcol, &v1->vcol); } if (true || (poly->flags & VERT_N)) { if (Pt3Dot(&V0->vn, &poly->pn)*Pt3Dot(&V1->vn, &poly->pn) < 0) { Pt3Comb(-mu0, &V0->vn, mu1, &V1->vn, &v1->vn); } else { Pt3Comb(mu0, &V0->vn, mu1, &V1->vn, &v1->vn); } Pt3Unit(&v1->vn); } if (fpos(edges[1].scp[0])) { vstart[1] = vend[0] = v1; istart[1] = edges[1].v[1]; iend[0] = edges[1].v[0]; } else { vstart[0] = vend[1] = v1; istart[0] = edges[1].v[1]; iend[1] = edges[1].v[0]; } } ListPush(*front, plnode); ListPush(*back, new_poly_list_node(tagged_app, scratch)); if ((poly->flags & POLY_NONFLAT)) { if (!(*front)->pn) { /* Compute the normal on the parent element to avoid numerical * instabilities on increasingly degenerated polygons. */ (*front)->pn = obstack_alloc(scratch, sizeof(Point3)); PolyNormal(poly, (*front)->pn, true /* 4d */, false /* evert */, NULL, NULL); } (*back)->pn = (*front)->pn; } for (i = 0; i < 2; i++) { nv[i] = iend[i] - istart[i] + 1; if (nv[i] < 0) { nv[i] += poly->n_vertices; } nv[i] += (vstart[i] != NULL) + (vend[i] != NULL); } if (poly->flags & POLY_SCRATCH) { savedp = *poly; memcpy(savedv, poly->v, poly->n_vertices*sizeof(Vertex *)); if (nv[0] <= poly->n_vertices) { poly->n_vertices = nv[0]; (*front)->poly = poly; (*back)->poly = new_poly(nv[1], NULL, scratch); } else { if (nv[1] > poly->n_vertices) { abort(); } poly->n_vertices = nv[1]; (*back)->poly = poly; (*front)->poly = new_poly(nv[0], NULL, scratch); } /* Attention: gcc had problems with this code snippet with * -fstrict-aliasing, the "#if 1" stuff seems to work. In the * "#else" version gcc somehow lost the "savedp.v = savedv" * assignment. I think this is a compiler bug. */ poly = &savedp; #if 1 poly->v = savedv; #else savedp.v = savedv; #endif } else { (*front)->poly = new_poly(nv[0], NULL, scratch); (*back)->poly = new_poly(nv[1], NULL, scratch); } for (i = 0; i < 2; i++) { PolyListNode *half = (i == 0) ? *front : *back; int j; vpos = half->poly->v; if (vstart[i] != NULL) { *vpos++ = vstart[i]; } if (istart[i] <= iend[i]) { for (j = istart[i]; j <= iend[i] && j < poly->n_vertices; j++) { *vpos++ = poly->v[j]; } } else { for (j = istart[i]; j < poly->n_vertices; j++) { *vpos++ = poly->v[j]; } for (j = 0; j <= iend[i]; j++) { *vpos++ = poly->v[j]; } } if (vend[i] != NULL) { *vpos++ = vend[i]; } half->poly->pcol = poly->pcol; half->poly->pn = poly->pn; half->poly->flags = poly->flags|POLY_SCRATCH; check_poly(half->poly); } }