diff -urN rt_v47/area.c rt_v48/area.c --- rt_v47/area.c 2018-06-08 01:48:48.000000000 +0900 +++ rt_v48/area.c 2018-06-08 23:52:17.000000000 +0900 @@ -8,18 +8,19 @@ } static struct node * -node_new(double t, void *d, struct node *next) +node_new(double t, struct node *next, void *d, int dsz) { - struct node *p = malloc( sizeof(*p) ); + struct node *p = malloc( sizeof(*p) + dsz ); p->t = t; - p->d = d; p->next = next; + p->dsz = dsz; + memcpy(p->d, d, dsz); return p; } void -area_ins(struct area *a, double t, void *d) +area_ins(struct area *a, double t, void *d, int dsz) { struct node **pp = &a->p, *p = *pp; @@ -27,7 +28,7 @@ pp = &p->next; p = *pp; } - *pp = node_new(t, d, p); + *pp = node_new(t, p, d, dsz); } void @@ -55,41 +56,55 @@ } void -area_and(struct area *a, struct area *b, struct area *r) +area_not(struct area *a) { - struct node *ap = a->p, *bp = b->p; + a->v = !a->v; +} - area_init(r, a->v && b->v); - while( ap || bp ){ - if( !bp || (ap && ap->t < bp->t) ){ - if( area_val(b, ap->t) ){ - area_ins(r, ap->t, ap->d); - } - ap = ap->next; - }else{ - if( area_val(a, bp->t) ){ - area_ins(r, bp->t, bp->d); - } - bp = bp->next; - } +static int +op_f(int op, double t, struct area *b) +{ + switch(op){ + case AREA_OP_AND: + return area_val(b, t); + case AREA_OP_OR: + return !area_val(b, t); + default: + break; } + return 1; /* xor */ } void -area_or(struct area *a, struct area *b, struct area *r) +area_op(int op, struct area *a, struct area *b, struct area *r) { struct node *ap = a->p, *bp = b->p; + int v = 0; + + switch(op){ + case AREA_OP_AND: + v = a->v && b->v; + break; + case AREA_OP_OR: + v = a->v || b->v; + break; + case AREA_OP_XOR: + v = !a->v != !b->v; + break; + default: + break; + } - area_init(r, a->v || b->v); + area_init(r, v); while( ap || bp ){ if( !bp || (ap && ap->t < bp->t) ){ - if( !area_val(b, ap->t) ){ - area_ins(r, ap->t, ap->d); + if( op_f(op, ap->t, b) ){ + area_ins(r, ap->t, ap->d, ap->dsz); } ap = ap->next; }else{ - if( !area_val(a, bp->t) ){ - area_ins(r, bp->t, bp->d); + if( op_f(op, bp->t, a) ){ + area_ins(r, bp->t, bp->d, bp->dsz); } bp = bp->next; } @@ -97,29 +112,16 @@ } void -area_not(struct area *a, struct area *r) +area_op_eq(int op, struct area *dst, struct area *src) { - struct node *p = a->p; - - area_init(r, !a->v); - while(p){ - area_ins(r, p->t, p->d); - p = p->next; - } -} + /* dst = dst op src */ -struct node * -area_has_d(struct area *a, void *d) -{ - struct node *p = a->p; + struct area r; - while(p){ - if(p->d == d){ /* address */ - return p; - } - p = p->next; - } - return NULL; + area_op(op, dst, src, &r); + area_free(src); + area_free(dst); + *dst = r; } int @@ -140,7 +142,7 @@ } while(p){ - fprintf(stderr, "%s(%f %p)", v ? "###" : "...", p->t, p->d); + fprintf(stderr, "%s(%f)", v ? "###" : "...", p->t); p = p->next; v = !v; } diff -urN rt_v47/area.h rt_v48/area.h --- rt_v47/area.h 2018-06-08 01:48:54.000000000 +0900 +++ rt_v48/area.h 2018-06-08 23:52:17.000000000 +0900 @@ -3,11 +3,13 @@ #include #include +#include struct node{ double t; - void *d; struct node *next; + int dsz; + char d[0]; }; struct area{ @@ -15,15 +17,19 @@ struct node *p; }; +#define AREA_OP_AND 0 +#define AREA_OP_OR 1 +#define AREA_OP_XOR 2 + void area_init(struct area *a, int v); -void area_ins(struct area *a, double t, void *d); +void area_ins(struct area *a, double t, void *d, int dsz); void area_free(struct area *a); int area_val(struct area *a, double t); -void area_and(struct area *a, struct area *b, struct area *r); -void area_or(struct area *a, struct area *b, struct area *r); -void area_not(struct area *a, struct area *r); +void area_not(struct area *a); + +void area_op(int op, struct area *a, struct area *b, struct area *r); +void area_op_eq(int op, struct area *dst, struct area *src); -struct node *area_has_d(struct area *a, void *d); void area_show(struct area *a); int area_is_all(struct area *a, int v); diff -urN rt_v47/cross.c rt_v48/cross.c --- rt_v47/cross.c 2018-06-08 01:37:40.000000000 +0900 +++ rt_v48/cross.c 2018-06-08 23:52:17.000000000 +0900 @@ -358,137 +358,140 @@ ret->ang_nv_eyev = dot( ret->nv, ret->eyev ); } -static void -my_area_ins(struct area *a, double t, struct cross_ret *ret) -{ - int sz = sizeof(*ret); - void *d = malloc(sz); - memcpy(d, ret, sz); - area_ins(a, t, d); -} - -static void -my_area_free(struct area *a, struct area *without) +static int +is_plane(int kind) { - struct node *p = a->p; - while(p){ - if(p->d && ( !without || !area_has_d(without, p->d) ) ){ - free(p->d); - p->d = NULL; - } - p = p->next; + switch(kind){ + case KIND_SQUARE: + case KIND_CIRCLE: + case KIND_TRIANGLE: + return 1; } - area_free(a); - + return 0; } -static void -my_area_not(struct area *a) +static int +kind_to_op(int kind) { - struct area r; - area_not(a, &r); - my_area_free(a, &r); - *a = r; + switch(kind){ + case KIND_AND: + return AREA_OP_AND; + case KIND_OR: + return AREA_OP_OR; + case KIND_XOR: + return AREA_OP_XOR; + } + return -1; } static int -my_area_and(struct area *area, struct area *a) +is_op(int kind) { - struct area r; - - area_and(area, a, &r); - my_area_free(area, &r); - my_area_free(a, &r); - *area = r; - return area_is_all(area, 0); + return kind_to_op(kind) != -1; } static int -my_area_sel(struct area *a, struct cross_ret *ret) +get_idx_of_id(struct data *data, int id) { - struct node *p = a->p; + int i; - while(p && p->t <= 0){ - p = p->next; - } - if(p){ - memcpy(ret, p->d, sizeof(*ret)); - line_on_line_p(&ret->l, ret->t, ret->p); /* ! */ + for(i=0; in; i++){ + if(data->lst[i].id == id){ + return i; + } } - my_area_free(a, NULL); - return p ? 1 : 0; + return -1; } static int -is_plane(int kind) -{ - return kind == KIND_SQUARE || kind == KIND_CIRCLE || kind == KIND_TRIANGLE; -} - -static int -cross_and(struct line *l_g, int prev_idx, struct data *data, int p_i, struct data_one *pd, struct cross_ret *ret) +cross_op(struct line *l_g, int prev_idx, struct data *data, int p_i, struct data_one *pd, struct area *ret_a) { - int i, j, n; - struct area area; - - area_init(&area, 1); /* for and */ + int op = kind_to_op(pd->kind); + int i, j, k, n; + int v = op == AREA_OP_AND ? 1 : 0; + + area_init(ret_a, v); for(i=0; ichildren.n; i++){ - struct cross_ret ret_; - int id = pd->children.lst[i]; - struct area a; + int id = pd->children.lst[i], pl; struct data_one *d; - int is_pl; + struct cross_ret r; + struct area a; - for(j=0; jn; j++){ - if(data->lst[j].id == id){ - break; - } - } - if(j >= data->n){ - // err... + j = get_idx_of_id(data, id); + if(j < 0){ + continue; } d = &data->lst[j]; - is_pl = is_plane(d->kind); + pl = is_plane(d->kind); - ret_.use_ts_only = 1; + r.use_ts_only = 1; - n = cross_cross_one( d->kind, &d->l2g, prev_idx == j, l_g, &ret_ ); - - if( n == 0 && ( is_pl || !d->not ) ){ - return 0; - } - ret_.idx = j; + if( !is_op(d->kind) ){ + n = cross_cross_one( d->kind, &d->l2g, prev_idx == j, l_g, &r ); - area_init(&a, 0); + r.idx = j; + area_init(&a, 0); - if(is_pl){ - cross_get_nv( d->kind, &d->l2g, l_g, 0, &ret_ ); - if(ret_.ang_nv_eyev > 0){ - area_init(&a, 1); + if(n == 0){ + if(pl && r.l.p[2] < 0){ + area_init(&a, 1); + } + }else if(pl){ + r.t = r.ts[0]; + area_ins(&a, r.t, &r, sizeof(r)); + cross_get_nv( d->kind, &d->l2g, l_g, 0, &r ); + if(r.ang_nv_eyev > 0){ + area_not(&a); + } + }else{ + for(k=0; k<2; k++){ + r.t = r.ts[k]; + area_ins(&a, r.t, &r, sizeof(r)); + } } - ret_.t = ret_.ts[0]; - my_area_ins(&a, ret_.ts[0], &ret_); - }else if(n == 0){ /* && d->not */ - area_init(&a, 1); /* all */ }else{ - int ii; - for(ii=0; ii<2; ii++){ - struct cross_ret r; - r = ret_; - r.t = ret_.ts[ii]; - my_area_ins(&a, r.t, &r); - } - if(d->not){ - my_area_not(&a); - } + cross_op(l_g, prev_idx, data, j, d, &a); } - if( my_area_and(&area, &a) ){ + + if(d->not){ + area_not(&a); + } + + area_op_eq(op, ret_a, &a); + + v = -1; + switch(op){ + case AREA_OP_AND: + v = 0; break; + case AREA_OP_OR: + v = 1; + break; + default: + break; + } + if( v != -1 && area_is_all(ret_a, v) ){ + return 0; } } + return 1; +} + +static int +my_area_sel(struct area *a, struct cross_ret *ret) +{ + struct node *p = a->p; - return my_area_sel(&area, ret); + while(p && p->t <= 0){ + p = p->next; + } + if(p){ + memcpy(ret, p->d, sizeof(*ret)); + line_on_line_p(&ret->l, ret->t, ret->p); /* ! */ + } + area_free(a); + return p ? 1 : 0; } void @@ -509,10 +512,13 @@ ret_.use_ts_only = 0; ret_.idx = -1; - if(d->kind == KIND_AND){ - if( !cross_and( l_g, prev_idx, data, i, d, &ret_ ) ){ + if(is_op(d->kind)){ + struct area a; + if( !cross_op( l_g, prev_idx, data, i, d, &a ) ){ continue; } + my_area_sel(&a, &ret_); + }else if( !cross_cross_one( d->kind, &d->l2g, prev_idx == i, l_g, &ret_ ) ){ continue; } diff -urN rt_v47/dat.h rt_v48/dat.h --- rt_v47/dat.h 2018-06-08 01:46:38.000000000 +0900 +++ rt_v48/dat.h 2018-06-08 23:52:22.000000000 +0900 @@ -13,6 +13,8 @@ #define KIND_CONE_SIDE 5 #define KIND_AND 6 +#define KIND_OR 7 +#define KIND_XOR 8 struct map{ struct lstx xyz2g; diff -urN rt_v47/dat.py rt_v48/dat.py --- rt_v47/dat.py 2018-06-08 01:45:45.000000000 +0900 +++ rt_v48/dat.py 2018-06-08 23:52:17.000000000 +0900 @@ -113,7 +113,7 @@ get_id = new_get_id() -def d_setup(d): +def d_setup(d, in_op=False): # return lst [d] kind = d.get('kind') @@ -138,12 +138,21 @@ d_ = d_copy(d) d_['kind'] = 'square' d_['l2m'] = [ ax.slide_z(1), ax.rot(l, deg) ] + d_.get( 'l2m', [] ) - return d_setup( d_ ) + return d_ rots = [ (line.x1, 0), (line.x1, 90), (line.x1, 180), (line.x1, -90), (line.y1, 90), (line.y1, -90) ] - return sum( ut.map_up( cube_f, rots ), [] ) + + f_not = False + if in_op and 'not' in d: + f_not = d.pop('not') + + lst = ut.map_up_lst( cube_f, rots ) + + if in_op: + return d_setup( { 'kind': 'and', 'args': lst, 'not': f_not } ) + return sum( map( d_setup, lst ), [] ) if kind == 'tri_prism_side': d0 = d_copy(d) @@ -369,7 +378,8 @@ ### kinds = [ 'square', 'circle', 'triangle', 'ball', 'pipe_side', 'cone_side' ] - kinds += [ 'and' ] + ops = [ 'and', 'or', 'xor' ] + kinds += ops if not val.cli.has_prop('kinds'): val.cli.set_prop( 'kinds', '[str]', kinds ) kind = d.get('kind') @@ -377,15 +387,16 @@ d['kind'] = kinds.index(kind) ### - if kind == 'and': + if kind in ops: ds = [] for d_ in d.get('args', []): d_['m2g'] = d_.get('m2g', []) + d.get('l2g') - ds += d_setup(d_) + ds += d_setup(d_, True) for d_ in ds: d_['maps'] = d_.get('maps', []) + d.get('maps', []) - d_['parent'] = d.get('id') - d['children'].append( d_.get('id') ) + if d_.get('parent', -1) < 0: + d_['parent'] = d.get('id') + d['children'].append( d_.get('id') ) return [d] + ds ### diff -urN rt_v47/op.yaml rt_v48/op.yaml --- rt_v47/op.yaml 1970-01-01 09:00:00.000000000 +0900 +++ rt_v48/op.yaml 2018-06-08 23:52:17.000000000 +0900 @@ -0,0 +1,59 @@ +defs: + rtd_A: { base: 0.1, diff: 0, reflect: 0.5, reflact: 0.5, density: 2 } + mov4: IMG_3999_4.mov + +big_ball: +- kind: ball + rtd: { diff: 0.3 } + maps: + - fn: '*mov4' + fn_r: '*mov4' + t2m: [ ax.zoom_all(2), ax.rot_x(90) ] + - fn: '*mov4' + fn_r: '*mov4' + t2m: [ ax.zoom_all(2), ax.rot_x(90), ax.rot_z(180) ] + m2g: [ ax.zoom_all(1000) ] + +all: +- kind: export + export: big_ball + +- kind: or + args: + - kind: ball + rtd: '*rtd_A' + - kind: cube + rtd: '*rtd_A' + m2g: [ 'ax.zoom_all(0.8)' ] + m2g: [ 'ax.slide([-1,-1,0])', 'ax.zoom_all(20)' ] + +- kind: and + args: + - kind: cube + rtd: '*rtd_A' + m2g: [ 'ax.zoom_all(0.8)' ] + - kind: ball + not: True + rtd: '*rtd_A' + m2g: [ 'ax.slide([1,-1,0])', 'ax.zoom_all(20)' ] + +- kind: and + args: + - kind: ball + rtd: '*rtd_A' + - kind: cube + not: True + rtd: '*rtd_A' + m2g: [ 'ax.zoom_all(0.8)' ] + m2g: [ 'ax.slide([-1,1,0])', 'ax.zoom_all(20)' ] + +- kind: and + args: + - kind: ball + rtd: '*rtd_A' + - kind: cube + rtd: '*rtd_A' + m2g: [ 'ax.zoom_all(0.8)' ] + m2g: [ 'ax.slide([1,1,0])', 'ax.zoom_all(20)' ] + +# EOF