Appendix A: Scene File Grammar
This appendix contains the formal syntax of the mental images .mi scene description format. The grammar is in yacc format; yacc is a Unix compiler generator. Nonterminals that begin with T_ are typed values:
= pcrr at 7.0pt -2pt
=|=0 \=12 |obeylines|gdef|doverbatim#1#1|endgroup
%{ %union { miBoolean boolean; char *symbol; char *string; struct { int len; miUchar *bytes; } byte_string; int integer; double floating; miMatrix matrix; miVector vector; miGeoVector geovector; miTransform *transform; miParameter *para_type; miDlist *dlist; miTag tag; } %token <symbol> T_SYMBOL %token <integer> T_INTEGER %token <floating> T_FLOAT %token <string> T_STRING %token <byte_string> T_BYTE_STRING %token <vector> T_VECTOR %token ACCELERATION ACCURACY ADAPTIVE ALL ANGLE APERTURE APPLY APPROXIMATE %token ARRAY ASPECT %token BACK BASIS BEZIER BLUE BOOLEAN BOTH BOX BSP BSPLINE BUMP %token CALL CAMERA CARDINAL CAUSTIC CLASSIFICATION CLIP CODE COLOR COMPLEXITY %token CONE CONNECT CONSTANT CONTOUR CONTRAST CP CURVATURE CURVE %token D DEBUG_ DECLARE DELETE_ DEPTH DERIVATIVE DESATURATE DIRECTION DISC %token DISPLACE DISTANCE DITHER %token ECHO EMITTER END ENVIRONMENT EVEN ENERGY EXPONENT %token FACE FALSE_ FAN FIELD FILE_ FILTER FOCAL FRAME FRONT %token GAMMA GAUSS GEOMETRY GLOBILLUM GREEN GRID GROUP %token HIDE HOLE %token IMP IMPLICIT INCREMENTAL INFINITY_ INHERITANCE INSTANCE INSTGROUP %token INTEGER INTERFACE %token JITTER %token LENGTH LENS LIGHT LINK LOCAL %token M MAPSTO MATERIAL MATRIX MAX MEMORY MERGE MESH MI MIN MIXED MOTION %token N NOCONTOUR NULL_ %token OBJECT ODD OFF ON OPAQUE_ OPTIONS ORIGIN OUTPUT %token P PARAMETRIC PHENOMENON PHOTON PHOTONMAP PHOTONS PHOTONVOL PREMULTIPLY %token PRIORITY %token QUALITY %token RATIONAL RAY RAYCL RECTANGLE RECURSIVE %token REBUILD %token RED RENDER RESOLUTION ROOT %token SAMPLES SCALAR SCANLINE SEGMENTS SET SHADOW SHADOWMAP SHUTTER SIZE %token SOFTNESS SORT SPACE SPATIAL SPDL SPECIAL SPHERE SPREAD STORE STRING %token STRIP STRUCT SUBDIVISION SHADER SMART SURFACE SYSTEM %token T TAG TAGGED TASK TAYLOR TEXTURE TIME TRACE TRANSFORM TREE TRIANGLE TRIM %token TRUE_ %token U V VALUE VECTOR VERBOSE VERSION VIEW VISIBLE VOLUME %token W WHITE WIDTH WINDOW WORLD %type <floating> floating %type <boolean> boolean %type <string> symbol %type <string> opt_symbol %type <matrix> transform %type <matrix> obj_transform %type <integer> tex_flags %type <integer> tex_flag %type <integer> tex_type %type <integer> simple_type %type <string> inst_item %type <tag> inst_func %type <tag> inst_params %type <integer> filter_type %type <tag> function %type <tag> function_list %type <tag> tex_func_list %type <tag> phen_root %type <string> mtl_or_label %type <para_type> shret_type %type <para_type> shret_type_nosh %type <para_type> shret_decl_seq %type <para_type> shret_decl %type <para_type> parm_decl_list %type <para_type> parm_decl_seq %type <para_type> parm_decl %type <boolean> rational %type <dlist> basis_matrix %type <floating> merge_option %type <vector> vector %type <geovector> geovector %type <dlist> para_list %type <boolean> opt_volume_flag %type <boolean> opt_vector_flag %type <boolean> opt_incremental %type <integer> apply %type <integer> apply_list %% start : { functag = 0; mi_api_incremental(is_incremental = miFALSE); } command_list | ; /*----------------------------------------------------------------------------- * primitive types *---------------------------------------------------------------------------*/ boolean : ON { $$ = miTRUE; } | OFF { $$ = miFALSE; } | TRUE_ { $$ = miTRUE; } | FALSE_ { $$ = miFALSE; } ; floating : T_FLOAT { $$ = $1; } | T_INTEGER { $$ = $1; } ; vector : floating floating floating { $$.x = $1; $$.y = $2; $$.z = $3; } | T_VECTOR { $$ = $1; } ; geovector : floating floating floating { $$.x = $1; $$.y = $2; $$.z = $3; } | T_VECTOR { $$.z = $1.z; $$.y = $1.y; $$.x = $1.x; } ; transform : TRANSFORM floating floating floating floating floating floating floating floating floating floating floating floating floating floating floating floating { $$[0] = $2; $$[1] = $3; $$[2] = $4; $$[3] = $5; $$[4] = $6; $$[5] = $7; $$[6] = $8; $$[7] = $9; $$[8] = $10; $$[9] = $11; $$[10]= $12; $$[11]= $13; $$[12]= $14; $$[13]= $15; $$[14]= $16; $$[15]= $17; } ; symbol : T_SYMBOL { $$ = $1; } | T_STRING { $$ = $1; } ; opt_symbol : { $$ = 0; } | symbol { $$ = $1; } ; /*----------------------------------------------------------------------------- * top-level commands *---------------------------------------------------------------------------*/ command_list : { mi_api_incremental(is_incremental = miFALSE); } command | command_list { mi_api_incremental(is_incremental = miFALSE); } command ; command : frame | debug | set | call | version | incr_command | INCREMENTAL { mi_api_incremental(is_incremental = miTRUE); } incr_command | DELETE_ symbol { mi_api_delete($2); } | RENDER symbol symbol symbol { mi_api_render($2, $3, $4, mi_mem_strdup(ctx->inheritance_func)); if (mi_get_subverbosity(miM_MI) & miMSG_PHASE) mi_progress("resume mi scene file parsing"); yyreturn MIYYRENDER; } | VERBOSE boolean { if (!ctx->mi_force_verbose) mi_set_verbosity($2? miERR_ALL & ~miERR_DEBUG & ~miERR_VDEBUG : miERR_FATAL|miERR_ERROR);} | VERBOSE T_INTEGER { if (!ctx->mi_force_verbose) mi_set_verbosity((1 << $2) - 1); } | ECHO T_STRING { mi_info("%s", $2); mi_mem_release($2); } | SYSTEM T_STRING { if ((system ($2) >> 8) & 0xff) mi_api_warning("system \"%s\" failed", $2); mi_mem_release($2); } | MEMORY T_INTEGER { mi_api_warning("memory view parameter ignored"); } | CODE T_STRING { mi_link_file_add($2, miTRUE, miFALSE, miFALSE); } | CODE { mi_api_code_verbatim_begin(); } code_bytes_list { mi_api_code_verbatim_end(); } | LINK T_STRING { mi_link_file_add($2, miFALSE, miFALSE, miFALSE); } | DECLARE function_decl | DECLARE phenomenon_decl | REGISTRY symbol { mi_api_registry_begin($2); } reg_body END REGISTRY { mi_api_registry_end(); } ; reg_body : | reg_item reg_body ; reg_item : VALUE symbol { mi_api_registry_add(mi_mem_strdup("value"), $2); } | LINK symbol { mi_api_registry_add(mi_mem_strdup("link"), $2); } | CODE symbol { mi_api_registry_add(mi_mem_strdup("code"), $2); } | MI symbol { mi_api_registry_add(mi_mem_strdup("mi"), $2); } | SPDL symbol { mi_api_registry_add(mi_mem_strdup("spdl"), $2); } | ECHO symbol { mi_api_registry_add(mi_mem_strdup("echo"), $2); } | SYSTEM symbol { mi_api_registry_add(mi_mem_strdup("system"), $2); } | symbol symbol { mi_api_registry_add($1, $2); } ; incr_command : options | camera | texture | material | light | instance | instgroup | object | SHADER symbol function_list { mi_api_shader_add($2, $3); } ; code_bytes_list : T_BYTE_STRING { mi_api_code_byte_copy($1.len, $1.bytes); } | code_bytes_list T_BYTE_STRING { mi_api_code_byte_copy($2.len, $2.bytes); } ; set : SET symbol { mi_api_variable_set($2, 0); } | SET symbol symbol { mi_api_variable_set($2, $3); } ; call : CALL function_list { mi_api_shader_call($2, 0, 0); } | CALL function_list ',' symbol symbol { mi_api_shader_call($2, $4, $5); } ; debug : DEBUG_ symbol opt_symbol { mi_api_debug($2,$3); } ; version : VERSION T_STRING { mi_api_version_check($2, 0); ctx->mi_did_check_version = miTRUE; } | MIN VERSION T_STRING { mi_api_version_check($3, 0); ctx->mi_did_check_version = miTRUE; } | MAX VERSION T_STRING { mi_api_version_check($3, 1); ctx->mi_did_check_version = miTRUE; } ; /*----------------------------------------------------------------------------- * options *---------------------------------------------------------------------------*/ options : OPTIONS symbol { options = mi_api_options_begin($2); } option_list END OPTIONS { mi_api_options_end(); } ; option_list : | option_list option_item ; option_item : optview_item | ACCELERATION RAYCL { options->acceleration = 'c'; } | ACCELERATION BSP { options->acceleration = 'b'; } | ACCELERATION GRID { options->acceleration = 'g'; } | SAMPLES T_INTEGER { options->min_samples = $2-2; options->max_samples = $2; } | SAMPLES T_INTEGER T_INTEGER { options->min_samples = $2; options->max_samples = $3; } ; optview_item : SHADOW OFF { options->shadow = 0; } | SHADOW ON { options->shadow = 1; } | SHADOW SORT { options->shadow = 'l'; } | SHADOW SEGMENTS { options->shadow = 's'; } | TRACE boolean { options->trace = $2; } | SCANLINE boolean { options->scanline = $2; } | LENS boolean { options->no_lens = !$2; } | VOLUME boolean { options->no_volume = !$2; } | GEOMETRY boolean { options->no_geometry = !$2; } | DISPLACE boolean { options->no_displace = !$2; } | OUTPUT boolean { options->no_output = !$2; } | MERGE boolean { options->no_merge = !$2; } | FILTER filter_type floating { options->filter = $2; options->filter_size_x = options->filter_size_y = $3; } | FILTER filter_type floating floating { options->filter = $2; options->filter_size_x = $3; options->filter_size_y = $4; } | FACE FRONT { options->face = 'f'; } | FACE BACK { options->face = 'b'; } | FACE BOTH { options->face = 'a'; } | FIELD OFF { options->field = 0; } | FIELD EVEN { options->field = 'e'; } | FIELD ODD { options->field = 'o'; } | PHOTON TRACE DEPTH T_INTEGER { options->photon_reflection_depth = $4; options->photon_refraction_depth = $4; options->photon_trace_depth = $4 + $4; } | PHOTON TRACE DEPTH T_INTEGER T_INTEGER { options->photon_reflection_depth = $4; options->photon_refraction_depth = $5; options->photon_trace_depth = $4 + $5; } | PHOTON TRACE DEPTH T_INTEGER T_INTEGER T_INTEGER { options->photon_reflection_depth = $4; options->photon_refraction_depth = $5; options->photon_trace_depth = $6; } | TRACE DEPTH T_INTEGER { options->reflection_depth = $3; options->refraction_depth = $3; options->trace_depth = $3 + $3; } | TRACE DEPTH T_INTEGER T_INTEGER { options->reflection_depth = $3; options->refraction_depth = $4; options->trace_depth = $3 + $4; } | TRACE DEPTH T_INTEGER T_INTEGER T_INTEGER { options->reflection_depth = $3; options->refraction_depth = $4; options->trace_depth = $5; } | CONTRAST floating floating floating { options->contrast.r = $2; options->contrast.g = $3; options->contrast.b = $4; options->contrast.a = ($2 + $3 + $4)/3; } | CONTRAST floating floating floating floating { options->contrast.r = $2; options->contrast.g = $3; options->contrast.b = $4; options->contrast.a = $5; } | TIME CONTRAST floating floating floating { options->time_contrast.r = $3; options->time_contrast.g = $4; options->time_contrast.b = $5; options->time_contrast.a = ($3 + $4 + $5)/3; } | TIME CONTRAST floating floating floating floating { options->time_contrast.r = $3; options->time_contrast.g = $4; options->time_contrast.b = $5; options->time_contrast.a = $6; } | CONTOUR STORE function { options->contour_store = $3; } | CONTOUR CONTRAST function { options->contour_contrast = $3; } | JITTER floating { options->jitter = $2; } | SHUTTER floating { options->shutter = $2; options->motion = options->shutter > 0; } | TASK SIZE T_INTEGER { options->task_size = $3; } | RAYCL SUBDIVISION T_INTEGER T_INTEGER { options->subdivision = $3; options->subdivision_2d = $4; } | RAYCL MEMORY T_INTEGER { options->subdivision_memory = $3; } | BSP SIZE T_INTEGER { options->space_max_size = $3; } | BSP DEPTH T_INTEGER { options->space_max_depth = $3; } | GRID SIZE floating { options->grid_size = $3; } | DESATURATE boolean { mi_img_mode($2, (miBoolean)-1, (miBoolean)-1, -1.0);} | DITHER boolean { mi_img_mode((miBoolean)-1, $2, (miBoolean)-1, -1.0);} | PREMULTIPLY boolean { mi_img_mode((miBoolean)-1, (miBoolean)-1, $2, -1.0);} | GAMMA floating { mi_img_mode((miBoolean)-1, (miBoolean)-1, (miBoolean)-1, $2); } | OBJECT SPACE { options->render_space = 'o'; } | CAMERA SPACE { options->render_space = 'c'; } | MIXED SPACE { options->render_space = 'm'; } | INHERITANCE symbol { if (ctx->inheritance_func) mi_mem_release(ctx->inheritance_func); ctx->inheritance_func = $2; } | SHADOWMAP MOTION boolean { options->shadow_map_motion = $3; } | SHADOWMAP REBUILD boolean { options->recompute_shadow_maps = (($3)?'y':'n'); } | SHADOWMAP boolean { options->use_shadow_maps = $2; } | CAUSTIC boolean { options->caustic = $2; } | CAUSTIC ACCURACY T_INTEGER { options->caustic_accuracy = $3; } | CAUSTIC ACCURACY T_INTEGER floating { options->caustic_accuracy = $3; options->caustic_radius = $4; } | CAUSTIC FILTER c_filter_type { options->caustic_filter = $3; options->caustic_filter_const = 1.1; } | CAUSTIC FILTER c_filter_type floating { options->caustic_filter = $3; options->caustic_filter_const = $4; } | GLOBILLUM boolean { options->globillum = $2; } | GLOBILLUM ACCURACY T_INTEGER { options->global_accuracy = $3; } | GLOBILLUM ACCURACY T_INTEGER floating { options->global_accuracy = $3; options->global_radius = $4; } | PHOTONVOL ACCURACY T_INTEGER { options->photonvol_accuracy = $3; } | PHOTONVOL ACCURACY T_INTEGER floating { options->photonvol_accuracy = $3; options->photonvol_radius = $4; } | PHOTONMAP FILE_ T_STRING { mi_scene_delete(options->photonmap_file); strcpy((char *)mi_scene_create( &options->photonmap_file, miSCENE_STRING, strlen($3)+1), $3); mi_db_unpin(options->photonmap_file); mi_mem_release($3); } | PHOTONMAP REBUILD boolean { options->photonmap_rebuild = $3; } | APPROXIMATE opt_displace ; filter_type : BOX { $$ = 'b'; } | TRIANGLE { $$ = 't'; } | GAUSS { $$ = 'g'; } ; c_filter_type : BOX { $$ = 'b'; } | CONE { $$ = 'c'; } | GAUSS { $$ = 'g'; } ; opt_displace : { miAPPROX_DEFAULT(approx); } s_approx_tech ALL { memcpy(&options->approx, &approx, sizeof(miApprox));} | { miAPPROX_DEFAULT(approx); } DISPLACE s_approx_tech ALL { memcpy(&options->approx_displace, &approx, sizeof(miApprox)); } ; /*----------------------------------------------------------------------------- * camera *---------------------------------------------------------------------------*/ camera : CAMERA symbol { camera = mi_api_camera_begin($2); have_l = have_o = have_v = have_e = 0; } camera_list END CAMERA { mi_api_camera_end(); } ; camera_list : | camera_list camera_item ; camera_item : camview_item | frame_number | FIELD T_INTEGER { camera->frame_field = $2; } ; camview_item : OUTPUT { mi_api_function_delete(&camera->output); } | OUTPUT T_STRING T_STRING { if (!have_o++) mi_api_function_delete(&camera->output); camera->output = mi_api_function_append( camera->output, mi_api_output_file_def(0, 0, $2, $3)); } | OUTPUT T_STRING T_STRING T_STRING { if (!have_o++) mi_api_function_delete(&camera->output); mi_api_output_type_identify(&tbm, &ibm, $2); camera->output = mi_api_function_append( camera->output, mi_api_output_file_def(tbm, ibm, $3, $4));} | OUTPUT T_STRING function { if (!have_o++) mi_api_function_delete(&camera->output); mi_api_output_type_identify(&tbm, &ibm, $2); camera->output = mi_api_function_append( camera->output, mi_api_output_function_def(tbm, ibm, $3)); } | VOLUME { mi_api_function_delete(&camera->volume); } | VOLUME function_list { if (!have_v++) mi_api_function_delete(&camera->volume); camera->volume = mi_api_function_append( camera->volume, $2); } | ENVIRONMENT { mi_api_function_delete(&camera->environment); } | ENVIRONMENT function_list { if (!have_e++) mi_api_function_delete(&camera->environment); camera->environment = mi_api_function_append( camera->environment, $2); } | LENS { mi_api_function_delete(&camera->lens); } | LENS function_list { if (!have_l++) mi_api_function_delete(&camera->lens); camera->lens = mi_api_function_append( camera->lens, $2); } | FOCAL floating { camera->focal = $2; camera->orthographic = miFALSE; } | FOCAL INFINITY_ { camera->orthographic = miTRUE; } | APERTURE floating { camera->aperture = $2; } | ASPECT floating { camera->aspect = $2; } | RESOLUTION T_INTEGER T_INTEGER { camera->x_resolution = $2; camera->y_resolution = $3; } | WINDOW T_INTEGER T_INTEGER T_INTEGER T_INTEGER { camera->window.xl = $2; camera->window.yl = $3; camera->window.xh = $4; camera->window.yh = $5; } | CLIP floating floating { camera->clip.min = $2; camera->clip.max = $3; } ; frame_number : FRAME T_INTEGER { camera->frame = $2; camera->frame_time = 0; camera->frame_field = 0; } | FRAME T_INTEGER floating { camera->frame = $2; camera->frame_time = 0; camera->frame_field = $3; } ; /*----------------------------------------------------------------------------- * instance *---------------------------------------------------------------------------*/ instance : INSTANCE symbol { curr_inst = mi_api_instance_begin($2); if (!curr_inst) curr_inst = &dummy_inst; } inst_item inst_func inst_flags inst_params { mi_api_instance_end($4,$5,$7); } END INSTANCE ; inst_item : { $$ = 0; } | symbol { $$ = $1; } ; inst_func : { $$ = miNULLTAG; } | GEOMETRY function_list { $$ = $2; } ; inst_flags : | inst_flag inst_flags ; inst_flag : VISIBLE boolean { curr_inst->visible = $2 ? 2 : 1; } | SHADOW boolean { curr_inst->shadow = $2 ? 2 : 1; } | TRACE boolean { curr_inst->trace = $2 ? 2 : 1; } | CAUSTIC { curr_inst->caustic = 3; } | CAUSTIC T_INTEGER { curr_inst->caustic = $2; } | HIDE boolean { curr_inst->off = $2; } | TRANSFORM { curr_inst->tf.function = miNULLTAG; mi_matrix_ident(curr_inst->tf.global_to_local); } | TRANSFORM function { curr_inst->tf.function = $2; mi_matrix_ident(curr_inst->tf.global_to_local); } | transform { curr_inst->tf.function = miNULLTAG; mi_matrix_copy( curr_inst->tf.global_to_local, $1); if (!mi_matrix_invert(curr_inst->tf.local_to_global, curr_inst->tf.global_to_local)){ mi_api_warning("singular matrix, using " "identity"); mi_matrix_ident(curr_inst->tf.global_to_local); mi_matrix_ident(curr_inst->tf.local_to_global); }} | MOTION OFF { mi_matrix_null(curr_inst->motion_transform); curr_inst->gen_motion = miGM_OFF; } | MOTION TRANSFORM { mi_matrix_null(curr_inst->motion_transform); curr_inst->gen_motion = miGM_INHERIT; } | MOTION transform { mi_matrix_copy(curr_inst->motion_transform,$2); curr_inst->gen_motion = miGM_TRANSFORM; } | MATERIAL { curr_inst->material = miNULLTAG; curr_inst->mtl_array_size = 0; } inst_mtl ; inst_params : { $$ = (miTag)-1; } | '(' ')' { $$ = miNULLTAG; } | '(' { if (!ctx->inheritance_func) mi_api_error( "no inheritance function in options"); else { mi_api_function_call(mi_mem_strdup( ctx->inheritance_func)); } } parameter_seq instparamstail { $$ = mi_api_function_call_end(0); } ; instparamstail : ')' | ',' ')' ; inst_mtl : | symbol { curr_inst->material = mi_api_material_lookup($1); } | '[' { taglist = mi_api_dlist_create(miDLIST_TAG); } inst_mtl_array ']' { curr_inst->mtl_array_size = taglist->nb; curr_inst->material = mi_api_taglist(taglist); mi_api_dlist_delete(taglist); } ; inst_mtl_array : symbol { mi_api_dlist_add(taglist, (void *)mi_api_material_lookup($1)); } inst_mtl_next ; inst_mtl_next : | ',' | ',' inst_mtl_array ; /*----------------------------------------------------------------------------- * instgroup *---------------------------------------------------------------------------*/ instgroup : INSTGROUP symbol { mi_api_instgroup_begin($2); } grouplist END INSTGROUP { mi_api_instgroup_end(); } ; grouplist : | symbol { mi_api_instgroup_additem($1); } grouplist ; /***************************************************************************** ************************* either ************************************** *****************************************************************************/ /*----------------------------------------------------------------------------- * function declaration *---------------------------------------------------------------------------*/ function_decl : shret_type_nosh T_STRING parm_decl_list { mi_api_function_declare($1, $2, $3); } | SHADER shret_type T_STRING parm_decl_list { tag = mi_api_function_declare($2, $3, $4); curr_decl = !tag ? &dummy_decl : (miFunction_decl *)mi_scene_edit(tag);} declare_req_seq END DECLARE { if (tag) mi_scene_edit_end(tag); } ; shret_type : shret_type_nosh { $$ = $1; } | SHADER { $$ = mi_api_parameter_decl(miTYPE_SHADER, 0, 0); } ; shret_type_nosh : { $$ = mi_api_parameter_decl(miTYPE_COLOR, 0, 0); } | simple_type { $$ = mi_api_parameter_decl($1, 0, 0); } | STRUCT '{' shret_decl_seq '}' { miParameter *parm = mi_api_parameter_decl(miTYPE_STRUCT, 0, 0); mi_api_parameter_child(parm, $3); $$ = parm; } ; shret_decl_seq : shret_decl_seq ',' shret_decl { $$ = mi_api_parameter_append($1, $3); } | shret_decl { $$ = $1; } ; shret_decl : simple_type symbol { $$ = mi_api_parameter_decl($1, $2, 0); } | SHADER symbol { $$ = mi_api_parameter_decl(miTYPE_SHADER, $2, 0); } ; parm_decl_list : '(' parm_decl_seq ')' { $$ = $2; } | '(' parm_decl_seq ',' ')' { $$ = $2; } | '(' ')' { $$ = 0; } ; parm_decl_seq : parm_decl_seq ',' parm_decl { $$ = mi_api_parameter_append($1, $3); } | parm_decl { $$ = $1; } ; parm_decl : simple_type symbol { $$ = mi_api_parameter_decl($1, $2, 0); } | SHADER symbol { $$ = mi_api_parameter_decl(miTYPE_SHADER, $2, 0); } | STRUCT symbol '{' parm_decl_seq '}' { miParameter *parm = mi_api_parameter_decl(miTYPE_STRUCT, $2, 0); mi_api_parameter_child(parm, $4); $$ = parm; } | ARRAY parm_decl { miParameter *parm = mi_api_parameter_decl(miTYPE_ARRAY, 0, 0); mi_api_parameter_child(parm, $2); $$ = parm; } ; simple_type : BOOLEAN { $$ = miTYPE_BOOLEAN; } | INTEGER { $$ = miTYPE_INTEGER; } | SCALAR { $$ = miTYPE_SCALAR; } | STRING { $$ = miTYPE_STRING; } | COLOR { $$ = miTYPE_COLOR; } | VECTOR { $$ = miTYPE_VECTOR; } | TRANSFORM { $$ = miTYPE_TRANSFORM; } | SCALAR TEXTURE { $$ = miTYPE_SCALAR_TEX; } | VECTOR TEXTURE { $$ = miTYPE_VECTOR_TEX; } | COLOR TEXTURE { $$ = miTYPE_COLOR_TEX; } | LIGHT { $$ = miTYPE_LIGHT; } | MATERIAL { $$ = miTYPE_MATERIAL; } | GEOMETRY { $$ = miTYPE_GEOMETRY; } ; declare_req_seq : | declare_req declare_req_seq ; declare_req : gui | SCANLINE OFF { curr_decl->phen.scanline = 1; } | SCANLINE ON { curr_decl->phen.scanline = 2; } | TRACE OFF { curr_decl->phen.trace = 1; } | TRACE ON { curr_decl->phen.trace = 2; } | SHADOW OFF { curr_decl->phen.shadow = 1; } | SHADOW ON { curr_decl->phen.shadow = 2; } | SHADOW SORT { curr_decl->phen.shadow = 'l'; } | SHADOW SEGMENTS { curr_decl->phen.shadow = 's'; } | FACE FRONT { curr_decl->phen.face = 'f'; } | FACE BACK { curr_decl->phen.face = 'b'; } | FACE BOTH { curr_decl->phen.face = 'a'; } | TEXTURE T_INTEGER { curr_decl->phen.mintextures = $2; } | BUMP T_INTEGER { curr_decl->phen.minbumps = $2; } | DERIVATIVE { curr_decl->phen.deriv1 = curr_decl->phen.deriv2 = 0; } | DERIVATIVE T_INTEGER { if ($2 == 1) curr_decl->phen.deriv1 = miTRUE; else if ($2 == 2) curr_decl->phen.deriv2 = miTRUE; else mi_api_error("derivative not 1 or 2"); } | DERIVATIVE T_INTEGER T_INTEGER { if ($2 == 1 || $3 == 1) curr_decl->phen.deriv1 = miTRUE; else if ($2 == 2 || $3 == 2) curr_decl->phen.deriv2 = miTRUE; if ($2 != 1 && $2 != 2 || $3 != 1 && $3 != 2) mi_api_error("derivative not 1 or 2"); } | OBJECT SPACE { curr_decl->phen.render_space = 'o'; } | CAMERA SPACE { curr_decl->phen.render_space = 'c'; } | MIXED SPACE { curr_decl->phen.render_space = 'm'; } | WORLD SPACE { mi_api_warning("world space statement ignored"); } | SMART VOLUME boolean { curr_decl->phen.smart_volume = $3; } | VERSION T_INTEGER { curr_decl->version = $2; } | APPLY apply_list { curr_decl->apply = $2; } ; apply_list : apply { $$ = $1; } | apply ',' apply_list { $$ = $1 | $3; } ; apply : LENS { $$ = miAPPLY_LENS; } | MATERIAL { $$ = miAPPLY_MATERIAL; } | LIGHT { $$ = miAPPLY_LIGHT; } | SHADOW { $$ = miAPPLY_SHADOW; } | ENVIRONMENT { $$ = miAPPLY_ENVIRONMENT; } | VOLUME { $$ = miAPPLY_VOLUME; } | TEXTURE { $$ = miAPPLY_TEXTURE; } | PHOTON { $$ = miAPPLY_PHOTON; } | GEOMETRY { $$ = miAPPLY_GEOMETRY; } | DISPLACE { $$ = miAPPLY_DISPLACE; } | EMITTER { $$ = miAPPLY_PHOTON_EMITTER; } | OUTPUT { $$ = miAPPLY_OUTPUT; } ; /*----------------------------------------------------------------------------- * function instance *---------------------------------------------------------------------------*/ function_list : { funclist = miNULLTAG; } func_list { $$ = funclist; } ; func_list : function { funclist = $1; } | func_list function { funclist = mi_api_function_append(funclist, $2); } ; function : T_STRING { mi_api_function_call($1); } parameter_list { $$ = mi_api_function_call_end(functag); functag = 0;} | '=' symbol { $$ = mi_api_function_assign($2); } | '=' opt_incremental SHADER symbol function { mi_api_shader_add($4, $5); $$ = $5; mi_api_incremental(is_incremental); } ; opt_incremental : { mi_api_incremental(miFALSE); } | INCREMENTAL { mi_api_incremental(miTRUE); } ; parameter_list : '(' ')' | '(' parameter_seq ')' | '(' parameter_seq ',' ')' ; parameter_seq : parameter | parameter_seq ',' parameter ; parameter : symbol { mi_api_parameter_name($1); } value_list ; value_list : value | value_list value ; value : NULL_ | boolean { int value = $1; mi_api_parameter_value(miTYPE_BOOLEAN, &value,0,0); } | T_INTEGER { int value = $1; mi_api_parameter_value(miTYPE_INTEGER, &value,0,0); } | T_FLOAT { float value = $1; mi_api_parameter_value(miTYPE_SCALAR, &value,0,0); } | symbol { mi_api_parameter_value(miTYPE_STRING, $1, 0, 0); } | '=' symbol { mi_api_parameter_shader($2); } | '=' INTERFACE symbol { mi_api_parameter_interface($3); } | '{' { mi_api_parameter_push(miFALSE); } parameter_seq '}' { mi_api_parameter_pop(); } | '[' { mi_api_parameter_push(miTRUE); } array_value_seq ']' { mi_api_parameter_pop(); } | '[' ']' ; array_value_seq : { mi_api_new_array_element(); } value_list array_value_cont ; array_value_cont: | ',' { mi_api_new_array_element(); } value_list array_value_cont ; /*----------------------------------------------------------------------------- * phenomenon declaration *---------------------------------------------------------------------------*/ phenomenon_decl : PHENOMENON shret_type T_STRING { mi_api_phen_begin($3); } parm_decl_list { curr_decl = mi_api_phen_parameter_end($2, $5); if (!curr_decl) curr_decl = &dummy_decl; } phen_body_list END DECLARE { mi_api_phen_end(); } ; phen_body_list : | phen_body phen_body_list ; phen_body : SHADER symbol function_list { mi_api_shader_add($2, $3); } | material | light | instance | declare_req | ROOT phen_root { if (curr_decl->phen.root) mi_api_error("multiple roots not allowed"); else curr_decl->phen.root = $2; } | OUTPUT T_STRING T_STRING { curr_decl->phen.output = mi_api_function_append( curr_decl->phen.output, mi_api_output_file_def(0, 0, $2, $3)); } | OUTPUT T_STRING T_STRING T_STRING { mi_api_output_type_identify(&tbm, &ibm, $2); curr_decl->phen.output = mi_api_function_append( curr_decl->phen.output, mi_api_output_file_def(tbm, ibm, $3, $4));} | OUTPUT T_STRING function { mi_api_output_type_identify(&tbm, &ibm, $2); curr_decl->phen.output = mi_api_function_append( curr_decl->phen.output, mi_api_output_function_def(tbm, ibm, $3)); } | LENS function_list { curr_decl->phen.lens = mi_api_function_append( curr_decl->phen.lens, $2); } | VOLUME function_list { curr_decl->phen.volume = mi_api_function_append( curr_decl->phen.volume, $2); } | ENVIRONMENT function_list { curr_decl->phen.environment = mi_api_function_append( curr_decl->phen.environment, $2); } | GEOMETRY function_list { curr_decl->phen.geometry = mi_api_function_append( curr_decl->phen.geometry, $2);} | CONTOUR STORE function { curr_decl->phen.contour_store = $3; } | CONTOUR CONTRAST function { curr_decl->phen.contour_contrast = $3; } | OUTPUT PRIORITY T_INTEGER { curr_decl->phen.output_seqnr = $3; } | LENS PRIORITY T_INTEGER { curr_decl->phen.lens_seqnr = $3; } | VOLUME PRIORITY T_INTEGER { curr_decl->phen.volume_seqnr = $3; } ; phen_root : MATERIAL symbol { if (*curr_decl->declaration != 'm') { mi_api_error("not a material phenomenon"); $$ = 0; } else $$ = mi_api_material_lookup($2); } | LIGHT symbol { if (*curr_decl->declaration != 'l') { mi_api_error("not a light phenomenon"); $$ = 0; } else $$ = mi_api_light_lookup($2); } | function_list { $$ = 0; if (*curr_decl->declaration == 'm') mi_api_error("must use ``root material''"); else if (*curr_decl->declaration == 'l') mi_api_error("must use ``root light''"); else $$ = mi_api_function_append( curr_decl->phen.root, $1); } ; /*----------------------------------------------------------------------------- * texture *---------------------------------------------------------------------------*/ texture : { pyramid_filter = 0.; } tex_flags tex_type TEXTURE symbol { functag = mi_api_texture_begin($5,$3,$2); } tex_data { functag = 0; } ; tex_flags : { $$ = 0; } | tex_flag tex_flags { $$ = $1 | $2; } ; tex_flag : LOCAL { $$ = 1; } | FILTER { pyramid_filter = 1.; $$ = 2; } | FILTER floating { pyramid_filter = $2; $$ = (pyramid_filter > 0.) ? 2 : 0; } ; tex_type : COLOR { $$ = 0; } | SCALAR { $$ = 1; } | VECTOR { $$ = 2; } ; tex_data : '[' T_INTEGER T_INTEGER ']' { mi_api_texture_array_def_begin($2,$3,1); } tex_bytes_list { mi_api_texture_array_def_end(); } | '[' T_INTEGER T_INTEGER T_INTEGER ']' { mi_api_texture_array_def_begin($2,$3,$4); } tex_bytes_list { mi_api_texture_array_def_end(); } | tex_func_list { mi_api_texture_function_def($1); } | T_STRING { miTag itag = mi_api_texture_file_def($1); if (pyramid_filter > 0. && itag) { miImg_image *img = (miImg_image*) mi_scene_edit(itag); mi_img_pyramid_set_filter(img, pyramid_filter); mi_scene_edit_end(itag); }} ; tex_func_list : function { $$ = $1; } | function tex_func_list { $$ = mi_api_function_append($1, $2); } ; tex_bytes_list : | tex_bytes_list T_BYTE_STRING { mi_api_texture_byte_copy($2.len,$2.bytes); } ; /*----------------------------------------------------------------------------- * light *---------------------------------------------------------------------------*/ light : LIGHT symbol { curr_light = mi_api_light_begin($2); light_map = 0; } light_ops END LIGHT { switch(light_map & 6) { case 2: curr_light->type = miLIGHT_ORIGIN; break; case 4: curr_light->type = miLIGHT_DIRECTION;break; case 6: curr_light->type = miLIGHT_SPOT; break; } mi_api_light_end(); } ; light_ops : | light_op light_ops ; light_op : function { if (!(light_map & 1)) mi_api_function_delete(&curr_light->shader); light_map |= 1; curr_light->shader = mi_api_function_append( curr_light->shader, $1); } | EMITTER function { if (!(light_map & 8)) mi_api_function_delete(&curr_light->emitter); light_map |= 8; curr_light->emitter = mi_api_function_append( curr_light->emitter, $2); } | SHADOWMAP { curr_light->use_shadow_maps = miTRUE; } | SHADOWMAP boolean { curr_light->use_shadow_maps = $2; } | ORIGIN vector { curr_light->origin = $2; light_map |= 2; } | DIRECTION vector { curr_light->direction = $2; mi_vector_normalize(&curr_light->direction); light_map |= 4; } | ENERGY floating floating floating { curr_light->energy.r = $2; curr_light->energy.g = $3; curr_light->energy.b = $4; } | EXPONENT floating { curr_light->exponent = $2; } | CAUSTIC PHOTONS T_INTEGER { curr_light->caustic_photons = $3; } | GLOBILLUM PHOTONS T_INTEGER { curr_light->global_photons = $3; } | RECTANGLE vector vector { curr_light->area = miLIGHT_RECTANGLE; curr_light->primitive.rectangle.edge_u = $2; curr_light->primitive.rectangle.edge_v = $3; } | RECTANGLE vector vector T_INTEGER T_INTEGER { curr_light->area = miLIGHT_RECTANGLE; curr_light->primitive.rectangle.edge_u = $2; curr_light->primitive.rectangle.edge_v = $3; curr_light->samples_u = $4; curr_light->samples_v = $5; } | DISC vector floating { curr_light->area = miLIGHT_DISC; curr_light->primitive.disc.normal = $2; curr_light->primitive.disc.radius = $3; } | DISC vector floating T_INTEGER T_INTEGER { curr_light->area = miLIGHT_DISC; curr_light->primitive.disc.normal = $2; curr_light->primitive.disc.radius = $3; curr_light->samples_u = $4; curr_light->samples_v = $5; } | SPHERE floating { curr_light->area = miLIGHT_SPHERE; curr_light->primitive.sphere.radius = $2; } | SPHERE floating T_INTEGER T_INTEGER { curr_light->area = miLIGHT_SPHERE; curr_light->primitive.sphere.radius = $2; curr_light->samples_u = $3; curr_light->samples_v = $4; } | SPREAD floating { curr_light->spread = $2; } | SHADOWMAP RESOLUTION T_INTEGER { curr_light->shadowmap_resolution = $3; } | SHADOWMAP SOFTNESS floating { curr_light->shadowmap_softness = $3; } | SHADOWMAP SAMPLES T_INTEGER { curr_light->shadowmap_samples = $3; } | SHADOWMAP FILE_ T_STRING { mi_scene_delete(curr_light->shadowmap_file); strcpy((char *)mi_scene_create( &curr_light->shadowmap_file, miSCENE_STRING, strlen($3)+1), $3); mi_db_unpin(curr_light->shadowmap_file); mi_mem_release($3); } | VISIBLE { curr_light->visible = miTRUE; } ; /*----------------------------------------------------------------------------- * material *---------------------------------------------------------------------------*/ material : MATERIAL symbol { curr_mtl = mi_api_material_begin($2); have_d = have_s = have_v = have_e = have_c = have_p = have_pv = 0; } mtl_flags function_list { curr_mtl->shader = $5; } mtl_args END MATERIAL { mi_api_material_end(); } ; mtl_flags : | mtl_flag mtl_flags ; mtl_flag : NOCONTOUR { mi_api_warning( "obsolete \"nocontour\" flag ignored"); } | OPAQUE_ { curr_mtl->opaque = miTRUE; } ; mtl_args : | mtl_arg mtl_args ; mtl_arg : DISPLACE { mi_api_function_delete(&curr_mtl->displace); } | DISPLACE function_list { if (!have_d++) mi_api_function_delete(&curr_mtl->displace); curr_mtl->displace = $2; } | SHADOW { mi_api_function_delete(&curr_mtl->shadow); } | SHADOW function_list { if (!have_s++) mi_api_function_delete(&curr_mtl->shadow); curr_mtl->shadow = $2; } | VOLUME { mi_api_function_delete(&curr_mtl->volume); } | VOLUME function_list { if (!have_v++) mi_api_function_delete(&curr_mtl->volume); curr_mtl->volume = $2; } | ENVIRONMENT { mi_api_function_delete(&curr_mtl->environment); } | ENVIRONMENT function_list { if (!have_e++) mi_api_function_delete(&curr_mtl->environment); curr_mtl->environment = $2; } | CONTOUR { mi_api_function_delete(&curr_mtl->contour); } | CONTOUR function_list { if (!have_c++) mi_api_function_delete(&curr_mtl->contour); curr_mtl->contour = $2; } | PHOTON { mi_api_function_delete(&curr_mtl->photon); } | PHOTON function_list { if (!have_p++) mi_api_function_delete(&curr_mtl->photon); curr_mtl->photon = $2; } | PHOTONVOL { mi_api_function_delete(&curr_mtl->photonvol); } | PHOTONVOL function_list { if (!have_pv++) mi_api_function_delete(&curr_mtl->photonvol); curr_mtl->photonvol = $2; } ; /*----------------------------------------------------------------------------- * object *---------------------------------------------------------------------------*/ object : OBJECT opt_symbol { visible=shadow=trace=mtl_is_label=miFALSE; caustic=label=0; } obj_flags obj_transform { mi_api_object_begin($2,visible,shadow,trace,caustic, label, is_obj_transf ? $5 : 0, mtl_is_label); mi_api_basis_list_clear(); } bases_and_groups END OBJECT { mi_api_object_end(); mi_api_basis_list_clear(); } ; obj_flags : | obj_flag obj_flags ; obj_flag : VISIBLE { visible = miTRUE; } | SHADOW { shadow = miTRUE; } | TRACE { trace = miTRUE; } | TAGGED { mtl_is_label = miTRUE; } | CAUSTIC { caustic = 3; } | CAUSTIC T_INTEGER { caustic = $2; } | TAG T_INTEGER { label = $2; } ; obj_transform : { is_obj_transf = miFALSE; } | transform { is_obj_transf = miTRUE; (void)memcpy($$, $1, sizeof(miMatrix)); } ; bases_and_groups: | basis bases_and_groups | group bases_and_groups ; basis : BASIS symbol rational MATRIX T_INTEGER T_INTEGER basis_matrix { mi_api_basis_add($2, $3, miBASIS_MATRIX, $5, $6, $7); mi_api_dlist_delete($7); } | BASIS symbol rational BEZIER T_INTEGER { mi_api_basis_add($2, $3, miBASIS_BEZIER, $5, 0, 0); } | BASIS symbol rational TAYLOR T_INTEGER { mi_api_basis_add($2, $3, miBASIS_TAYLOR, $5, 0, 0); } | BASIS symbol rational BSPLINE T_INTEGER { mi_api_basis_add($2, $3, miBASIS_BSPLINE, $5, 0, 0);} | BASIS symbol rational CARDINAL { mi_api_basis_add($2, $3, miBASIS_CARDINAL, 0, 0, 0);} ; rational : { $$ = miFALSE; } | RATIONAL { $$ = miTRUE; } ; basis_matrix : { $$ = mi_api_dlist_create(miDLIST_GEOSCALAR); } | basis_matrix floating { miGeoScalar s=$2; mi_api_dlist_add($1, &s); $$=$1; } ; group : GROUP opt_symbol merge_option { mi_api_object_group_begin($2, $3); are_polys = are_surfs = miFALSE; } vector_list vertex_list geometry_list END GROUP { mi_api_object_group_end(are_polys, are_surfs); } ; merge_option : { $$ = 0.0; } | MERGE floating { $$ = $2; } ; vector_list : | vector_list geovector { mi_api_geovector_xyz_add(&$2); } ; vertex_list : | vertex_list vertex ; vertex : V T_INTEGER { mi_api_vertex_add($2); } n_vector d_vector t_vector_list m_vector u_vector_list ; n_vector : | N T_INTEGER { mi_api_vertex_normal_add($2); } ; d_vector : | D T_INTEGER T_INTEGER { mi_api_vertex_deriv_add($2, $3); } | D T_INTEGER T_INTEGER T_INTEGER { mi_api_vertex_deriv2_add($2, $3, $4); } | D T_INTEGER T_INTEGER T_INTEGER T_INTEGER T_INTEGER { mi_api_vertex_deriv_add($2, $3); mi_api_vertex_deriv2_add($4, $5, $6); } ; m_vector : | M T_INTEGER { mi_api_vertex_motion_add($2); } ; t_vector_list : | t_vector_list T T_INTEGER { mi_api_vertex_tex_add($3, -1, -1); } | t_vector_list T T_INTEGER T_INTEGER T_INTEGER { mi_api_vertex_tex_add($3, $4, $5); } ; u_vector_list : | u_vector_list U T_INTEGER { mi_api_vertex_user_add($3); } ; geometry_list : | geometry_list geometry ; geometry : polygon | curve | surface | connection | approximation ; polygon : CP opt_symbol { mi_api_poly_begin(1, $2); } poly_indices { mi_api_poly_end(); are_polys = miTRUE; } | P opt_symbol { mi_api_poly_begin(0, $2); } poly_indices { mi_api_poly_end(); are_polys = miTRUE; } | STRIP opt_symbol { mi_api_poly_begin(2, $2); } strip_indices { mi_api_poly_end(); are_polys = miTRUE; } | FAN opt_symbol { mi_api_poly_begin(3, $2); } strip_indices { mi_api_poly_end(); are_polys = miTRUE; } ; poly_indices : | T_INTEGER { mi_api_poly_index_add($1); } poly_indices | HOLE { mi_api_poly_hole_add(); } poly_indices ; strip_indices : | T_INTEGER { mi_api_poly_index_add($1); } strip_indices ; h_vertex_ref_seq: h_vertex_ref | h_vertex_ref_seq h_vertex_ref ; h_vertex_ref : T_INTEGER { mi_api_vertex_ref_add($1, (double)1.0); } | T_INTEGER T_FLOAT { mi_api_vertex_ref_add($1, $2); } | T_INTEGER W floating { mi_api_vertex_ref_add($1, $3); } ; para_list : T_FLOAT { miDlist *dlp =mi_api_dlist_create(miDLIST_GEOSCALAR); miGeoScalar s = $1; /* $1 is a double */ mi_api_dlist_add(dlp, &s); $$ = dlp; } | para_list T_FLOAT { miGeoScalar s = $2; /* $2 is a double */ mi_api_dlist_add($1, &s); $$ = $1; } ; curve : CURVE symbol rational symbol { mi_api_curve_begin($2,$4,$3); } para_list h_vertex_ref_seq curve_spec { mi_api_curve_end($6); } ; curve_spec : | SPECIAL curve_special_list ; curve_special_list : curve_special | curve_special_list curve_special ; curve_special : T_INTEGER { mi_api_curve_specpnt($1, -1); } | T_INTEGER MAPSTO T_INTEGER { mi_api_curve_specpnt($1, $3); } ; surface : SURFACE symbol mtl_or_label { mi_api_surface_begin($2, $3); } rational symbol floating floating para_list { mi_api_surface_params(miU, $6, $7, $8, $9, $5); } rational symbol floating floating para_list { mi_api_surface_params(miV, $12, $13, $14, $15, $11);} h_vertex_ref_seq tex_surf_list surf_spec_list { mi_api_surface_end(); are_surfs = miTRUE; } ; mtl_or_label : symbol { $$ = $1; } | T_INTEGER { $$ = (char *)$1; } ; tex_surf_list : | tex_surf_list tex_surf ; tex_surf : opt_volume_flag opt_vector_flag TEXTURE rational symbol para_list rational symbol para_list { mi_api_surface_texture_begin( $1, $2, $5, $6, $4, $8, $9, $7); } h_vertex_ref_seq | DERIVATIVE { mi_api_surface_derivative(1); } | DERIVATIVE T_INTEGER { mi_api_surface_derivative($2); } | DERIVATIVE T_INTEGER T_INTEGER { mi_api_surface_derivative($2); mi_api_surface_derivative($3); } ; opt_volume_flag : { $$ = miFALSE; } | VOLUME { $$ = miTRUE; } ; opt_vector_flag : { $$ = miFALSE; } | VECTOR { $$ = miTRUE; } ; surf_spec_list : | surf_spec_list surf_spec ; surf_spec : TRIM trim_spec_list | HOLE hole_spec_list | SPECIAL { newloop = miTRUE; } special_spec_list ; trim_spec_list : symbol floating floating { miGeoRange r; r.min = $2; r.max = $3; mi_api_surface_curveseg(miTRUE, miCURVE_TRIM,$1,&r);} | trim_spec_list symbol floating floating { miGeoRange r; r.min = $3; r.max = $4; mi_api_surface_curveseg(miFALSE,miCURVE_TRIM,$2,&r);} ; hole_spec_list : symbol floating floating { miGeoRange r; r.min = $2; r.max = $3; mi_api_surface_curveseg(miTRUE,miCURVE_HOLE,$1,&r); } | hole_spec_list symbol floating floating { miGeoRange r; r.min = $3; r.max = $4; mi_api_surface_curveseg(miFALSE,miCURVE_HOLE,$2,&r);} ; special_spec_list : special_spec | special_spec_list special_spec ; special_spec : T_INTEGER { mi_api_surface_specpnt($1, -1); } | T_INTEGER MAPSTO T_INTEGER { mi_api_surface_specpnt($1, $3); } | symbol floating floating { miGeoRange r; r.min = $2; r.max = $3; mi_api_surface_curveseg(newloop, miCURVE_SPECIAL, $1, &r); newloop = miFALSE; } ; connection : CONNECT symbol symbol floating floating symbol symbol floating floating { miGeoRange c1, c2; c1.min = $4; c1.max = $5; c2.min = $8; c2.max = $9; mi_api_object_group_connection($2,$3,&c1,$6,$7,&c2);} ; /*----------------------------------------------------------------------------- * approximations (in objects and options) *---------------------------------------------------------------------------*/ approximation : { miAPPROX_DEFAULT(approx); } approx_body ; approx_body : APPROXIMATE SURFACE s_approx_tech s_approx_names | APPROXIMATE DISPLACE s_approx_tech d_approx_names | APPROXIMATE CURVE c_approx_tech c_approx_names | APPROXIMATE TRIM c_approx_tech t_approx_names | APPROXIMATE s_approx_tech { mi_api_poly_approx(&approx); } ; s_approx_tech : s_approx_params { approx.subdiv[miMIN] = 0; approx.subdiv[miMAX] = 5; } | s_approx_params T_INTEGER T_INTEGER { approx.subdiv[miMIN] = $2; approx.subdiv[miMAX] = $3; } ; c_approx_tech : c_approx_params { approx.subdiv[miMIN] = 0; approx.subdiv[miMAX] = 5; } | c_approx_params T_INTEGER T_INTEGER { approx.subdiv[miMIN] = $2; approx.subdiv[miMAX] = $3; } ; s_approx_params : s_approx_param | s_approx_param s_approx_params ; c_approx_params : c_approx_param | c_approx_param c_approx_params ; s_approx_param : x_approx_param | PARAMETRIC floating floating { approx.method = miAPPROX_PARAMETRIC; approx.cnst[miCNST_UPARAM] = $2; approx.cnst[miCNST_VPARAM] = $3; } | REGULAR PARAMETRIC floating floating { approx.method = miAPPROX_REGULAR; approx.cnst[miCNST_UPARAM] = $3; approx.cnst[miCNST_VPARAM] = $4; } | IMPLICIT { approx.method = miAPPROX_ALGEBRAIC; } ; c_approx_param : x_approx_param | PARAMETRIC floating { approx.method = miAPPROX_PARAMETRIC; approx.cnst[miCNST_UPARAM] = $2; approx.cnst[miCNST_VPARAM] = 1.0; } | REGULAR PARAMETRIC floating { approx.method = miAPPROX_REGULAR; approx.cnst[miCNST_UPARAM] = $3; approx.cnst[miCNST_VPARAM] = 1.0; } ; x_approx_param : VIEW { approx.view_dep = miTRUE; } | TREE { approx.style = miAPPROX_STYLE_TREE;} | GRID { approx.style = miAPPROX_STYLE_GRID;} | MESH { approx.style = miAPPROX_STYLE_MESH;} | LENGTH floating { approx.method = miAPPROX_LDA; approx.cnst[miCNST_LENGTH] = $2; } | DISTANCE floating { approx.method = miAPPROX_LDA; approx.cnst[miCNST_DISTANCE] = $2; } | ANGLE floating { approx.method = miAPPROX_LDA; approx.cnst[miCNST_ANGLE] = $2; } | SPATIAL approx_view floating { approx.method = miAPPROX_SPATIAL; approx.cnst[miCNST_LENGTH] = $3; } | CURVATURE approx_view floating floating { approx.method = miAPPROX_CURVATURE; approx.cnst[miCNST_DISTANCE] = $3; approx.cnst[miCNST_ANGLE] = $4; } ; approx_view : | VIEW { approx.view_dep = miTRUE; } ; s_approx_names : symbol { mi_api_surface_approx($1, &approx); } | s_approx_names symbol { mi_api_surface_approx($2, &approx); } ; d_approx_names : symbol { mi_api_surface_approx_displace($1, &approx); } | s_approx_names symbol { mi_api_surface_approx_displace($2, &approx); } ; c_approx_names : symbol { mi_api_curve_approx($1, &approx); } | c_approx_names symbol { mi_api_curve_approx($2, &approx); } ; t_approx_names : symbol { mi_api_surface_approx_trim($1, &approx); } | t_approx_names symbol { mi_api_surface_approx_trim($2, &approx); } ; %%
= pcrr at 12.0pt