Esempio n. 1
0
/**
 * Executes a GFX DEFINE GLYPH command.
 */
int gfx_define_glyph(struct Parse_state *state,
	void *glyph_name_void, void *define_glyph_data_void)
{
	int return_code = 1;
	Define_glyph_data *define_glyph_data = static_cast<Define_glyph_data *>(define_glyph_data_void);
	if ((state) && (define_glyph_data))
	{
		if (state->current_token)
		{
			const char *glyph_name = static_cast<char *>(glyph_name_void);
			bool process = false;
			if (glyph_name)
			{
				process = true;
			}
			else
			{
				if (Parse_state_help_mode(state))
				{
					glyph_name = "GLYPH_NAME";
					Option_table *option_table = CREATE(Option_table)();
					Option_table_add_entry(option_table, "GLYPH_NAME",
						(void *)glyph_name, define_glyph_data_void, gfx_define_glyph);
					return_code = Option_table_parse(option_table, state);
					DESTROY(Option_table)(&option_table);
				}
				else
				{
					glyph_name = state->current_token;
					shift_Parse_state(state, 1);
					process = true;
				}
			}
			if (process)
			{
				char *scene_path_name = 0;
				struct Option_table *option_table = CREATE(Option_table)();
				Option_table_add_help(option_table,
					"The 'scene' option defines a static glyph from the named graphics "
					"at the region/scene path.");
				/* scene (graphics) */
				Option_table_add_string_entry(option_table, "scene",
					&scene_path_name, " [/REGION_PATH.]GRAPHICS_NAME");

				return_code = Option_table_multi_parse(option_table, state);
				if (return_code)
				{
					cmzn_graphics* graphics = 0;
					const char *scene_name = 0;
					const char *graphics_name = 0;
					if (scene_path_name)
						export_object_name_parser(scene_path_name, &scene_name, &graphics_name);
					cmzn_region *input_region =
						cmzn_region_find_subregion_at_path(define_glyph_data->root_region, scene_name);
					if (input_region && graphics_name)
					{
						cmzn_scene_id scene = cmzn_region_get_scene(input_region);
						graphics = cmzn_scene_find_graphics_by_name(scene, graphics_name);
						cmzn_scene_destroy(&scene);
					}
					if (!graphics)
					{
						display_message(ERROR_MESSAGE,
							"gfx_define_glyph.  Invalid scene region path or graphics name");
						return_code = 0;
					}
					else
					{
						cmzn_glyphmodule_begin_change(define_glyph_data->glyphmodule);
						cmzn_glyph_id glyph = cmzn_glyphmodule_find_glyph_by_name(define_glyph_data->glyphmodule, glyph_name);
						if (glyph)
						{
							struct GT_object *graphics_object = cmzn_graphics_copy_graphics_object(
								graphics);
							if (!cmzn_glyph_set_graphics_object(glyph, graphics_object))
							{
								display_message(ERROR_MESSAGE, "gfx_define_glyph.  Unable to change glyph");
								return_code = 0;
							}
							DEACCESS(GT_object)(&graphics_object);
						}
						else
						{
							glyph = cmzn_glyphmodule_create_static_glyph_from_graphics(define_glyph_data->glyphmodule,
								graphics);
							if ((CMZN_OK != cmzn_glyph_set_name(glyph, glyph_name)) ||
								(CMZN_OK != cmzn_glyph_set_managed(glyph, true)))
							{
								display_message(ERROR_MESSAGE, "gfx_define_glyph.  Failed");
								return_code = 0;
							}
						}
						cmzn_glyph_destroy(&glyph);
						cmzn_glyphmodule_end_change(define_glyph_data->glyphmodule);
					}
					cmzn_graphics_destroy(&graphics);
					cmzn_region_destroy(&input_region);
					if (scene_name)
						DEALLOCATE(scene_name);
					if (graphics_name)
						DEALLOCATE(graphics_name);
				}
				if (scene_path_name)
					DEALLOCATE(scene_path_name);
				DESTROY(Option_table)(&option_table);
			}
		}
		else
		{
			display_message(ERROR_MESSAGE, "Missing glyph name");
			display_parse_state_location(state);
			return_code=0;
		}
	}
	else
	{
		display_message(ERROR_MESSAGE, "gfx_define_glyph.  Invalid argument(s)");
		return_code = 0;
	}
	return (return_code);
}
int define_Computed_field_type_compose(struct Parse_state *state,
	void *field_modify_void, void *computed_field_compose_package_void)
