/* Find convex hull vertex to complete triangle (oriented call) */ static RBFNODE * find_chull_vert(const RBFNODE *rbf0, const RBFNODE *rbf1) { FVECT vmid, vejn, vp; RBFNODE *rbf, *rbfbest = NULL; double dprod, area2, bestarea2 = FHUGE, bestdprod = -.5; VSUB(vejn, rbf1->invec, rbf0->invec); VADD(vmid, rbf0->invec, rbf1->invec); if (normalize(vejn) == 0 || normalize(vmid) == 0) return(NULL); /* XXX exhaustive search */ /* Find triangle with minimum rotation from perpendicular */ for (rbf = dsf_list; rbf != NULL; rbf = rbf->next) { if ((rbf == rbf0) | (rbf == rbf1)) continue; tri_orient(vp, rbf0->invec, rbf1->invec, rbf->invec); if (DOT(vp, vmid) <= FTINY) continue; /* wrong orientation */ area2 = .25*DOT(vp,vp); VSUB(vp, rbf->invec, vmid); dprod = -DOT(vp, vejn); VSUM(vp, vp, vejn, dprod); /* above guarantees non-zero */ dprod = DOT(vp, vmid) / VLEN(vp); if (dprod <= bestdprod + FTINY*(1 - 2*(area2 < bestarea2))) continue; /* found better already */ if (overlaps_tri(rbf0, rbf1, rbf)) continue; /* overlaps another triangle */ rbfbest = rbf; bestdprod = dprod; /* new one to beat */ bestarea2 = area2; } return(rbfbest); }
static int ambcollision( /* proposed direciton collides? */ AMBHEMI *hp, int i, int j, FVECT dv ) { double cos_thresh; int ii, jj; /* min. spacing = 1/4th division */ cos_thresh = (PI/4.)/(double)hp->ns; cos_thresh = 1. - .5*cos_thresh*cos_thresh; /* check existing neighbors */ for (ii = i-1; ii <= i+1; ii++) { if (ii < 0) continue; if (ii >= hp->ns) break; for (jj = j-1; jj <= j+1; jj++) { AMBSAMP *ap; FVECT avec; double dprod; if (jj < 0) continue; if (jj >= hp->ns) break; if ((ii==i) & (jj==j)) continue; ap = &ambsam(hp,ii,jj); if (ap->d <= .5/FHUGE) continue; /* no one home */ VSUB(avec, ap->p, hp->rp->rop); dprod = DOT(avec, dv); if (dprod >= cos_thresh*VLEN(avec)) return(1); /* collision */ } } return(0); /* nothing to worry about */ }
QSE_INLINE void qse_rbt_freepair (rbt_t* rbt, pair_t* pair) { if (rbt->style->freeer[QSE_RBT_KEY] != QSE_NULL) rbt->style->freeer[QSE_RBT_KEY] (rbt, KPTR(pair), KLEN(pair)); if (rbt->style->freeer[QSE_RBT_VAL] != QSE_NULL) rbt->style->freeer[QSE_RBT_VAL] (rbt, VPTR(pair), VLEN(pair)); QSE_MMGR_FREE (rbt->mmgr, pair); }
static void add_holo( /* register a new holodeck section */ HDGRID *hdg, char *gfn, char *pfn ) { VIEW nv; double d; register int hd; for (hd = 0; hd < HDMAX && hdlist[hd] != NULL; hd++) ; if (hd >= HDMAX) error(INTERNAL, "too many holodeck sections in add_holo"); hdlist[hd] = (HOLO *)malloc(sizeof(HOLO)); if (hdlist[hd] == NULL) error(SYSTEM, "out of memory in add_holo"); memcpy((void *)hdlist[hd], (void *)hdg, sizeof(HDGRID)); hdcompgrid(hdlist[hd]); hdgfn[hd] = savestr(gfn); hdpfn[hd] = pfn && *pfn ? savestr(pfn) : (char *)NULL; if (hd) return; /* set initial viewpoint */ nv = odev.v; VSUM(nv.vp, hdlist[0]->orig, hdlist[0]->xv[0], 0.5); VSUM(nv.vp, nv.vp, hdlist[0]->xv[1], 0.5); VSUM(nv.vp, nv.vp, hdlist[0]->xv[2], 0.5); fcross(nv.vdir, hdlist[0]->xv[1], hdlist[0]->xv[2]); VCOPY(nv.vup, hdlist[0]->xv[2]); if (do_outside) { normalize(nv.vdir); d = VLEN(hdlist[0]->xv[1]); d += VLEN(hdlist[0]->xv[2]); VSUM(nv.vp, nv.vp, nv.vdir, -d); } new_view(&nv); }
void hdcompgrid( /* compute derived grid vector and index */ HOLO *hp ) { double d; int i, j; /* initialize depth map */ if (hd_depthmap[0] < 1.) { d = 1. + .5/DCLIN; for (i = 0; i < DCINF-DCLIN; i++) { hd_depthmap[i] = d; d *= 1. + 1./DCLIN; } logstep = log(1. + 1./DCLIN); } /* compute grid coordinate vectors */ for (i = 0; i < 3; i++) { fcross(hp->wg[i], hp->xv[(i+1)%3], hp->xv[(i+2)%3]); d = DOT(hp->wg[i],hp->xv[i]); if ((d <= FTINY) & (d >= -FTINY)) error(USER, "degenerate holodeck section"); d = hp->grid[i] / d; hp->wg[i][0] *= d; hp->wg[i][1] *= d; hp->wg[i][2] *= d; } /* compute linear depth range */ hp->tlin = VLEN(hp->xv[0]) + VLEN(hp->xv[1]) + VLEN(hp->xv[2]); /* compute wall super-indices from grid */ hp->wi[0] = 1; /**** index values begin at 1 ****/ for (i = 1; i < 6; i++) { hp->wi[i] = 0; for (j = i; j < 6; j++) hp->wi[i] += hp->grid[hdwg0[j]] * hp->grid[hdwg1[j]]; hp->wi[i] *= hp->grid[hdwg0[i-1]] * hp->grid[hdwg1[i-1]]; hp->wi[i] += hp->wi[i-1]; } }
static double l_psize(char *nm) /* compute pixel size in steradians */ { static unsigned long ltick[MAXINP]; static double psize[MAXINP]; FVECT dir0, org, dirx, diry; RREAL locx[2], locy[2]; double d; int fn; register int i; d = argument(1); if (d <= -0.5 || d >= nfiles+0.5) { errno = EDOM; return(0.0); } if (d < 0.5) return((double)nfiles); fn = d - 0.5; if (ltick[fn] != eclock) { /* need to compute? */ psize[fn] = 0.0; if (input[fn].vw.type == 0) errno = EDOM; else if (input[fn].vw.type != VT_PAR && funvalue(vray[6], 1, &d) >= -FTINY) { for (i = 0; i < 3; i++) dir0[i] = funvalue(vray[3+i], 1, &d); pix2loc(locx, &input[fn].rs, xscan+1, ymax-1-yscan); pix2loc(locy, &input[fn].rs, xscan, ymax-yscan); if (viewray(org, dirx, &input[fn].vw, locx[0], locx[1]) >= -FTINY && viewray(org, diry, &input[fn].vw, locy[0], locy[1]) >= -FTINY) { /* approximate solid angle */ for (i = 0; i < 3; i++) { dirx[i] -= dir0[i]; diry[i] -= dir0[i]; } fcross(dir0, dirx, diry); psize[fn] = VLEN(dir0); } } ltick[fn] = eclock; } return(psize[fn]); }
R8 V1AIpart( const IX nv, const VERTEX3D p2[], const VERTEX3D *p1, const DIRCOS *u1 ) /* nv number of vertices/edges of surface (polygon) P2 * p2 coordinates of vertices of surface (polygon) P2 * p1 coordinates of surface (point) P1 * u1 components of unit vector normal to surface P1 */ { IX n; /* edge number */ VECTOR3D A, /* A = vector from P1 to P2[n-1]; |A| > 0 */ B, /* B = vector from P1 to P2[n]; |B| > 0 */ C; /* C = vector cross product of A and B */ R8 UdotC; /* dot product of U and C; always >= 0 */ R8 sum=0; /* sum of line integrals */ /* Initialization */ n = nv - 1; VECTOR( p1, (p2+n), (&B) ); /* vector B */ /* For all edges of polygon p2: */ for( n=0; n<nv; n++ ) { VCOPY( (&B), (&A) ); /* A = old B */ VECTOR( p1, (p2+n), (&B) ); /* vector B */ VCROSS( (&A), (&B), (&C) ); /* C = A cross B */ UdotC = VDOT( u1, (&C) ); /* U dot C */ if( fabs(UdotC) > EPS2 ) { R8 Clen = VLEN( (&C) ); /* | C | */ if( Clen > EPS2 ) { /* gamma = angle between A and B; 0 < gamma < 180 */ R8 gamma = PId2 - atan( VDOT( (&A), (&B) ) / Clen ); sum += UdotC * gamma / Clen; } else error( 3, __FILE__, __LINE__, "View1AI failed, call George", "" ); } } /* end edge loop */ sum *= PIt2inv; /* Divide by 2*pi */ return sum; } /* end of V1AIpart
int i_cyl( /* translate a cylinder description */ int ac, char **av ) { register C_VERTEX *v1, *v2; FVECT va; double length, angle; if (ac != 4) return(MG_EARGC); flush_cache(); /* flush vertex cache */ printf("%sSeparator {\n", tabs); indent(1); /* put out current material */ if (put_material() < 0) return(MG_EBADMAT); /* get endpoints */ if (((v1 = c_getvert(av[1])) == NULL) | ((v2 = c_getvert(av[3])) == NULL)) return(MG_EUNDEF); /* get radius */ if (!isflt(av[2])) return(MG_ETYPE); /* compute transform */ va[0] = v2->p[0] - v1->p[0]; va[1] = v2->p[1] - v1->p[1]; va[2] = v2->p[2] - v1->p[2]; length = VLEN(va); angle = Acos(va[1]/length); printf("%sTranslation { translation %13.9g %13.9g %13.9g }\n", tabs, .5*(v1->p[0]+v2->p[0]), .5*(v1->p[1]+v2->p[1]), .5*(v1->p[2]+v2->p[2])); printf("%sRotation { rotation %.9g %.9g %.9g %.9g }\n", tabs, va[2], 0., -va[0], angle); /* open-ended */ printf("%sCylinder { parts SIDES height %13.9g radius %s }\n", tabs, length, av[2]); indent(0); printf("%s}\n", tabs); return(MG_OK); }
int gc_set_config_repl(generic_cache_t *gc, const char *repl) { repl_interface_t *ri; int i = 0; if (!VLEN(repl_policies)) { SIM_log_error(&gc->log, GC_Log_Repl, "Cache has no replacement policies registered."); return -1; } ri = VGET(repl_policies, i); while (ri != NULL) { if (strcmp(repl, ri->get_name()) == 0) { MM_FREE(gc->config.repl_data); memcpy(&gc->config.repl_fun, ri, sizeof(*ri)); gc->config.repl_data = gc->config.repl_fun.new_instance(gc); gc->config.repl_fun.update_config( gc->config.repl_data, gc); return 0; } i++; ri = VGET(repl_policies, i); } SIM_log_info(1, &gc->log, GC_Log_Repl, "replacement: possible values are :"); i = 0; ri = VGET(repl_policies, i); while (ri != NULL) { SIM_log_info(1, &gc->log, GC_Log_Repl, " %s", ri->get_name()); i++; ri = VGET(repl_policies, i); } return -1; }
void HUDPosition(LWViewportInfo *ViewGlobal, int view, LWDVector pos, const LWDVector dir) { int type, ax = 0; double Near, Far, norm, z; type = ViewGlobal->type(view); ViewGlobal->clip(view, &Near, &Far); ViewGlobal->pos(view, pos); switch(type) { case LVVIEWT_BACK: case LVVIEWT_FRONT: ax++; // fallthrough: ax-> 2 case LVVIEWT_TOP: case LVVIEWT_BOTTOM: ax++; // fallthrough: ax-> 1 case LVVIEWT_RIGHT: case LVVIEWT_LEFT: pos[ax] = 0.5*(Near+Far); break; case LVVIEWT_PERSPECTIVE: case LVVIEWT_LIGHT: case LVVIEWT_CAMERA: z = HUD_Depth(ViewGlobal, view); norm = VLEN(dir); if(norm>0) norm = 1.0/norm; norm *= z; VADDS(pos, dir, norm); break; case LVVIEWT_SCHEMATIC: case LVVIEWT_NONE: default: VCLR(pos); break; } }
R8 Triangle( VERTEX3D *p1, VERTEX3D *p2, VERTEX3D *p3, void *dc, IX dcflag ) /* p1 - X, Y, & Z coordinates of point P1. * p2 - X, Y, & Z coordinates of point P2. * p3 - X, Y, & Z coordinates of point P3. * c - X, Y, & Z components of direction cosines vector "C". */ { VECTOR3D a, b, *c=(void *)dc; R8 r; /* length of "C" (= twice the area of triangle P1-P2-P3) */ VECTOR( p2, p3, (&a) ); VECTOR( p2, p1, (&b) ); VCROSS( (&a), (&b), c ); r = VLEN( c ); if( dcflag ) /* compute direction cosines */ { if( r <= 1.e-12 ) { fprintf( _ulog, "Vertices:\n" ); fprintf( _ulog, " %f %f %f\n", p1->x, p1->y, p1->z ); fprintf( _ulog, " %f %f %f\n", p2->x, p2->y, p2->z ); fprintf( _ulog, " %f %f %f\n", p3->x, p3->y, p3->z ); error( 3, __FILE__, __LINE__, "Vertices give invalid area, surface ", IntStr(dcflag), "" ); } c->x /= r; /* reduce C to unit length */ c->y /= r; c->z /= r; } #ifdef XXX fprintf( _ulog, " DC: %f %f %f; A: %f\n", c->x, c->y, c->z, 0.5*r ); #endif return (0.5f * r); } /* end of Triangle */
void viewloc( /* find image location for point */ FVECT ip, VIEW *v, FVECT p ) { double d, d2; FVECT disp; VSUB(disp, p, v->vp); switch (v->type) { case VT_PAR: /* parallel view */ ip[2] = DOT(disp,v->vdir) - v->vfore; break; case VT_PER: /* perspective view */ d = DOT(disp,v->vdir); ip[2] = VLEN(disp); if (d < 0.0) { /* fold pyramid */ ip[2] = -ip[2]; d = -d; } if (d > FTINY) { d = 1.0/d; disp[0] *= d; disp[1] *= d; disp[2] *= d; } ip[2] *= (1.0 - v->vfore*d); break; case VT_HEM: /* hemispherical fisheye */ d = normalize(disp); if (DOT(disp,v->vdir) < 0.0) ip[2] = -d; else ip[2] = d; ip[2] -= v->vfore; break; case VT_CYL: /* cylindrical panorama */ d = DOT(disp,v->hvec); d2 = DOT(disp,v->vdir); ip[0] = 180.0/PI * atan2(d,d2) / v->horiz + 0.5 - v->hoff; d = 1.0/sqrt(d*d + d2*d2); ip[1] = DOT(disp,v->vvec)*d/v->vn2 + 0.5 - v->voff; ip[2] = VLEN(disp); ip[2] *= (1.0 - v->vfore*d); return; case VT_ANG: /* angular fisheye */ ip[0] = 0.5 - v->hoff; ip[1] = 0.5 - v->voff; ip[2] = normalize(disp) - v->vfore; d = DOT(disp,v->vdir); if (d >= 1.0-FTINY) return; if (d <= -(1.0-FTINY)) { ip[0] += 180.0/v->horiz; return; } d = (180.0/PI)*acos(d) / sqrt(1.0 - d*d); ip[0] += DOT(disp,v->hvec)*d/v->horiz; ip[1] += DOT(disp,v->vvec)*d/v->vert; return; case VT_PLS: /* planispheric fisheye */ ip[0] = 0.5 - v->hoff; ip[1] = 0.5 - v->voff; ip[2] = normalize(disp) - v->vfore; d = DOT(disp,v->vdir); if (d >= 1.0-FTINY) return; if (d <= -(1.0-FTINY)) return; /* really an error */ ip[0] += DOT(disp,v->hvec)/((1. + d)*sqrt(v->hn2)); ip[1] += DOT(disp,v->vvec)/((1. + d)*sqrt(v->vn2)); return; } ip[0] = DOT(disp,v->hvec)/v->hn2 + 0.5 - v->hoff; ip[1] = DOT(disp,v->vvec)/v->vn2 + 0.5 - v->voff; }
IX Subsurface( SRFDAT3X *srf, SRFDAT3X sub[] ) { IX nSubSrf; /* number of subsurfaces */ VERTEX3D tmpVrt; /* temporary vertex */ VECTOR3D edge[4]; /* quadrilateral edge vectors */ R8 edgeLength[4]; /* lengths of edges */ R8 cosAngle[4]; /* cosines of angles */ IX obtuse=0; /* identifies obtuse angles */ IX i, j, k; if( srf->shape > 0 ) /* triangle or parallelogram */ { memcpy( sub+0, srf, sizeof(SRFDAT3X) ); /* no subdivision */ sub[0].nr = 0; nSubSrf = 1; } else if( srf->nv==4 ) /* convex quadrilateral */ { for( j=0,i=1; j<4; j++,i++ ) /* compute edge vectors and lengths */ { i &= 3; /* equivalent to: if( i==4 ) i = 0; in this context */ VECTOR( (srf->v+i), (srf->v+j), (edge+j) ); edgeLength[j] = VLEN( (edge+j) ); } for( k=1,j=0,i=3; j<4; j++,i++,k*=2 ) /* compute corner angles */ { i &= 3; /* A dot B = |A|*|B|*cos(angle) */ cosAngle[j] = -VDOT( (edge+j), (edge+i) ) / ( edgeLength[j] * edgeLength[i] ); if( cosAngle[j] < 0.0 ) /* angle > 90 if cos(angle) < 0 */ obtuse += k; } #if( DEBUG > 1 ) for( j=0; j<4; j++ ) { fprintf( _ulog, " edge %d: (%f %f %f) L %f, C %f (%.3f deg)\n", j+1, edge[j].x, edge[j].y, edge[j].z, edgeLength[j], cosAngle[j], acos(cosAngle[j])*RTD ); } fprintf( _ulog, " quadrilateral, case %d\n", obtuse ); fflush( _ulog ); #endif switch (obtuse) /* divide based on number and positions of obtuse angles */ { case 0: /* rectangle */ memcpy( sub+0, srf, sizeof(SRFDAT3X) ); /* no subdivision */ sub[0].nr = 0; nSubSrf = 1; break; case 1: /* only angle 0 is obtuse */ case 4: /* only angle 2 is obtuse */ case 5: /* angles 0 and 2 are obtuse */ case 7: /* angles 0, 1, and 2 are obtuse */ case 13: /* angles 0, 2, and 3 are obtuse */ VCOPY( (srf->v+0), (sub[0].v+0) ); VCOPY( (srf->v+1), (sub[0].v+1) ); VCOPY( (srf->v+2), (sub[0].v+2) ); VCOPY( (srf->v+2), (sub[1].v+0) ); VCOPY( (srf->v+3), (sub[1].v+1) ); VCOPY( (srf->v+0), (sub[1].v+2) ); nSubSrf = 2; break; case 2: /* only angle 1 is obtuse */ case 8: /* only angle 3 is obtuse */ case 10: /* angles 1 and 3 are obtuse */ case 11: /* angles 0, 1, and 3 are obtuse */ case 14: /* angles 1, 2, and 3 are obtuse */ VCOPY( (srf->v+1), (sub[0].v+0) ); VCOPY( (srf->v+2), (sub[0].v+1) ); VCOPY( (srf->v+3), (sub[0].v+2) ); VCOPY( (srf->v+3), (sub[1].v+0) ); VCOPY( (srf->v+0), (sub[1].v+1) ); VCOPY( (srf->v+1), (sub[1].v+2) ); nSubSrf = 2; break; case 3: /* angles 0 and 1 are obtuse */ tmpVrt.x = 0.5f * (srf->v[2].x + srf->v[3].x ); tmpVrt.y = 0.5f * (srf->v[2].y + srf->v[3].y ); tmpVrt.z = 0.5f * (srf->v[2].z + srf->v[3].z ); VCOPY( (srf->v+3), (sub[0].v+0) ); VCOPY( (srf->v+0), (sub[0].v+1) ); VCOPY( (&tmpVrt), (sub[0].v+2) ); VCOPY( (srf->v+0), (sub[1].v+0) ); VCOPY( (srf->v+1), (sub[1].v+1) ); VCOPY( (&tmpVrt), (sub[1].v+2) ); VCOPY( (srf->v+1), (sub[2].v+0) ); VCOPY( (srf->v+2), (sub[2].v+1) ); VCOPY( (&tmpVrt), (sub[2].v+2) ); nSubSrf = 3; break; case 6: /* angles 1 and 2 are obtuse */ tmpVrt.x = 0.5f * (srf->v[0].x + srf->v[3].x ); tmpVrt.y = 0.5f * (srf->v[0].y + srf->v[3].y ); tmpVrt.z = 0.5f * (srf->v[0].z + srf->v[3].z ); VCOPY( (srf->v+0), (sub[0].v+0) ); VCOPY( (srf->v+1), (sub[0].v+1) ); VCOPY( (&tmpVrt), (sub[0].v+2) ); VCOPY( (srf->v+1), (sub[1].v+0) ); VCOPY( (srf->v+2), (sub[1].v+1) ); VCOPY( (&tmpVrt), (sub[1].v+2) ); VCOPY( (srf->v+2), (sub[2].v+0) ); VCOPY( (srf->v+3), (sub[2].v+1) ); VCOPY( (&tmpVrt), (sub[2].v+2) ); nSubSrf = 3; break; case 9: /* angles 0 and 3 are obtuse */ tmpVrt.x = 0.5f * (srf->v[1].x + srf->v[2].x ); tmpVrt.y = 0.5f * (srf->v[1].y + srf->v[2].y ); tmpVrt.z = 0.5f * (srf->v[1].z + srf->v[2].z ); VCOPY( (srf->v+2), (sub[0].v+0) ); VCOPY( (srf->v+3), (sub[0].v+1) ); VCOPY( (&tmpVrt), (sub[0].v+2) ); VCOPY( (srf->v+3), (sub[1].v+0) ); VCOPY( (srf->v+0), (sub[1].v+1) ); VCOPY( (&tmpVrt), (sub[1].v+2) ); VCOPY( (srf->v+0), (sub[2].v+0) ); VCOPY( (srf->v+1), (sub[2].v+1) ); VCOPY( (&tmpVrt), (sub[2].v+2) ); nSubSrf = 3; break; case 12: /* angles 2 and 3 are obtuse */ tmpVrt.x = 0.5f * (srf->v[0].x + srf->v[1].x ); tmpVrt.y = 0.5f * (srf->v[0].y + srf->v[1].y ); tmpVrt.z = 0.5f * (srf->v[0].z + srf->v[1].z ); VCOPY( (srf->v+1), (sub[0].v+0) ); VCOPY( (srf->v+2), (sub[0].v+1) ); VCOPY( (&tmpVrt), (sub[0].v+2) ); VCOPY( (srf->v+2), (sub[1].v+0) ); VCOPY( (srf->v+3), (sub[1].v+1) ); VCOPY( (&tmpVrt), (sub[1].v+2) ); VCOPY( (srf->v+3), (sub[2].v+0) ); VCOPY( (srf->v+0), (sub[2].v+1) ); VCOPY( (&tmpVrt), (sub[2].v+2) ); nSubSrf = 3; break; case 15: /* invalid configuration */ error( 2, __FILE__, __LINE__, "Invalid configuration", "" ); break; default: error( 2, __FILE__, __LINE__, "Invalid switch: ", IntStr(obtuse), "" ); } /* end switch */ if( obtuse > 0 ) /* complete subdivision data */ for( j=0; j<nSubSrf; j++ ) { sub[j].nr = j; sub[j].nv = 3; SetCentroid( 3, sub[j].v, &sub[j].ctd ); sub[j].area = Triangle( sub[j].v+0, sub[j].v+1, sub[j].v+2, &tmpVrt, 0 ); memcpy( &sub[j].dc, &srf->dc, sizeof(DIRCOS) ); } } else if( srf->nv==5 ) { for( j=0,i=1; j<5; j++,i++ ) { if( i==5 ) i = 0; VCOPY( (&srf->ctd), (sub[j].v+0) ); VCOPY( (srf->v+j), (sub[j].v+1) ); VCOPY( (srf->v+i), (sub[j].v+2) ); sub[j].nr = j; sub[j].nv = 3; SetCentroid( 3, sub[j].v, &sub[j].ctd ); sub[j].area = Triangle( sub[j].v+0, sub[j].v+1, sub[j].v+2, &tmpVrt, 0 ); memcpy( &sub[j].dc, &srf->dc, sizeof(DIRCOS) ); } nSubSrf = 5; } else error( 3, __FILE__, __LINE__, "Invalid number of vertices", IntStr(srf->nv), "" ); return nSubSrf; } /* end Subsurface */
QSE_INLINE pair_t* qse_rbt_allocpair ( rbt_t* rbt, void* kptr, size_t klen, void* vptr, size_t vlen) { pair_t* n; copier_t kcop = rbt->style->copier[QSE_RBT_KEY]; copier_t vcop = rbt->style->copier[QSE_RBT_VAL]; size_t as = SIZEOF(pair_t); if (kcop == QSE_RBT_COPIER_INLINE) as += KTOB(rbt,klen); if (vcop == QSE_RBT_COPIER_INLINE) as += VTOB(rbt,vlen); n = (pair_t*) QSE_MMGR_ALLOC (rbt->mmgr, as); if (n == QSE_NULL) return QSE_NULL; n->color = QSE_RBT_RED; n->parent = QSE_NULL; n->child[LEFT] = &rbt->xnil; n->child[RIGHT] = &rbt->xnil; KLEN(n) = klen; if (kcop == QSE_RBT_COPIER_SIMPLE) { KPTR(n) = kptr; } else if (kcop == QSE_RBT_COPIER_INLINE) { KPTR(n) = n + 1; if (kptr) QSE_MEMCPY (KPTR(n), kptr, KTOB(rbt,klen)); } else { KPTR(n) = kcop (rbt, kptr, klen); if (KPTR(n) == QSE_NULL) { QSE_MMGR_FREE (rbt->mmgr, n); return QSE_NULL; } } VLEN(n) = vlen; if (vcop == QSE_RBT_COPIER_SIMPLE) { VPTR(n) = vptr; } else if (vcop == QSE_RBT_COPIER_INLINE) { VPTR(n) = n + 1; if (kcop == QSE_RBT_COPIER_INLINE) VPTR(n) = (byte_t*)VPTR(n) + KTOB(rbt,klen); if (vptr) QSE_MEMCPY (VPTR(n), vptr, VTOB(rbt,vlen)); } else { VPTR(n) = vcop (rbt, vptr, vlen); if (VPTR(n) != QSE_NULL) { if (rbt->style->freeer[QSE_RBT_KEY] != QSE_NULL) rbt->style->freeer[QSE_RBT_KEY] (rbt, KPTR(n), KLEN(n)); QSE_MMGR_FREE (rbt->mmgr, n); return QSE_NULL; } } return n; }
static pair_t* change_pair_val ( rbt_t* rbt, pair_t* pair, void* vptr, size_t vlen) { if (VPTR(pair) == vptr && VLEN(pair) == vlen) { /* if the old value and the new value are the same, * it just calls the handler for this condition. * No value replacement occurs. */ if (rbt->style->keeper != QSE_NULL) { rbt->style->keeper (rbt, vptr, vlen); } } else { copier_t vcop = rbt->style->copier[QSE_RBT_VAL]; void* ovptr = VPTR(pair); size_t ovlen = VLEN(pair); /* place the new value according to the copier */ if (vcop == QSE_RBT_COPIER_SIMPLE) { VPTR(pair) = vptr; VLEN(pair) = vlen; } else if (vcop == QSE_RBT_COPIER_INLINE) { if (ovlen == vlen) { if (vptr) QSE_MEMCPY (VPTR(pair), vptr, VTOB(rbt,vlen)); } else { /* need to reconstruct the pair */ pair_t* p = qse_rbt_allocpair (rbt, KPTR(pair), KLEN(pair), vptr, vlen); if (p == QSE_NULL) return QSE_NULL; p->color = pair->color; p->left = pair->left; p->right = pair->right; p->parent = pair->parent; if (pair->parent) { if (pair->parent->left == pair) { pair->parent->left = p; } else { QSE_ASSERT (pair->parent->right == pair); pair->parent->right = p; } } if (!IS_NIL(rbt,pair->left)) pair->left->parent = p; if (!IS_NIL(rbt,pair->right)) pair->right->parent = p; if (pair == rbt->root) rbt->root = p; qse_rbt_freepair (rbt, pair); return p; } } else { void* nvptr = vcop (rbt, vptr, vlen); if (nvptr == QSE_NULL) return QSE_NULL; VPTR(pair) = nvptr; VLEN(pair) = vlen; } /* free up the old value */ if (rbt->style->freeer[QSE_RBT_VAL] != QSE_NULL) { rbt->style->freeer[QSE_RBT_VAL] (rbt, ovptr, ovlen); } } return pair; }