/*******************************************************************************
LAST MODIFIED : 24 August 2006

DESCRIPTION :
Converts <field> into type COMPUTED_FIELD_COMPOSE (if it is not
already) and allows its contents to be modified.
==============================================================================*/
{
	int return_code;
	Computed_field_compose_package *computed_field_compose_package;
	Computed_field_modify_data *field_modify;
	struct Option_table *find_option_table, *option_table,
		*out_of_bounds_option_table;
	struct Set_Computed_field_conditional_data set_calculate_values_field_data,
		set_find_element_xi_field_data, set_texture_coordinates_field_data;

	ENTER(define_Computed_field_type_compose);
	if (state && (field_modify=(Computed_field_modify_data *)field_modify_void) &&
		(computed_field_compose_package =
			(Computed_field_compose_package *)
			computed_field_compose_package_void))
	{
		return_code = 1;
		Cmiss_mesh_id mesh = 0;
		char *search_group_name = 0;
		Cmiss_field_id calculate_values_field = 0;
		Cmiss_field_id find_element_xi_field = 0;
		Cmiss_field_id texture_coordinates_field = 0;
		char find_nearest_flag = 0;
		char find_exact_flag = 0;
		char use_point_five_when_out_of_bounds_flag = 0;
		char fail_when_out_of_bounds_flag = 0;
		int use_point_five_when_out_of_bounds = 0;
		int element_dimension = 0;
		/* Maintain the existing behaviour as the default */
		int find_nearest = 0;
		/* get valid parameters for composite field */
		if (field_modify->get_field())
		{
			Computed_field_compose* compose_core =
				dynamic_cast<Computed_field_compose*>(field_modify->get_field()->core);
			if (compose_core)
			{
				return_code = compose_core->get_type(
					&calculate_values_field, &find_element_xi_field,
					&texture_coordinates_field, &mesh,
					&find_nearest, &use_point_five_when_out_of_bounds);
				if (mesh)
				{
					Cmiss_mesh_access(mesh);
					element_dimension = Cmiss_mesh_get_dimension(mesh);
				}
			}
		}
		if (return_code)
		{
			/* must access objects for set functions */
			if (calculate_values_field)
			{
				ACCESS(Computed_field)(calculate_values_field);
			}
			if (find_element_xi_field)
			{
				ACCESS(Computed_field)(find_element_xi_field);
			}
			if (texture_coordinates_field)
			{
				ACCESS(Computed_field)(texture_coordinates_field);
			}

			option_table = CREATE(Option_table)();
			Option_table_add_help(option_table,
				"The value of a compose field is found by evaluating the <texture_coordinates_field>, "
				"then searching for matching values of the <find_element_xi_field> in the elements of "
				"the <mesh> (alternatively specified by <group> and <element_dimension>) and then "
				"finally evaluating the <calculate_values_field> at this found location.  You can "
				"specify the outcome if the matching values cannot be found in the mesh with "
				"<use_point_five_when_out_of_bounds> or <fail_when_out_of_bounds>.  See examples "
				"a/resample_texture or a/create_slices where the compose field is used to find the "
				"equivalent coordinate in another element to evaluate a texture.");
			/* calculate_values_field */
			set_calculate_values_field_data.computed_field_manager =
				field_modify->get_field_manager();
			set_calculate_values_field_data.conditional_function =
				Computed_field_has_numerical_components;
			set_calculate_values_field_data.conditional_function_user_data =
				(void *)NULL;
			Option_table_add_entry(option_table, "calculate_values_field",
				&calculate_values_field, &set_calculate_values_field_data,
				set_Computed_field_conditional);
			Option_table_add_int_positive_entry(option_table,"element_dimension",
				&element_dimension);
			/* find_element_xi_field */
			set_find_element_xi_field_data.computed_field_manager =
				field_modify->get_field_manager();
			set_find_element_xi_field_data.conditional_function =
				Computed_field_has_numerical_components;
			set_find_element_xi_field_data.conditional_function_user_data =
				(void *)NULL;
			Option_table_add_entry(option_table, "find_element_xi_field",
				&find_element_xi_field, &set_find_element_xi_field_data,
				set_Computed_field_conditional);
			find_option_table=CREATE(Option_table)();
			Option_table_add_char_flag_entry(find_option_table,"find_nearest",
				&find_nearest_flag);
			Option_table_add_char_flag_entry(find_option_table,"find_exact",
				&find_exact_flag);
			Option_table_add_suboption_table(option_table, find_option_table);
			/* group */
			Option_table_add_string_entry(option_table, "group",
				 &search_group_name, " GROUP_NAME");
			// mesh
			Option_table_add_mesh_entry(option_table, "mesh", field_modify->get_region(), &mesh);
			/* texture_coordinates_field */
			set_texture_coordinates_field_data.computed_field_manager =
				field_modify->get_field_manager();
			set_texture_coordinates_field_data.conditional_function =
				Computed_field_has_numerical_components;
			set_texture_coordinates_field_data.conditional_function_user_data =
				(void *)NULL;
			Option_table_add_entry(option_table, "texture_coordinates_field",
				&texture_coordinates_field, &set_texture_coordinates_field_data,
				set_Computed_field_conditional);
			out_of_bounds_option_table=CREATE(Option_table)();
			/* use_point_five_when_out_of_bounds */
			Option_table_add_char_flag_entry(out_of_bounds_option_table,
				"use_point_five_when_out_of_bounds",
				&use_point_five_when_out_of_bounds_flag);
			Option_table_add_char_flag_entry(out_of_bounds_option_table,
				"fail_when_out_of_bounds",
				&fail_when_out_of_bounds_flag);
			Option_table_add_suboption_table(option_table, out_of_bounds_option_table);
			return_code = Option_table_multi_parse(option_table, state);

			if (return_code && !mesh)
			{
				mesh = Cmiss_field_module_find_mesh_by_dimension(
					field_modify->get_field_module(), element_dimension);
				if (search_group_name)
				{
					Cmiss_field_id group_field = Cmiss_field_module_find_field_by_name(field_modify->get_field_module(), search_group_name);
					Cmiss_field_group_id group = Cmiss_field_cast_group(group_field);
					Cmiss_field_element_group_id element_group = Cmiss_field_group_get_element_group(group, mesh);
					Cmiss_mesh_destroy(&mesh);
					mesh = Cmiss_mesh_group_base_cast(Cmiss_field_element_group_get_mesh(element_group));
					Cmiss_field_element_group_destroy(&element_group);
					Cmiss_field_group_destroy(&group);
					Cmiss_field_destroy(&group_field);
				}
			}
			if (return_code && !mesh)
			{
				display_message(ERROR_MESSAGE, "You must specify a mesh (or element_dimension and optional group).");
				return_code = 0;
			}
			if (return_code)
			{
				if (find_nearest_flag && find_exact_flag)
				{
					display_message(ERROR_MESSAGE,
						"Specify only one of find_nearest and find_exact");
					return_code = 0;
				}
				if (find_nearest_flag)
				{
					find_nearest = 1;
				}
				else if (find_exact_flag)
				{
					find_nearest = 0;
				}
				if (use_point_five_when_out_of_bounds_flag &&
					fail_when_out_of_bounds_flag)
				{
					display_message(ERROR_MESSAGE,
						"Specify only one of use_point_five_when_out_of_bounds "
						"and fail_when_out_of_bounds");
					return_code = 0;
				}
				if (use_point_five_when_out_of_bounds_flag)
				{
					use_point_five_when_out_of_bounds = 1;
				}
				else if (fail_when_out_of_bounds_flag)
				{
					use_point_five_when_out_of_bounds = 0;
				}
			}
			if (return_code)
			{
				return_code = field_modify->update_field_and_deaccess(
					Computed_field_create_compose(field_modify->get_field_module(),
						texture_coordinates_field, find_element_xi_field,
						calculate_values_field, mesh,
						find_nearest, use_point_five_when_out_of_bounds));
			}
			if (!return_code)
			{
				if ((!state->current_token) ||
					(strcmp(PARSER_HELP_STRING, state->current_token)&&
						strcmp(PARSER_RECURSIVE_HELP_STRING, state->current_token)))
				{
					/* error */
					display_message(ERROR_MESSAGE,
						"define_Computed_field_type_compose.  Failed");
				}
			}
			Cmiss_mesh_destroy(&mesh);
			if (calculate_values_field)
			{
				DEACCESS(Computed_field)(&calculate_values_field);
			}
			if (find_element_xi_field)
			{
				DEACCESS(Computed_field)(&find_element_xi_field);
			}
			if (search_group_name)
			{
				DEALLOCATE(search_group_name);
			}
			if (texture_coordinates_field)
			{
				DEACCESS(Computed_field)(&texture_coordinates_field);
			}
			DESTROY(Option_table)(&option_table);
		}
	}
	else
	{
		display_message(ERROR_MESSAGE,
			"define_Computed_field_type_compose.  Invalid argument(s)");
		return_code = 0;
	}
	LEAVE;

	return (return_code);
} /* define_Computed_field_type_compose */
Esempio n. 3
0
int gfx_define_font(struct Parse_state *state,
	void *dummy_to_be_modified,void *graphics_module_void)
/*******************************************************************************
LAST MODIFIED : 12 March 2008

DESCRIPTION :
Executes a GFX DEFINE FONT command.
==============================================================================*/
{
	const char *current_token, *font_name;
	int return_code;
	Cmiss_graphics_module_id graphics_module = 0;

	if (state && (graphics_module = (Cmiss_graphics_module_id)graphics_module_void))
	{
		if (NULL != (current_token = state->current_token))
		{
			if (strcmp(PARSER_HELP_STRING,current_token)&&
				strcmp(PARSER_RECURSIVE_HELP_STRING,current_token))
			{
				font_name = current_token;
				if (shift_Parse_state(state,1)&&
					(current_token=state->current_token))
				{
					Cmiss_graphics_font_id font = Cmiss_graphics_module_find_font_by_name(
						graphics_module, font_name);
					if (!font)
					{
						font = Cmiss_graphics_module_create_font(graphics_module);
						Cmiss_graphics_font_set_name(font, font_name);
					}
					Cmiss_graphics_font_type font_type = Cmiss_graphics_font_get_type(font);
					Cmiss_graphics_font_true_type true_type = Cmiss_graphics_font_get_true_type(font);
					char *font_type_string = 0;
					char *true_type_string = 0;
					int number_of_valid_strings_font_type = 0;
					int number_of_valid_strings_true_type = 0;
					const char **valid_font_type_strings = ENUMERATOR_GET_VALID_STRINGS(Cmiss_graphics_font_type)(
						&number_of_valid_strings_font_type,
						(ENUMERATOR_CONDITIONAL_FUNCTION(Cmiss_graphics_font_type) *)NULL,
						(void *)NULL);
					std::string all_font_types = " ";
					for (int i = 0; i < number_of_valid_strings_font_type; i++)
					{
						if (i)
							all_font_types += "|";

						all_font_types += valid_font_type_strings[i];
					}
					const char *all_font_types_help = all_font_types.c_str();
					const char **valid_font_true_type_strings = ENUMERATOR_GET_VALID_STRINGS(Cmiss_graphics_font_true_type)(
						&number_of_valid_strings_true_type,
						(ENUMERATOR_CONDITIONAL_FUNCTION(Cmiss_graphics_font_true_type) *)NULL,
						(void *)NULL);
					std::string all_font_true_types = " ";
					for (int i = 0; i < number_of_valid_strings_true_type; i++)
					{
						if (i)
							all_font_true_types += "|";

						all_font_true_types += valid_font_true_type_strings[i];
					}
					const char *all_font_true_types_help = all_font_true_types.c_str();

					struct Option_table *option_table = CREATE(Option_table)();
					int bold_flag = 0;
					int italic_flag = 0;
					float depth = (float)Cmiss_graphics_font_get_depth(font);
					int size = Cmiss_graphics_font_get_size(font);
					/* bold */
					Option_table_add_entry(option_table, "bold",
						(void *)&bold_flag, NULL, set_char_flag);
					Option_table_add_entry(option_table, "italic",
						(void *)&italic_flag, NULL, set_char_flag);
					Option_table_add_entry(option_table,"depth",
						&(depth),NULL,set_float);
					Option_table_add_entry(option_table,"size",
						&(size),NULL,set_int_non_negative);
					Option_table_add_string_entry(option_table, "font_type",
						&font_type_string, all_font_types_help);
					Option_table_add_string_entry(option_table, "true_type",
						&true_type_string, all_font_true_types_help);
					return_code = Option_table_multi_parse(option_table, state);
					if (return_code)
					{
						if (font_type_string)
						{
							STRING_TO_ENUMERATOR(Cmiss_graphics_font_type)(font_type_string,
								&font_type);
							if (CMISS_GRAPHICS_FONT_TYPE_INVALID == font_type)
							{
								display_message(ERROR_MESSAGE,
									"gfx_define_font:  Invalid font type %s", font_type_string);
								return_code = 0;
							}
						}
						else
						{
							display_message(ERROR_MESSAGE,
								"gfx_define_font:  Missing font_type argument");
							return_code = 0;
						}
						if (true_type_string)
						{
							STRING_TO_ENUMERATOR(Cmiss_graphics_font_true_type)(true_type_string,
								&true_type);
							if (CMISS_GRAPHICS_FONT_TRUE_TYPE_INVALID == true_type)
							{
								display_message(ERROR_MESSAGE,
									"gfx_define_font:  Invalid true type %s", true_type_string);
								return_code = 0;
							}
						}
						else
						{
							display_message(ERROR_MESSAGE,
								"gfx_define_font:  Missing true_type argument");
							return_code = 0;
						}
						if (font)
						{
							Cmiss_graphics_font_set_bold(font, bold_flag);
							Cmiss_graphics_font_set_italic(font, italic_flag);
							Cmiss_graphics_font_set_depth(font, depth);
							Cmiss_graphics_font_set_size(font, size);
							Cmiss_graphics_font_set_true_type(font, true_type);
							Cmiss_graphics_font_set_type(font, font_type);
						}

					}

					Cmiss_graphics_font_destroy(&font);
					DEALLOCATE(font_type_string);
					DEALLOCATE(true_type_string);
					DESTROY(Option_table)(&option_table);
				}
				else
				{
					display_message(WARNING_MESSAGE,"Missing font string.");
					display_parse_state_location(state);
					return_code=0;
				}
			}
int define_Computed_field_type_nodal_lookup(struct Parse_state *state,
	void *field_modify_void, void *computed_field_lookup_package_void)
/*******************************************************************************
LAST MODIFIED : 25 August 2006

DESCRIPTION :
Converts <field> into type COMPUTED_FIELD_NODAL_LOOKUP (if it is not
already) and allows its contents to be modified.
==============================================================================*/
{
	int return_code;
	Computed_field_lookup_package *computed_field_lookup_package;
	Computed_field_modify_data *field_modify;

	if (state&&(field_modify=(Computed_field_modify_data *)field_modify_void) &&
		(computed_field_lookup_package=
		(Computed_field_lookup_package *)
		computed_field_lookup_package_void))
	{
		return_code = 1;
		Cmiss_field_id source_field = 0;
		char *nodeset_name = duplicate_string("cmiss_nodes");
		char node_flag = 0;
		int node_identifier = 0;
		if ((NULL != field_modify->get_field()) &&
			(computed_field_nodal_lookup_type_string ==
				Computed_field_get_type_string(field_modify->get_field())))
		{
			Cmiss_node_id lookup_node = 0;
			return_code = Computed_field_get_type_nodal_lookup(field_modify->get_field(),
				&source_field, &lookup_node);
			if (source_field)
			{
				 ACCESS(Computed_field)(source_field);
			}
			if (lookup_node)
			{
				node_identifier = get_FE_node_identifier(lookup_node);
				FE_region *fe_region = FE_node_get_FE_region(lookup_node);
				if (!FE_region_contains_FE_node(fe_region, lookup_node))
				{
					DEALLOCATE(nodeset_name);
					nodeset_name = duplicate_string("cmiss_data");
				}
				node_flag = 1;
			}
		}

		Option_table *option_table = CREATE(Option_table)();
		/* source field */
		Set_Computed_field_conditional_data set_source_field_data;
		set_source_field_data.computed_field_manager = field_modify->get_field_manager();
		set_source_field_data.conditional_function = Computed_field_has_numerical_components;
		set_source_field_data.conditional_function_user_data = (void *)NULL;
		Option_table_add_entry(option_table,"field", &source_field,
			&set_source_field_data,set_Computed_field_conditional);
		/* the node to nodal_lookup */
		Option_table_add_entry(option_table, "node", &node_identifier,
			&node_flag, set_int_and_char_flag);
		/* the nodeset the node is from */
		Option_table_add_string_entry(option_table, "nodeset", &nodeset_name,
			" NODE_GROUP_FIELD_NAME|[GROUP_NAME.]cmiss_nodes|cmiss_data[cmiss_nodes]");
		return_code = Option_table_multi_parse(option_table,state);
		DESTROY(Option_table)(&option_table);

		if (return_code && node_flag)
		{
			Cmiss_nodeset_id nodeset = Cmiss_field_module_find_nodeset_by_name(field_modify->get_field_module(), nodeset_name);
			Cmiss_node_id node = Cmiss_nodeset_find_node_by_identifier(nodeset, node_identifier);
			if (node)
			{
				return_code = field_modify->update_field_and_deaccess(
					Computed_field_create_nodal_lookup(field_modify->get_field_module(),
						source_field, node));
			}
			else
			{
				display_message(ERROR_MESSAGE,
					"define field nodal lookup.  Invalid node %d", node_identifier);
				return_code = 0;
			}
			Cmiss_node_destroy(&node);
			Cmiss_nodeset_destroy(&nodeset);
		}
		else
		{
			if ((!state->current_token)||
				(strcmp(PARSER_HELP_STRING,state->current_token)&&
					strcmp(PARSER_RECURSIVE_HELP_STRING,state->current_token)))
			{
				display_message(ERROR_MESSAGE,
					"define_Computed_field_type_time_nodal_lookup.  Failed");
			}
		}
		DEALLOCATE(nodeset_name);
		REACCESS(Computed_field)(&source_field, NULL);
	}
	else
	{
		display_message(ERROR_MESSAGE,
			"define_Computed_field_type_nodal_lookup.  Invalid argument(s)");
		return_code = 0;
	}
	return (return_code);
}
int define_Computed_field_type_quaternion_SLERP(struct Parse_state *state,
	void *field_modify_void, void *computed_field_lookup_package_void)
/*******************************************************************************
LAST MODIFIED : 25 August 2006

DESCRIPTION :
Converts <field> into type 'quaterions' (if it is not already) and allows its
contents to be modified.
==============================================================================*/
{
	int return_code;
	Computed_field_lookup_package *computed_field_lookup_package;
	Computed_field_modify_data *field_modify;

	ENTER(define_Computed_field_type_quaternion_SLERP);
	if (state&&(field_modify=(Computed_field_modify_data *)field_modify_void) &&
		 (computed_field_lookup_package=
				(Computed_field_lookup_package *)
				computed_field_lookup_package_void))
	{
		return_code = 1;
		Cmiss_field_id source_field = 0;
		char *nodeset_name = duplicate_string("cmiss_nodes");
		char node_flag = 0;
		int node_identifier = 0;
		if ((NULL != field_modify->get_field()) &&
			(computed_field_quaternion_SLERP_type_string ==
				Computed_field_get_type_string(field_modify->get_field())))
		{
			Cmiss_node_id lookup_node = 0;
			return_code = Computed_field_get_type_quaternion_SLERP(field_modify->get_field(),
				 &source_field, &lookup_node);
			if (source_field)
			{
				 ACCESS(Computed_field)(source_field);
			}
			if (lookup_node)
			{
				node_identifier = get_FE_node_identifier(lookup_node);
				FE_region *fe_region = FE_node_get_FE_region(lookup_node);
				if (!FE_region_contains_FE_node(fe_region, lookup_node))
				{
					DEALLOCATE(nodeset_name);
					nodeset_name = duplicate_string("cmiss_data");
				}
				node_flag = 1;
			}
		}

		Option_table *option_table = CREATE(Option_table)();
		Option_table_add_help(option_table,
			 "A 4 components quaternion field. The components of "
			 "the quaternion field are expected to be the w, x, y, z components"
			 "of a quaternion (4 components in total). The quaternion field  is"
			 "evaluated and interpolated using SLERP at a normalised time between two"
			 "quaternions (read in from the exnode generally). This quaternion field"
			 "can be convert to a matrix with quaternion_to_matrix field, the resulting"
			 "matrix can be used to create a smooth time dependent rotation for an object"
			 "using the quaternion_to_matrix field. This field must be define directly from"
			 "exnode file or from a matrix_to_quaternion field");
		Set_Computed_field_conditional_data set_source_field_data;
		set_source_field_data.computed_field_manager = field_modify->get_field_manager();
		set_source_field_data.conditional_function = Computed_field_has_4_components;
		set_source_field_data.conditional_function_user_data = (void *)NULL;
		Option_table_add_entry(option_table, "field", &source_field,
			&set_source_field_data, set_Computed_field_conditional);
		/* identifier of the node to lookup */
		Option_table_add_entry(option_table, "node", &node_identifier,
			&node_flag, set_int_and_char_flag);
		/* the nodeset the node is from */
		Option_table_add_string_entry(option_table, "nodeset", &nodeset_name,
			" NODE_GROUP_FIELD_NAME|[GROUP_NAME.]cmiss_nodes|cmiss_data[cmiss_nodes]");
		return_code = Option_table_multi_parse(option_table, state);
		DESTROY(Option_table)(&option_table);

		if (return_code && node_flag)
		{
			Cmiss_nodeset_id nodeset = Cmiss_field_module_find_nodeset_by_name(field_modify->get_field_module(), nodeset_name);
			Cmiss_node_id node = Cmiss_nodeset_find_node_by_identifier(nodeset, node_identifier);
			if (node)
			{
				return_code = field_modify->update_field_and_deaccess(
					Computed_field_create_quaternion_SLERP(field_modify->get_field_module(),
						source_field, node));
			}
			else
			{
				display_message(ERROR_MESSAGE,
					"define field quaternion_SLERP.  Invalid node %d", node_identifier);
				return_code = 0;
			}
			Cmiss_node_destroy(&node);
			Cmiss_nodeset_destroy(&nodeset);
		}
		else
		{
			if ((!state->current_token)||
				(strcmp(PARSER_HELP_STRING,state->current_token)&&
					strcmp(PARSER_RECURSIVE_HELP_STRING,state->current_token)))
			{
				display_message(ERROR_MESSAGE,
					"define_Computed_field_type_quaternion_SLERP.  Failed");
			}
		}
		DEALLOCATE(nodeset_name);
		REACCESS(Computed_field)(&source_field, NULL);
	}
	else
	{
		 display_message(ERROR_MESSAGE,
				"define_Computed_field_type_quaternion_SLERP.  Invalid argument(s)");
		 return_code = 0;
	}
	LEAVE;

	return (return_code);
} /* define_Computed_field_type_quaternion_SLERP */
int define_Computed_field_type_integration(Parse_state *state,
	void *field_modify_void,void *computed_field_integration_package_void)
/*******************************************************************************
LAST MODIFIED : 24 August 2006

DESCRIPTION :
Converts <field> into type COMPUTED_FIELD_INTEGRATION (if it is not already)
and allows its contents to be modified.
==============================================================================*/
{
	int return_code = 1;
	ENTER(define_Computed_field_type_integration);
	Computed_field_modify_data *field_modify = reinterpret_cast<Computed_field_modify_data *>(field_modify_void);
	USE_PARAMETER(computed_field_integration_package_void);
	if (state && field_modify)
	{
		cmzn_region_id region = field_modify->get_region();
		cmzn_mesh_id mesh = 0;
		cmzn_field_id coordinate_field = 0;
		cmzn_field_id integrand = 0;
		int magnitude_coordinates_flag = 0;
		int seed_element_identifier = 0;
		float time_update = 0;
		if ((NULL != field_modify->get_field()) &&
			Computed_field_is_type_integration(field_modify->get_field()))
		{
			cmzn_element_id seed_element;
			return_code = Computed_field_get_type_integration(field_modify->get_field(),
				&mesh, &seed_element, &integrand, &magnitude_coordinates_flag, &coordinate_field);
			if (seed_element)
			{
				seed_element_identifier = cmzn_element_get_identifier(seed_element);
				cmzn_element_destroy(&seed_element);
			}
		}
		if (coordinate_field)
		{
			ACCESS(Computed_field)(coordinate_field);
		}
		if (integrand)
		{
			ACCESS(Computed_field)(integrand);
		}
		else
		{
			/* Make a default integrand of one */
			double value = 1.0;
			// use temporary field module to supply different defaults
			cmzn_fieldmodule *temp_field_module = cmzn_region_get_fieldmodule(region);
			cmzn_fieldmodule_set_field_name(temp_field_module, "constant_1.0");
			integrand = Computed_field_create_constant(temp_field_module,
				/*number_of_components*/1, &value);
			if (NULL == integrand)
			{
				display_message(ERROR_MESSAGE,
					"define_Computed_field_type_integration.  Unable to create constant integrand");
				return_code = 0;
			}
			cmzn_fieldmodule_destroy(&temp_field_module);
		}
		char *group_name = 0;

		Option_table *option_table = CREATE(Option_table)();
		/* coordinate */
		Set_Computed_field_conditional_data set_coordinate_field_data;
		set_coordinate_field_data.computed_field_manager = field_modify->get_field_manager();
		set_coordinate_field_data.conditional_function = Computed_field_has_up_to_3_numerical_components;
		set_coordinate_field_data.conditional_function_user_data = 0;
		Option_table_add_Computed_field_conditional_entry(option_table, "coordinate",
			&coordinate_field, &set_coordinate_field_data);
		/* integrand */
		Set_Computed_field_conditional_data set_integrand_field_data;
		set_integrand_field_data.computed_field_manager = field_modify->get_field_manager();
		set_integrand_field_data.conditional_function = Computed_field_is_scalar;
		set_integrand_field_data.conditional_function_user_data = 0;
		Option_table_add_Computed_field_conditional_entry(option_table, "integrand",
			&integrand, &set_integrand_field_data);
		/* magnitude_coordinates|no_magnitude_coordinates */
		Option_table_add_switch(option_table, "magnitude_coordinates", "no_magnitude_coordinates",
			&magnitude_coordinates_flag);
		// mesh
		Option_table_add_mesh_entry(option_table, "mesh", region, &mesh);
		/* region - legacy group name */
		Option_table_add_string_entry(option_table, "region", &group_name, " GROUP_NAME(DEPRECATED)");
		/* seed_element */
		Option_table_add_int_non_negative_entry(option_table, "seed_element",
			&seed_element_identifier);
		/* update_time_integration */
		Option_table_add_entry(option_table,"update_time_integration",
			&time_update, NULL, set_float);
		return_code = Option_table_multi_parse(option_table,state);
		DESTROY(Option_table)(&option_table);

		if (return_code && !mesh)
		{
			int dimension = FE_region_get_highest_dimension(cmzn_region_get_FE_region(region));
			mesh = cmzn_fieldmodule_find_mesh_by_dimension(field_modify->get_field_module(), dimension);
			if (group_name)
			{
				cmzn_field_id group_field = cmzn_fieldmodule_find_field_by_name(field_modify->get_field_module(), group_name);
				cmzn_field_group_id group = cmzn_field_cast_group(group_field);
				cmzn_field_element_group_id element_group = cmzn_field_group_get_field_element_group(group, mesh);
				cmzn_mesh_destroy(&mesh);
				mesh = cmzn_mesh_group_base_cast(cmzn_field_element_group_get_mesh_group(element_group));
				cmzn_field_element_group_destroy(&element_group);
				cmzn_field_group_destroy(&group);
				cmzn_field_destroy(&group_field);
			}
		}
		if (return_code && !mesh)
		{
			display_message(ERROR_MESSAGE, "You must specify a mesh.");
			return_code = 0;
		}
		if (return_code && !coordinate_field)
		{
			display_message(ERROR_MESSAGE, "You must specify a coordinate field.");
			return_code = 0;
		}
		if (return_code && !integrand)
		{
			display_message(ERROR_MESSAGE, "You must specify an integrand field.");
			return_code = 0;
		}
		cmzn_element_id seed_element = 0;
		if (return_code)
		{
			seed_element = cmzn_mesh_find_element_by_identifier(mesh, seed_element_identifier);
			if (!seed_element)
			{
				display_message(ERROR_MESSAGE, "Could not find seed_element %d in mesh.", seed_element_identifier);
				return_code = 0;
			}
		}
		if (return_code)
		{
			if (time_update && (NULL != field_modify->get_field()) &&
				Computed_field_is_type_integration(field_modify->get_field()))
			{
				display_message(ERROR_MESSAGE,
					"The update_time_integration code has not been updated"
					"with the latest changes.");
				return_code=0;
			}
			else
			{
				return_code = field_modify->update_field_and_deaccess(
					Computed_field_create_integration(field_modify->get_field_module(),
						mesh, seed_element, integrand, magnitude_coordinates_flag, coordinate_field));
			}
		}
		if (group_name)
		{
			DEALLOCATE(group_name);
		}
		cmzn_element_destroy(&seed_element);
		cmzn_mesh_destroy(&mesh);
		cmzn_field_destroy(&coordinate_field);
		cmzn_field_destroy(&integrand);
	}
	else
	{
		display_message(ERROR_MESSAGE,
			"define_Computed_field_type_integration.  Invalid argument(s)");
		return_code=0;
	}
	LEAVE;

	return (return_code);
}
int define_Computed_field_type_xi_texture_coordinates(Parse_state *state,
	void *field_modify_void,void *computed_field_integration_package_void)
/*******************************************************************************
LAST MODIFIED : 24 August 2006

DESCRIPTION :
Converts <field> into type COMPUTED_FIELD_XI_TEXTURE_COORDINATES (if it is not already)
and allows its contents to be modified.
==============================================================================*/
{
	int return_code = 1;
	ENTER(define_Computed_field_type_xi_texture_coordinates);
	Computed_field_modify_data *field_modify = reinterpret_cast<Computed_field_modify_data *>(field_modify_void);
	USE_PARAMETER(computed_field_integration_package_void);
	if (state && field_modify)
	{
		cmzn_region_id region = field_modify->get_region();
		cmzn_mesh_id mesh = 0;
		int seed_element_identifier = 0;
		char *group_name = 0;

		Option_table *option_table = CREATE(Option_table)();
		// mesh
		Option_table_add_mesh_entry(option_table, "mesh", region, &mesh);
		/* region - legacy group name */
		Option_table_add_string_entry(option_table, "region", &group_name, " GROUP_NAME(OBSOLETE)");
		/* seed_element */
		Option_table_add_int_non_negative_entry(option_table, "seed_element",
			&seed_element_identifier);
		return_code = Option_table_multi_parse(option_table,state);
		DESTROY(Option_table)(&option_table);

		if (return_code && !mesh)
		{
			int dimension = FE_region_get_highest_dimension(cmzn_region_get_FE_region(region));
			mesh = cmzn_fieldmodule_find_mesh_by_dimension(field_modify->get_field_module(), dimension);
			if (group_name)
			{
				cmzn_field_id group_field = cmzn_fieldmodule_find_field_by_name(field_modify->get_field_module(), group_name);
				cmzn_field_group_id group = cmzn_field_cast_group(group_field);
				cmzn_field_element_group_id element_group = cmzn_field_group_get_field_element_group(group, mesh);
				cmzn_mesh_destroy(&mesh);
				mesh = cmzn_mesh_group_base_cast(cmzn_field_element_group_get_mesh_group(element_group));
				cmzn_field_element_group_destroy(&element_group);
				cmzn_field_group_destroy(&group);
				cmzn_field_destroy(&group_field);
			}
		}
		if (return_code && !mesh)
		{
			display_message(ERROR_MESSAGE, "Must specify mesh.");
			return_code = 0;
		}
		cmzn_element_id seed_element = 0;
		if (return_code)
		{
			seed_element = cmzn_mesh_find_element_by_identifier(mesh, seed_element_identifier);
			if (!seed_element)
			{
				display_message(ERROR_MESSAGE, "Could not find seed_element %d in mesh.", seed_element_identifier);
				return_code = 0;
			}
		}
		// use temporary field module to supply different defaults
		cmzn_field_id coordinate_field = FIRST_OBJECT_IN_MANAGER_THAT(Computed_field)(
			Computed_field_is_type_xi_coordinates, (void *)NULL,
			field_modify->get_field_manager());
		if (coordinate_field)
		{
			ACCESS(Computed_field)(coordinate_field);
		}
		else
		{
			if ((!state->current_token) ||
				(strcmp(PARSER_HELP_STRING, state->current_token)&&
					strcmp(PARSER_RECURSIVE_HELP_STRING, state->current_token)))
			{
				display_message(ERROR_MESSAGE,
					"define_Computed_field_type_xi_texture_coordinates.  xi field not found");
			}
			return_code = 0;
		}
		double value = 1.0;
		cmzn_fieldmodule *temp_field_module = cmzn_region_get_fieldmodule(region);
		cmzn_fieldmodule_set_field_name(temp_field_module, "constant_1.0");
		Computed_field *integrand = Computed_field_create_constant(temp_field_module,
			/*number_of_components*/1, &value);
		cmzn_fieldmodule_destroy(&temp_field_module);
		if (NULL == integrand)
		{
			display_message(ERROR_MESSAGE,
				"define_Computed_field_type_xi_texture_coordinates.  Unable to create constant field");
			return_code = 0;
		}
		if (return_code)
		{
			return_code = field_modify->update_field_and_deaccess(
				Computed_field_create_integration(field_modify->get_field_module(),
					mesh, seed_element, integrand, /*magnitude_coordinates*/0, coordinate_field));
		}
		if (group_name)
		{
			DEALLOCATE(group_name);
		}
		cmzn_element_destroy(&seed_element);
		cmzn_mesh_destroy(&mesh);
		cmzn_field_destroy(&coordinate_field);
		cmzn_field_destroy(&integrand);
	}
	else
	{
		display_message(ERROR_MESSAGE,
			"define_Computed_field_type_xi_texture_coordinates.  Invalid argument(s)");
		return_code=0;
	}
	LEAVE;

	return (return_code);
}
int define_Computed_field_type_format_output(struct Parse_state *state,
	void *field_modify_void,void *computed_field_arithmetic_operators_package_void)
/*******************************************************************************
LAST MODIFIED : 15 May 2008

DESCRIPTION :
Converts <field> into type COMPUTED_FIELD_FORMAT_OUTPUT (if it is not
already) and allows its contents to be modified.
==============================================================================*/
{
	int return_code;
	char *format_string;
	struct Computed_field *source_field;
	Computed_field_modify_data *field_modify;
	struct Option_table *option_table;
	struct Set_Computed_field_conditional_data set_source_field_data;

	ENTER(define_Computed_field_type_format_output);
	USE_PARAMETER(computed_field_arithmetic_operators_package_void);
	if (state&&(field_modify=(Computed_field_modify_data *)field_modify_void))
	{
		return_code=1;
		source_field = (struct Computed_field *)NULL;
		format_string = NULL;
		if ((NULL != field_modify->get_field()) &&
			(computed_field_format_output_type_string ==
				Computed_field_get_type_string(field_modify->get_field())))
		{
			return_code=Computed_field_get_type_format_output(field_modify->get_field(),
				&source_field, &format_string);
		}
		if (return_code)
		{
			/* must access objects for set functions */
			if (source_field)
			{
				ACCESS(Computed_field)(source_field);
			}

			option_table = CREATE(Option_table)();
			/* fields */
			set_source_field_data.computed_field_manager=
				field_modify->get_field_manager();
			set_source_field_data.conditional_function=
				Computed_field_has_numerical_components;
			set_source_field_data.conditional_function_user_data=(void *)NULL;
			Option_table_add_Computed_field_conditional_entry(option_table,"field",
				&source_field, &set_source_field_data);
			Option_table_add_string_entry(option_table, "format_string", &format_string,
				"C style formatting string");
			return_code=Option_table_multi_parse(option_table,state);
			/* no errors,not asking for help */
			if (return_code)
			{
				return_code = field_modify->update_field_and_deaccess(
					Computed_field_create_format_output(field_modify->get_field_module(),
						source_field, format_string));
			}
			if (!return_code)
			{
				if ((!state->current_token)||
					(strcmp(PARSER_HELP_STRING,state->current_token)&&
						strcmp(PARSER_RECURSIVE_HELP_STRING,state->current_token)))
				{
					/* error */
					display_message(ERROR_MESSAGE,
						"define_Computed_field_type_format_output.  Failed");
				}
			}
			if (source_field)
			{
				DEACCESS(Computed_field)(&source_field);
			}
			if (format_string)
				DEALLOCATE(format_string);
			DESTROY(Option_table)(&option_table);
		}
		else
		{
			display_message(ERROR_MESSAGE,
				"define_Computed_field_type_format_output.  Not enough memory");
			return_code = 0;
		}
	}
	else
	{
		display_message(ERROR_MESSAGE,
			"define_Computed_field_type_format_output.  Invalid argument(s)");
		return_code = 0;
	}
	LEAVE;

	return (return_code);
} /* define_Computed_field_type_format_output */