static void ui_node_draw_node(uiLayout *layout, bContext *C, bNodeTree *ntree, bNode *node, int depth)
{
	bNodeSocket *input;
	uiLayout *col, *split;
	PointerRNA nodeptr;

	RNA_pointer_create(&ntree->id, &RNA_Node, node, &nodeptr);

	if (node->typeinfo->draw_buttons) {
		if (node->type != NODE_GROUP) {
			split = uiLayoutSplit(layout, 0.35f, false);
			col = uiLayoutColumn(split, false);
			col = uiLayoutColumn(split, false);

			node->typeinfo->draw_buttons(col, C, &nodeptr);
		}
	}

	for (input = node->inputs.first; input; input = input->next)
		ui_node_draw_input(layout, C, ntree, node, input, depth + 1);
}
Example #2
0
void operator_wrapper(wmOperatorType *ot, void *userdata)
{
	/* take care not to overwrite anything set in
	 * WM_operatortype_append_ptr before opfunc() is called */
	StructRNA *srna = ot->srna;
	*ot = *((wmOperatorType *)userdata);
	ot->srna = srna; /* restore */

	operator_properties_init(ot);

	{	/* XXX - not nice, set the first enum as searchable, should have a way for python to set */
		PointerRNA ptr;
		PropertyRNA *prop;

		RNA_pointer_create(NULL, ot->srna, NULL, &ptr);
		prop = RNA_struct_find_property(&ptr, "type");
		if (prop) {
			ot->prop = prop;
		}
	}
}
Example #3
0
/* wrapper for iterator callback */
static void RKS_ITER_rna_internal(KeyingSetInfo *ksi, bContext *C, KeyingSet *ks)
{
	extern FunctionRNA rna_KeyingSetInfo_iterator_func;

	PointerRNA ptr;
	ParameterList list;
	FunctionRNA *func;

	RNA_pointer_create(NULL, ksi->ext.srna, ksi, &ptr);
	func = &rna_KeyingSetInfo_iterator_func; /* RNA_struct_find_function(&ptr, "poll"); */

	RNA_parameter_list_create(&list, &ptr, func);
		/* hook up arguments */
		RNA_parameter_set_lookup(&list, "ksi", &ksi);
		RNA_parameter_set_lookup(&list, "context", &C);
		RNA_parameter_set_lookup(&list, "ks", &ks);
		
		/* execute the function */
		ksi->ext.call(C, &ptr, func, &list);
	RNA_parameter_list_free(&list);
}
Example #4
0
PyObject *PYOP_wrap_macro_define(PyObject *UNUSED(self), PyObject *args)
{
	wmOperatorType *ot;
	wmOperatorTypeMacro *otmacro;
	PyObject *macro;
	PointerRNA ptr_otmacro;
	StructRNA *srna;

	char *opname;
	const char *macroname;

	if (!PyArg_ParseTuple(args, "Os:_bpy.ops.macro_define", &macro, &opname))
		return NULL;

	if (WM_operatortype_find(opname, TRUE) == NULL) {
		PyErr_Format(PyExc_ValueError,
		             "Macro Define: '%s' is not a valid operator id",
		             opname);
		return NULL;
	}

	/* identifiers */
	srna = srna_from_self(macro, "Macro Define:");
	macroname = RNA_struct_identifier(srna);

	ot = WM_operatortype_find(macroname, TRUE);

	if (!ot) {
		PyErr_Format(PyExc_ValueError,
		             "Macro Define: '%s' is not a valid macro or hasn't been registered yet",
		             macroname);
		return NULL;
	}

	otmacro = WM_operatortype_macro_define(ot, opname);

	RNA_pointer_create(NULL, &RNA_OperatorMacro, otmacro, &ptr_otmacro);

	return pyrna_struct_CreatePyObject(&ptr_otmacro);
}
Example #5
0
static int panel_poll(const bContext *C, PanelType *pt)
{
    PointerRNA ptr;
    ParameterList list;
    FunctionRNA *func;
    void *ret;
    int visible;

    RNA_pointer_create(NULL, pt->ext.srna, NULL, &ptr); /* dummy */
    func= RNA_struct_find_function(&ptr, "poll");

    RNA_parameter_list_create(&list, &ptr, func);
    RNA_parameter_set_lookup(&list, "context", &C);
    pt->ext.call((bContext *)C, &ptr, func, &list);

    RNA_parameter_get_lookup(&list, "visible", &ret);
    visible= *(int*)ret;

    RNA_parameter_list_free(&list);

    return visible;
}
Example #6
0
StructRNA *rna_PropertyGroup_register(Main *UNUSED(bmain), ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc UNUSED(call), StructFreeFunc UNUSED(free))
{
	PointerRNA dummyptr;

	/* create dummy pointer */
	RNA_pointer_create(NULL, &RNA_PropertyGroup, NULL, &dummyptr);

	/* validate the python class */
	if(validate(&dummyptr, data, NULL) != 0)
		return NULL;

	/* note: it looks like there is no length limit on the srna id since its
	 * just a char pointer, but take care here, also be careful that python
	 * owns the string pointer which it could potentually free while blender
	 * is running. */
	if(BLI_strnlen(identifier, MAX_IDPROP_NAME) == MAX_IDPROP_NAME) {
		BKE_reportf(reports, RPT_ERROR, "registering id property class: '%s' is too long, maximum length is " STRINGIFY(MAX_IDPROP_NAME), identifier);
		return NULL;
	}

	return RNA_def_struct(&BLENDER_RNA, identifier, "PropertyGroup");  // XXX
}
Example #7
0
/* show popup to determine settings */
static int pose_calculate_paths_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{	
	Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
	
	if (ELEM(NULL, ob, ob->pose))
		return OPERATOR_CANCELLED;
	
	/* set default settings from existing/stored settings */
	{
		bAnimVizSettings *avs = &ob->pose->avs;
		PointerRNA avs_ptr;
		
		RNA_int_set(op->ptr, "start_frame", avs->path_sf);
		RNA_int_set(op->ptr, "end_frame", avs->path_ef);
		
		RNA_pointer_create(NULL, &RNA_AnimVizMotionPaths, avs, &avs_ptr);
		RNA_enum_set(op->ptr, "bake_location", RNA_enum_get(&avs_ptr, "bake_location"));
	}
	
	/* show popup dialog to allow editing of range... */
	// FIXME: hardcoded dimensions here are just arbitrary
	return WM_operator_props_dialog_popup(C, op, 10 * UI_UNIT_X, 10 * UI_UNIT_Y);
}
Example #8
0
static void buttons_texture_users_find_nodetree(ListBase *users, ID *id,
        bNodeTree *ntree, const char *category)
{
    bNode *node;

    if (ntree) {
        for (node = ntree->nodes.first; node; node = node->next) {
            if (node->typeinfo->nclass == NODE_CLASS_TEXTURE) {
                PointerRNA ptr;
                /* PropertyRNA *prop; */ /* UNUSED */

                RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr);
                /* prop = RNA_struct_find_property(&ptr, "texture"); */ /* UNUSED */

                buttons_texture_user_node_add(users, id, ntree, node,
                                              category, RNA_struct_ui_icon(ptr.type), node->name);
            }
            else if (node->type == NODE_GROUP && node->id) {
                buttons_texture_users_find_nodetree(users, id, (bNodeTree *)node->id, category);
            }
        }
    }
}
Example #9
0
/* Add new data source for relative Keying Sets */
void ANIM_relative_keyingset_add_source(ListBase *dsources, ID *id, StructRNA *srna, void *data)
{
	tRKS_DSource *ds;
	
	/* sanity checks 
	 *	- we must have somewhere to output the data
	 *	- we must have both srna+data (and with id too optionally), or id by itself only
	 */
	if (dsources == NULL)
		return;
	if (ELEM(NULL, srna, data) && (id == NULL))
		return;
	
	/* allocate new elem, and add to the list */
	ds = MEM_callocN(sizeof(tRKS_DSource), "tRKS_DSource");
	BLI_addtail(dsources, ds);
	
	/* depending on what data we have, create using ID or full pointer call */
	if (srna && data)
		RNA_pointer_create(id, srna, data, &ds->ptr);
	else
		RNA_id_pointer_create(id, &ds->ptr);
}
Example #10
0
/* active node */
static void active_node_panel(const bContext *C, Panel *pa)
{
	SpaceNode *snode= CTX_wm_space_node(C);
	bNodeTree *ntree= (snode) ? snode->edittree : NULL;
	bNode *node = (ntree) ? nodeGetActive(ntree) : NULL; // xxx... for editing group nodes
	uiLayout *layout= pa->layout;
	uiBlock *block;
	PointerRNA ptr;
	
	/* verify pointers, and create RNA pointer for the node */
	if ELEM(NULL, ntree, node)
		return;
	//if (node->id) /* for group nodes */
	//	RNA_pointer_create(node->id, &RNA_Node, node, &ptr);
	//else
		RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr); 
	
	/* set update callback */
	// xxx is this really needed
	block= uiLayoutGetBlock(layout);
	uiBlockSetHandleFunc(block, do_node_region_buttons, NULL);
	
	/* draw this node's name, etc. */
	uiItemR(layout, &ptr, "label", 0, NULL, ICON_NODE);
	uiItemS(layout);
	uiItemR(layout, &ptr, "name", 0, NULL, ICON_NODE);
	uiItemS(layout);
	
	uiItemO(layout, NULL, 0, "NODE_OT_hide_socket_toggle");
	uiItemS(layout);

	/* draw this node's settings */
	if (node->typeinfo && node->typeinfo->uifuncbut)
		node->typeinfo->uifuncbut(layout, (bContext *)C, &ptr);
	else if (node->typeinfo && node->typeinfo->uifunc)
		node->typeinfo->uifunc(layout, (bContext *)C, &ptr);
}
Example #11
0
static PyObject *pyop_getinstance(PyObject *UNUSED(self), PyObject *value)
{
	wmOperatorType *ot;
	wmOperator *op;
	PointerRNA ptr;
	const char *opname = _PyUnicode_AsString(value);
	BPy_StructRNA *pyrna = NULL;

	if (opname == NULL) {
		PyErr_SetString(PyExc_TypeError, "_bpy.ops.get_instance() expects a string argument");
		return NULL;
	}
	ot = WM_operatortype_find(opname, true);
	if (ot == NULL) {
		PyErr_Format(PyExc_KeyError, "_bpy.ops.get_instance(\"%s\") not found", opname);
		return NULL;
	}

#ifdef PYRNA_FREE_SUPPORT
	op = MEM_callocN(sizeof(wmOperator), __func__);
#else
	op = PyMem_MALLOC(sizeof(wmOperator));
	memset(op, 0, sizeof(wmOperator));
#endif
	BLI_strncpy(op->idname, op->idname, sizeof(op->idname)); /* in case its needed */
	op->type = ot;

	RNA_pointer_create(NULL, &RNA_Operator, op, &ptr);

	pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
#ifdef PYRNA_FREE_SUPPORT
	pyrna->freeptr = true;
#endif
	op->ptr = &pyrna->ptr;

	return (PyObject *)pyrna;
}
Example #12
0
static int actuator_add_exec(bContext *C, wmOperator *op)
{
    Object *ob;
    bActuator *act;
    PointerRNA act_ptr;
    PropertyRNA *prop;
    const char *act_name;
    char name[MAX_NAME];
    int type = RNA_enum_get(op->ptr, "type");

    ob = edit_object_property_get(C, op);
    if (!ob)
        return OPERATOR_CANCELLED;

    act = new_actuator(type);
    BLI_addtail(&(ob->actuators), act);

    /* set the actuator name based on rna type enum */
    RNA_pointer_create((ID *)ob, &RNA_Actuator, act, &act_ptr);
    prop = RNA_struct_find_property(&act_ptr, "type");

    RNA_string_get(op->ptr, "name", name);
    if (*name) {
        BLI_strncpy(act->name, name, sizeof(act->name));
    }
    else {
        RNA_property_enum_name(C, &act_ptr, prop, RNA_property_enum_get(&act_ptr, prop), &act_name);
        BLI_strncpy(act->name, act_name, sizeof(act->name));
    }

    make_unique_prop_names(C, act->name);
    ob->scaflag |= OB_SHOWACT;

    WM_event_add_notifier(C, NC_LOGIC, NULL);

    return OPERATOR_FINISHED;
}
Example #13
0
static int sensor_add_exec(bContext *C, wmOperator *op)
{
	Object *ob;
	bSensor *sens;
	PointerRNA sens_ptr;
	PropertyRNA *prop;
	const char *sens_name;
	char name[MAX_NAME];
	int type = RNA_enum_get(op->ptr, "type");

	ob = edit_object_property_get(C, op);
	if (!ob)
		return OPERATOR_CANCELLED;

	sens = new_sensor(type);
	BLI_addtail(&(ob->sensors), sens);
	
	/* set the sensor name based on rna type enum */
	RNA_pointer_create((ID *)ob, &RNA_Sensor, sens, &sens_ptr);
	prop = RNA_struct_find_property(&sens_ptr, "type");

	RNA_string_get(op->ptr, "name", name);
	if (*name) {
		BLI_strncpy(sens->name, name, sizeof(sens->name));
	}
	else {
		RNA_property_enum_name(C, &sens_ptr, prop, RNA_property_enum_get(&sens_ptr, prop), &sens_name);
		BLI_strncpy(sens->name, sens_name, sizeof(sens->name));
	}

	BLI_uniquename(&ob->sensors, sens, DATA_("Sensor"), '.', offsetof(bSensor, name), sizeof(sens->name));
	ob->scaflag |= OB_SHOWSENS;

	WM_event_add_notifier(C, NC_LOGIC, NULL);
	
	return OPERATOR_FINISHED;
}
Example #14
0
void wm_stereo3d_set_draw(bContext *UNUSED(C), wmOperator *op)
{
	Stereo3dData *s3dd = op->customdata;
	PointerRNA stereo3d_format_ptr;
	uiLayout *layout = op->layout;
	uiLayout *col;

	RNA_pointer_create(NULL, &RNA_Stereo3dDisplay, &s3dd->stereo3d_format, &stereo3d_format_ptr);

	col = uiLayoutColumn(layout, false);
	uiItemR(col, &stereo3d_format_ptr, "display_mode", 0, NULL, ICON_NONE);

	switch (s3dd->stereo3d_format.display_mode) {
		case S3D_DISPLAY_ANAGLYPH:
		{
			uiItemR(col, &stereo3d_format_ptr, "anaglyph_type", 0, NULL, ICON_NONE);
			break;
		}
		case S3D_DISPLAY_INTERLACE:
		{
			uiItemR(col, &stereo3d_format_ptr, "interlace_type", 0, NULL, ICON_NONE);
			uiItemR(col, &stereo3d_format_ptr, "use_interlace_swap", 0, NULL, ICON_NONE);
			break;
		}
		case S3D_DISPLAY_SIDEBYSIDE:
		{
			uiItemR(col, &stereo3d_format_ptr, "use_sidebyside_crosseyed", 0, NULL, ICON_NONE);
			/* fall-through */
		}
		case S3D_DISPLAY_PAGEFLIP:
		case S3D_DISPLAY_TOPBOTTOM:
		default:
		{
			break;
		}
	}
}
Example #15
0
static bool menu_poll(const bContext *C, MenuType *pt)
{
	extern FunctionRNA rna_Menu_poll_func;

	PointerRNA ptr;
	ParameterList list;
	FunctionRNA *func;
	void *ret;
	bool visible;

	RNA_pointer_create(NULL, pt->ext.srna, NULL, &ptr); /* dummy */
	func = &rna_Menu_poll_func; /* RNA_struct_find_function(&ptr, "poll"); */

	RNA_parameter_list_create(&list, &ptr, func);
	RNA_parameter_set_lookup(&list, "context", &C);
	pt->ext.call((bContext *)C, &ptr, func, &list);

	RNA_parameter_get_lookup(&list, "visible", &ret);
	visible = *(bool *)ret;

	RNA_parameter_list_free(&list);

	return visible;
}
Example #16
0
static void image_panel_curves(const bContext *C, Panel *pa)
{
	bScreen *sc = CTX_wm_screen(C);
	SpaceImage *sima = CTX_wm_space_image(C);
	ImBuf *ibuf;
	PointerRNA simaptr;
	int levels;
	void *lock;
	
	ibuf = ED_space_image_acquire_buffer(sima, &lock);
	
	if (ibuf) {
		if (sima->cumap == NULL)
			sima->cumap = curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f);

		/* curvemap black/white levels only works for RGBA */
		levels = (ibuf->channels == 4);

		RNA_pointer_create(&sc->id, &RNA_SpaceImageEditor, sima, &simaptr);
		uiTemplateCurveMapping(pa->layout, &simaptr, "curve", 'c', levels, 0);
	}

	ED_space_image_release_buffer(sima, lock);
}
Example #17
0
/* draw settings for noise modifier */
static void draw_modifier__noise(uiLayout *layout, ID *id, FModifier *fcm, short UNUSED(width))
{
	uiLayout *split, *col;
	PointerRNA ptr;
	
	/* init the RNA-pointer */
	RNA_pointer_create(id, &RNA_FModifierNoise, fcm, &ptr);
	
	/* blending mode */
	uiItemR(layout, &ptr, "blend_type", 0, NULL, ICON_NONE);
	
	/* split into 2 columns */
	split = uiLayoutSplit(layout, 0.5f, FALSE);
	
	/* col 1 */
	col = uiLayoutColumn(split, FALSE);
	uiItemR(col, &ptr, "scale", 0, NULL, ICON_NONE);
	uiItemR(col, &ptr, "strength", 0, NULL, ICON_NONE);
	
	/* col 2 */
	col = uiLayoutColumn(split, FALSE);
	uiItemR(col, &ptr, "phase", 0, NULL, ICON_NONE);
	uiItemR(col, &ptr, "depth", 0, NULL, ICON_NONE);
}
Example #18
0
/* draw settings for generator modifier */
static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, short width)
{
	FMod_Generator *data = (FMod_Generator *)fcm->data;
	uiLayout /* *col, */ /* UNUSED */ *row;
	uiBlock *block;
	uiBut *but;
	PointerRNA ptr;
	short bwidth = width - 1.5 * UI_UNIT_X; /* max button width */
	
	/* init the RNA-pointer */
	RNA_pointer_create(id, &RNA_FModifierFunctionGenerator, fcm, &ptr);
	
	/* basic settings (backdrop + mode selector + some padding) */
	/* col = uiLayoutColumn(layout, TRUE); */ /* UNUSED */
	block = uiLayoutGetBlock(layout);
	uiBlockBeginAlign(block);
	but = uiDefButR(block, MENU, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "mode", -1, 0, 0, -1, -1, NULL);
	uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL);
	
	uiDefButR(block, TOG, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "use_additive", -1, 0, 0, -1, -1, NULL);
	uiBlockEndAlign(block);
	
	/* now add settings for individual modes */
	switch (data->mode) {
		case FCM_GENERATOR_POLYNOMIAL: /* polynomial expression */
		{
			float *cp = NULL;
			char xval[32];
			unsigned int i;
			int maxXWidth;
			
			/* draw polynomial order selector */
			row = uiLayoutRow(layout, FALSE);
			block = uiLayoutGetBlock(row);
			but = uiDefButI(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 0.5f * UI_UNIT_X, 0, bwidth, UI_UNIT_Y,
			                &data->poly_order, 1, 100, 0, 0,
			                TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)"));
			uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL);
			
			
			/* calculate maximum width of label for "x^n" labels */
			if (data->arraysize > 2) {
				BLI_snprintf(xval, sizeof(xval), "x^%u", data->arraysize);
				maxXWidth = UI_GetStringWidth(xval) + 0.5 * UI_UNIT_X; /* XXX: UI_GetStringWidth is not accurate */
			}
			else {
				/* basic size (just "x") */
				maxXWidth = UI_GetStringWidth("x") + 0.5 * UI_UNIT_X;
			}
			
			/* draw controls for each coefficient and a + sign at end of row */
			row = uiLayoutRow(layout, TRUE);
			block = uiLayoutGetBlock(row);
			
			cp = data->coefficients;
			for (i = 0; (i < data->arraysize) && (cp); i++, cp++) {
				/* To align with first line... */
				if (i)
					uiDefBut(block, LABEL, 1, "   ", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
				else
					uiDefBut(block, LABEL, 1, "y =", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
				
				/* coefficient */
				uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, bwidth / 2, UI_UNIT_Y, cp, -UI_FLT_MAX, UI_FLT_MAX,
				          10, 3, TIP_("Coefficient for polynomial"));
				
				/* 'x' param (and '+' if necessary) */
				if (i == 0)
					BLI_strncpy(xval, "", sizeof(xval));
				else if (i == 1)
					BLI_strncpy(xval, "x", sizeof(xval));
				else
					BLI_snprintf(xval, sizeof(xval), "x^%u", i);
				uiDefBut(block, LABEL, 1, xval, 0, 0, maxXWidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, TIP_("Power of x"));
				
				if ( (i != (data->arraysize - 1)) || ((i == 0) && data->arraysize == 2) ) {
					uiDefBut(block, LABEL, 1, "+", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
					
					/* next coefficient on a new row */
					row = uiLayoutRow(layout, TRUE);
					block = uiLayoutGetBlock(row);
				}
				else {
					/* For alignment in UI! */
					uiDefBut(block, LABEL, 1, " ", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
				}
			}
			break;
		}
		
		case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* Factorized polynomial expression */
		{
			float *cp = NULL;
			unsigned int i;
			
			/* draw polynomial order selector */
			row = uiLayoutRow(layout, FALSE);
			block = uiLayoutGetBlock(row);
			but = uiDefButI(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 0, 0, width - 1.5 * UI_UNIT_X, UI_UNIT_Y,
			                &data->poly_order, 1, 100, 0, 0,
			                TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)"));
			uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL);
			
			
			/* draw controls for each pair of coefficients */
			row = uiLayoutRow(layout, TRUE);
			block = uiLayoutGetBlock(row);
			
			cp = data->coefficients;
			for (i = 0; (i < data->poly_order) && (cp); i++, cp += 2) {
				/* To align with first line */
				if (i)
					uiDefBut(block, LABEL, 1, "   ", 0, 0, 2.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
				else
					uiDefBut(block, LABEL, 1, "y =", 0, 0, 2.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
				/* opening bracket */
				uiDefBut(block, LABEL, 1, "(", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
				
				/* coefficients */
				uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, cp, -UI_FLT_MAX, UI_FLT_MAX,
				          10, 3, TIP_("Coefficient of x"));
				
				uiDefBut(block, LABEL, 1, "x +", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
				
				uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, cp + 1, -UI_FLT_MAX, UI_FLT_MAX,
				          10, 3, TIP_("Second coefficient"));
				
				/* closing bracket and multiplication sign */
				if ( (i != (data->poly_order - 1)) || ((i == 0) && data->poly_order == 2) ) {
					uiDefBut(block, LABEL, 1, ") \xc3\x97", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
					
					/* set up new row for the next pair of coefficients */
					row = uiLayoutRow(layout, TRUE);
					block = uiLayoutGetBlock(row);
				}
				else 
					uiDefBut(block, LABEL, 1, ")  ", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
			}
			break;
		}
	}
}
void BL_ConvertActuators(const char* maggiename,
                         struct Object* blenderobject,
                         KX_GameObject* gameobj,
                         SCA_LogicManager* logicmgr,
                         KX_Scene* scene,
                         KX_KetsjiEngine* ketsjiEngine,
                         int activeLayerBitInfo,
                         bool isInActiveLayer,
                         KX_BlenderSceneConverter* converter
                         )
{
	
	int uniqueint = 0;
	int actcount = 0;
	int executePriority = 0;
	bActuator* bact = (bActuator*) blenderobject->actuators.first;
	while (bact)
	{
		actcount++;
		bact = bact->next;
	}
	gameobj->ReserveActuator(actcount);
	bact = (bActuator*) blenderobject->actuators.first;
	while (bact)
	{
		STR_String uniquename = bact->name;
		STR_String& objectname = gameobj->GetName();
		
		SCA_IActuator* baseact = NULL;
		switch (bact->type)
		{
		case ACT_OBJECT:
			{
				bObjectActuator* obact = (bObjectActuator*) bact->data;
				KX_GameObject* obref = NULL;
				MT_Vector3 forcevec(KX_flt_trunc(obact->forceloc[0]),
				                    KX_flt_trunc(obact->forceloc[1]),
				                    KX_flt_trunc(obact->forceloc[2]));
				MT_Vector3 torquevec(obact->forcerot[0],
				                     obact->forcerot[1],
				                     obact->forcerot[2]);
				MT_Vector3 dlocvec(KX_flt_trunc(obact->dloc[0]),
				                   KX_flt_trunc(obact->dloc[1]),
				                   KX_flt_trunc(obact->dloc[2]));
				MT_Vector3 drotvec(KX_flt_trunc(obact->drot[0]),
				                   obact->drot[1],obact->drot[2]);
				MT_Vector3 linvelvec(KX_flt_trunc(obact->linearvelocity[0]),
				                     KX_flt_trunc(obact->linearvelocity[1]),
				                     KX_flt_trunc(obact->linearvelocity[2]));
				MT_Vector3 angvelvec(KX_flt_trunc(obact->angularvelocity[0]),
				                     KX_flt_trunc(obact->angularvelocity[1]),
				                     KX_flt_trunc(obact->angularvelocity[2]));
				short damping = obact->damping;

				/* Blender uses a bit vector internally for the local-flags. In */
				/* KX, we have four bools. The compiler should be smart enough  */
				/* to do the right thing. We need to explicitly convert here!   */
				
				KX_LocalFlags bitLocalFlag;
				
				bitLocalFlag.Force = bool((obact->flag & ACT_FORCE_LOCAL)!=0);
				bitLocalFlag.Torque = bool((obact->flag & ACT_TORQUE_LOCAL) !=0);//rlocal;
				bitLocalFlag.DLoc = bool((obact->flag & ACT_DLOC_LOCAL)!=0);
				bitLocalFlag.DRot = bool((obact->flag & ACT_DROT_LOCAL)!=0);
				bitLocalFlag.LinearVelocity = bool((obact->flag & ACT_LIN_VEL_LOCAL)!=0);
				bitLocalFlag.AngularVelocity = bool((obact->flag & ACT_ANG_VEL_LOCAL)!=0);
				bitLocalFlag.ServoControl = bool(obact->type == ACT_OBJECT_SERVO);
				bitLocalFlag.CharacterMotion = bool(obact->type == ACT_OBJECT_CHARACTER);
				bitLocalFlag.CharacterJump = bool((obact->flag & ACT_CHAR_JUMP)!=0);
				bitLocalFlag.AddOrSetLinV = bool((obact->flag & ACT_ADD_LIN_VEL)!=0);
				bitLocalFlag.AddOrSetCharLoc = bool((obact->flag & ACT_ADD_CHAR_LOC)!=0);
				if (obact->reference && bitLocalFlag.ServoControl)
				{
					obref = converter->FindGameObject(obact->reference);
				}
				
				KX_ObjectActuator* tmpbaseact = new KX_ObjectActuator(
				            gameobj,
				            obref,
				            forcevec.getValue(),
				            torquevec.getValue(),
				            dlocvec.getValue(),
				            drotvec.getValue(),
				            linvelvec.getValue(),
				            angvelvec.getValue(),
				            damping,
				            bitLocalFlag);
				baseact = tmpbaseact;
				break;
			}
		case ACT_ACTION:
			{
				bActionActuator* actact = (bActionActuator*) bact->data;
				STR_String propname = actact->name;
				STR_String propframe = actact->frameProp;

				short ipo_flags = 0;

				// Convert flags
				if (actact->flag & ACT_IPOFORCE) ipo_flags |= BL_Action::ACT_IPOFLAG_FORCE;
				if (actact->flag & ACT_IPOLOCAL) ipo_flags |= BL_Action::ACT_IPOFLAG_LOCAL;
				if (actact->flag & ACT_IPOADD) ipo_flags |= BL_Action::ACT_IPOFLAG_ADD;
				if (actact->flag & ACT_IPOCHILD) ipo_flags |= BL_Action::ACT_IPOFLAG_CHILD;
					
				BL_ActionActuator* tmpbaseact = new BL_ActionActuator(
				            gameobj,
				            propname,
				            propframe,
				            actact->sta,
				            actact->end,
				            actact->act,
				            actact->type, // + 1, because Blender starts to count at zero,
				            actact->blend_mode,
				            actact->blendin,
				            actact->priority,
				            actact->layer,
				            actact->layer_weight,
				            ipo_flags,
				            actact->end_reset,
				            actact->stridelength
				            // Ketsji at 1, because zero is reserved for "NoDef"
				            );
				baseact= tmpbaseact;
				break;
			}
		case ACT_SHAPEACTION:
			{
				if (blenderobject->type==OB_MESH) {
					bActionActuator* actact = (bActionActuator*) bact->data;
					STR_String propname = actact->name;
					STR_String propframe = actact->frameProp;
					
					BL_ShapeActionActuator* tmpbaseact = new BL_ShapeActionActuator(
					            gameobj,
					            propname,
					            propframe,
					            actact->sta,
					            actact->end,
					            actact->act,
					            actact->type, // + 1, because Blender starts to count at zero,
					            actact->blendin,
					            actact->priority,
					            actact->stridelength);
					// Ketsji at 1, because zero is reserved for "NoDef"
					baseact= tmpbaseact;
					break;
				}
				else
					printf ("Discarded shape action actuator from non-mesh object [%s]\n", blenderobject->id.name+2);
			}
		case ACT_LAMP:
			{
				break;
			}
		case ACT_CAMERA:
			{
				bCameraActuator *camact = (bCameraActuator *) bact->data;
				if (camact->ob) {
					KX_GameObject *tmpgob = converter->FindGameObject(camact->ob);
					
					/* visifac, fac and axis are not copied from the struct...   */ 
					/* that's some internal state...                             */
					KX_CameraActuator *tmpcamact = new KX_CameraActuator(
					            gameobj,
					            tmpgob,
					            camact->height,
					            camact->min,
					            camact->max,
					            camact->axis,
					            camact->damping);
					baseact = tmpcamact;
				}
				break;
			}
		case ACT_MESSAGE:
			{
				bMessageActuator *msgAct = (bMessageActuator *) bact->data;
				
				/* Get the name of the properties that objects must own that
				 * we're sending to, if present
				 */
				STR_String toPropName = msgAct->toPropName;
				
				/* Get the Message Subject to send.
				 */
				STR_String subject = msgAct->subject;
				
				/* Get the bodyType
				 */
				int bodyType = msgAct->bodyType;

				/* Get the body (text message or property name whose value
				 * we'll be sending, might be empty
				 */
				const STR_String body = msgAct->body;
				
				KX_NetworkMessageActuator *tmpmsgact = new KX_NetworkMessageActuator(
				            gameobj,					// actuator controlling object
				            scene->GetNetworkScene(),	// needed for replication
				            toPropName,
				            subject,
				            bodyType,
				            body);
				baseact = tmpmsgact;
				break;
			}
		case ACT_MATERIAL:
			{
				break;
			}
		case ACT_SOUND:
			{
				bSoundActuator* soundact = (bSoundActuator*) bact->data;
				/* get type, and possibly a start and end frame */
				KX_SoundActuator::KX_SOUNDACT_TYPE
					soundActuatorType = KX_SoundActuator::KX_SOUNDACT_NODEF;
				
				switch (soundact->type) {
				case ACT_SND_PLAY_STOP_SOUND:
					soundActuatorType = KX_SoundActuator::KX_SOUNDACT_PLAYSTOP;
					break;
				case ACT_SND_PLAY_END_SOUND:
					soundActuatorType = KX_SoundActuator::KX_SOUNDACT_PLAYEND;
					break;
				case ACT_SND_LOOP_STOP_SOUND:
					soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPSTOP;
					break;
				case ACT_SND_LOOP_END_SOUND:
					soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPEND;
					break;
				case ACT_SND_LOOP_BIDIRECTIONAL_SOUND:
					soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPBIDIRECTIONAL;
					break;
				case ACT_SND_LOOP_BIDIRECTIONAL_STOP_SOUND:
					soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP;
					break;
					
				default:
					/* This is an error!!! */
					soundActuatorType = KX_SoundActuator::KX_SOUNDACT_NODEF;
				}
				
				if (soundActuatorType != KX_SoundActuator::KX_SOUNDACT_NODEF) 
				{
					bSound* sound = soundact->sound;
					bool is3d = soundact->flag & ACT_SND_3D_SOUND ? true : false;
					AUD_Sound* snd_sound = NULL;
					KX_3DSoundSettings settings;
					settings.cone_inner_angle = RAD2DEGF(soundact->sound3D.cone_inner_angle);
					settings.cone_outer_angle = RAD2DEGF(soundact->sound3D.cone_outer_angle);
					settings.cone_outer_gain = soundact->sound3D.cone_outer_gain;
					settings.max_distance = soundact->sound3D.max_distance;
					settings.max_gain = soundact->sound3D.max_gain;
					settings.min_gain = soundact->sound3D.min_gain;
					settings.reference_distance = soundact->sound3D.reference_distance;
					settings.rolloff_factor = soundact->sound3D.rolloff_factor;

					if (!sound)
					{
						std::cout <<	"WARNING: Sound actuator \"" << bact->name <<
										"\" from object \"" <<  blenderobject->id.name+2 <<
										"\" has no sound datablock." << std::endl;
					}
					else
					{
						snd_sound = sound->playback_handle;

						// if sound shall be 3D but isn't mono, we have to make it mono!
						if (is3d)
						{
							snd_sound = AUD_Sound_rechannel(snd_sound, AUD_CHANNELS_MONO);
						}
					}
					KX_SoundActuator* tmpsoundact =
						new KX_SoundActuator(gameobj,
						snd_sound,
						soundact->volume,
						(float)(expf((soundact->pitch / 12.0f) * (float)M_LN2)),
						is3d,
						settings,
						soundActuatorType);

					// if we made it mono, we have to free it
					if(sound && snd_sound && snd_sound != sound->playback_handle)
						AUD_Sound_free(snd_sound);

					tmpsoundact->SetName(bact->name);
					baseact = tmpsoundact;
				}
				break;
			}
		case ACT_PROPERTY:
			{
				bPropertyActuator* propact = (bPropertyActuator*) bact->data;
				SCA_IObject* destinationObj = NULL;
				
				/*
				 * here the destinationobject is searched. problem with multiple scenes: other scenes
				 * have not been converted yet, so the destobj will not be found, so the prop will
				 * not be copied.
				 * possible solutions:
				 * - convert everything when possible and not realtime only when needed.
				 * - let the object-with-property report itself to the act when converted
				 */
				if (propact->ob)
					destinationObj = converter->FindGameObject(propact->ob);
				
				SCA_PropertyActuator* tmppropact = new SCA_PropertyActuator(
				            gameobj,
				            destinationObj,
				            propact->name,
				            propact->value,
				            propact->type + 1); // + 1 because Ketsji Logic starts
				// with 0 for KX_ACT_PROP_NODEF
				baseact = tmppropact;
				break;
			}
		case ACT_EDIT_OBJECT:
			{
				bEditObjectActuator *editobact 
					= (bEditObjectActuator *) bact->data;
				/* There are four different kinds of 'edit object' thingies  */
				/* The alternative to this lengthy conversion is packing     */
				/* several actuators in one, which is not very nice design.. */
				switch (editobact->type) {
				case ACT_EDOB_ADD_OBJECT: 
					{
						
						// does the 'original' for replication exists, and 
						// is it in a non-active layer ?
						SCA_IObject* originalval = NULL;
						if (editobact->ob)
						{
							if (editobact->ob->lay & activeLayerBitInfo)
							{
								fprintf(stderr, "Warning, object \"%s\" from AddObject actuator \"%s\" is not in a hidden layer.\n", objectname.Ptr(), uniquename.Ptr());
							}
							else {
								originalval = converter->FindGameObject(editobact->ob);
							}
						}
						
						KX_SCA_AddObjectActuator* tmpaddact = new KX_SCA_AddObjectActuator(
						            gameobj,
						            originalval,
						            editobact->time,
						            scene,
						            editobact->linVelocity,
						            (editobact->localflag & ACT_EDOB_LOCAL_LINV) != 0,
						            editobact->angVelocity,
						            (editobact->localflag & ACT_EDOB_LOCAL_ANGV) != 0);

								//editobact->ob to gameobj
								baseact = tmpaddact;
					}
					break;
				case ACT_EDOB_END_OBJECT:
					{
						KX_SCA_EndObjectActuator* tmpendact 
							= new KX_SCA_EndObjectActuator(gameobj,scene);
						baseact = tmpendact;
					}
					break;
				case ACT_EDOB_REPLACE_MESH:
					{
						RAS_MeshObject *tmpmesh = converter->FindGameMesh(editobact->me);

						if (!tmpmesh) {
							std::cout << "Warning: object \"" << objectname <<
							"\" from ReplaceMesh actuator \"" << uniquename <<
							"\" uses a mesh not owned by an object in scene \"" <<
							scene->GetName() << "\"." << std::endl;
						}

						KX_SCA_ReplaceMeshActuator* tmpreplaceact = new KX_SCA_ReplaceMeshActuator(
						            gameobj,
						            tmpmesh,
						            scene,
						            (editobact->flag & ACT_EDOB_REPLACE_MESH_NOGFX) == 0,
						            (editobact->flag & ACT_EDOB_REPLACE_MESH_PHYS) != 0);

						baseact = tmpreplaceact;
					}
					break;
				case ACT_EDOB_TRACK_TO:
					{
						SCA_IObject* originalval = NULL;
						if (editobact->ob)
							originalval = converter->FindGameObject(editobact->ob);
							
						KX_TrackToActuator* tmptrackact = new KX_TrackToActuator(
						            gameobj,
						            originalval,
						            editobact->time,
						            editobact->flag,
						            editobact->trackflag,
						            editobact->upflag);
						baseact = tmptrackact;
						break;
					}
				case ACT_EDOB_DYNAMICS:
					{
						KX_SCA_DynamicActuator* tmpdynact = new KX_SCA_DynamicActuator(
						            gameobj,
						            editobact->dyn_operation,
						            editobact->mass);
						baseact = tmpdynact;
					}
				}
				break;
			}
		case ACT_CONSTRAINT:
			{
				float min = 0.0, max = 0.0;
				char *prop = NULL;
				KX_ConstraintActuator::KX_CONSTRAINTTYPE locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_NODEF;
				bConstraintActuator *conact 
					= (bConstraintActuator*) bact->data;
				/* convert settings... degrees in the ui become radians  */ 
				/* internally                                            */ 
				if (conact->type == ACT_CONST_TYPE_ORI) {
					min = conact->minloc[0];
					max = conact->maxloc[0];
					switch (conact->mode) {
					case ACT_CONST_DIRPX:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIX;
						break;
					case ACT_CONST_DIRPY:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIY;
						break;
					case ACT_CONST_DIRPZ:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIZ;
						break;
					}
				} else if (conact->type == ACT_CONST_TYPE_DIST) {
					switch (conact->mode) {
					case ACT_CONST_DIRPX:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRPX;
						min = conact->minloc[0];
						max = conact->maxloc[0];
						break;
					case ACT_CONST_DIRPY:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRPY;
						min = conact->minloc[1];
						max = conact->maxloc[1];
						break;
					case ACT_CONST_DIRPZ:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRPZ;
						min = conact->minloc[2];
						max = conact->maxloc[2];
						break;
					case ACT_CONST_DIRNX:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRNX;
						min = conact->minloc[0];
						max = conact->maxloc[0];
						break;
					case ACT_CONST_DIRNY:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRNY;
						min = conact->minloc[1];
						max = conact->maxloc[1];
						break;
					case ACT_CONST_DIRNZ:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRNZ;
						min = conact->minloc[2];
						max = conact->maxloc[2];
						break;
					}
					prop = conact->matprop;
				} else if (conact->type == ACT_CONST_TYPE_FH) {
					switch (conact->mode) {
					case ACT_CONST_DIRPX:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPX;
						min = conact->minloc[0];
						max = conact->maxloc[0];
						break;
					case ACT_CONST_DIRPY:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPY;
						min = conact->minloc[1];
						max = conact->maxloc[1];
						break;
					case ACT_CONST_DIRPZ:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPZ;
						min = conact->minloc[2];
						max = conact->maxloc[2];
						break;
					case ACT_CONST_DIRNX:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNX;
						min = conact->minloc[0];
						max = conact->maxloc[0];
						break;
					case ACT_CONST_DIRNY:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNY;
						min = conact->minloc[1];
						max = conact->maxloc[1];
						break;
					case ACT_CONST_DIRNZ:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNZ;
						min = conact->minloc[2];
						max = conact->maxloc[2];
						break;
					}
					prop = conact->matprop;
				} else {
					switch (conact->flag) {
					case ACT_CONST_LOCX:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCX; 
						min = conact->minloc[0];
						max = conact->maxloc[0];
						break;
					case ACT_CONST_LOCY:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCY; 
						min = conact->minloc[1];
						max = conact->maxloc[1];
						break;
					case ACT_CONST_LOCZ:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCZ;
						min = conact->minloc[2];
						max = conact->maxloc[2];
						break;
					case ACT_CONST_ROTX:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTX;
						min = conact->minrot[0] * (float)MT_RADS_PER_DEG;
						max = conact->maxrot[0] * (float)MT_RADS_PER_DEG;
						break;
					case ACT_CONST_ROTY:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTY;
						min = conact->minrot[1] * (float)MT_RADS_PER_DEG;
						max = conact->maxrot[1] * (float)MT_RADS_PER_DEG;
						break;
					case ACT_CONST_ROTZ:
						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTZ;
						min = conact->minrot[2] * (float)MT_RADS_PER_DEG;
						max = conact->maxrot[2] * (float)MT_RADS_PER_DEG;
						break;
					default:
						; /* error */ 
					}
				}
				KX_ConstraintActuator *tmpconact = new KX_ConstraintActuator(
				            gameobj,
				            conact->damp,
				            conact->rotdamp,
				            min,
				            max,
				            conact->maxrot,
				            locrot,
				            conact->time,
				            conact->flag,
				            prop);
				baseact = tmpconact;
				break;
			}
		case ACT_GROUP:
			{
				// deprecated
			}
			break;
		case ACT_SCENE:
			{
				bSceneActuator *sceneact = (bSceneActuator *) bact->data;
				STR_String nextSceneName("");
				
				KX_SceneActuator* tmpsceneact;
				int mode = KX_SceneActuator::KX_SCENE_NODEF;
				KX_Camera *cam = NULL;
				//KX_Scene* scene = NULL;
				switch (sceneact->type)
				{
				case ACT_SCENE_RESUME:
				case ACT_SCENE_SUSPEND:
				case ACT_SCENE_ADD_FRONT:
				case ACT_SCENE_ADD_BACK:
				case ACT_SCENE_REMOVE:
				case ACT_SCENE_SET:
					{
						switch (sceneact->type)
						{
						case ACT_SCENE_RESUME:
							mode = KX_SceneActuator::KX_SCENE_RESUME;
							break;
						case ACT_SCENE_SUSPEND:
							mode = KX_SceneActuator::KX_SCENE_SUSPEND;
							break;
						case ACT_SCENE_ADD_FRONT:
							mode = KX_SceneActuator::KX_SCENE_ADD_FRONT_SCENE;
							break;
						case ACT_SCENE_ADD_BACK:
							mode = KX_SceneActuator::KX_SCENE_ADD_BACK_SCENE;
							break;
						case ACT_SCENE_REMOVE:
							mode = KX_SceneActuator::KX_SCENE_REMOVE_SCENE;
							break;
						case ACT_SCENE_SET:
						default:
							mode = KX_SceneActuator::KX_SCENE_SET_SCENE;
							break;
						};
						
						if (sceneact->scene) {
							nextSceneName = sceneact->scene->id.name + 2;
						}
						
						break;
					}
				case ACT_SCENE_CAMERA:
					mode = KX_SceneActuator::KX_SCENE_SET_CAMERA;
					if (sceneact->camera)
					{
						KX_GameObject *tmp = converter->FindGameObject(sceneact->camera);
						if (tmp && tmp->GetGameObjectType() == SCA_IObject::OBJ_CAMERA)
							cam = (KX_Camera*)tmp;
					}
					break;
				case ACT_SCENE_RESTART:
					{
						
						mode =  KX_SceneActuator::KX_SCENE_RESTART;
						break;
					}
				default:
					; /* flag error */
				}
				tmpsceneact = new KX_SceneActuator(
				            gameobj,
				            mode,
				            scene,
				            ketsjiEngine,
				            nextSceneName,
				            cam);
				baseact = tmpsceneact;
				break;
			}
		case ACT_GAME:
			{
				bGameActuator *gameact = (bGameActuator *) bact->data;
				KX_GameActuator* tmpgameact;
				STR_String filename = maggiename;
				STR_String loadinganimationname = "";
				int mode = KX_GameActuator::KX_GAME_NODEF;
				switch (gameact->type)
				{
				case ACT_GAME_LOAD:
					{
						mode = KX_GameActuator::KX_GAME_LOAD;
						filename = gameact->filename;
						loadinganimationname = gameact->loadaniname;
						break;
					}
				case ACT_GAME_START:
					{
						mode = KX_GameActuator::KX_GAME_START;
						filename = gameact->filename;
						loadinganimationname = gameact->loadaniname;
						break;
					}
				case ACT_GAME_RESTART:
					{
						mode = KX_GameActuator::KX_GAME_RESTART;
						break;
					}
				case ACT_GAME_QUIT:
					{
						mode = KX_GameActuator::KX_GAME_QUIT;
						break;
					}
				case ACT_GAME_SAVECFG:
					{
						mode = KX_GameActuator::KX_GAME_SAVECFG;
						break;
					}
				case ACT_GAME_LOADCFG:
					{
						mode = KX_GameActuator::KX_GAME_LOADCFG;
						break;
					}
					case ACT_GAME_SCREENSHOT:
					{
						mode = KX_GameActuator::KX_GAME_SCREENSHOT;
						filename = gameact->filename;
						break;
					}
				default:
					; /* flag error */
				}
				tmpgameact = new KX_GameActuator(
				            gameobj,
				            mode,
				            filename,
				            loadinganimationname,
				            scene,
				            ketsjiEngine);
				baseact = tmpgameact;

				break;
			}
		case ACT_RANDOM:
			{
				bRandomActuator *randAct 
					= (bRandomActuator *) bact->data;
				
				unsigned long seedArg = randAct->seed;
				if (seedArg == 0)
				{
					seedArg = (int)(ketsjiEngine->GetRealTime()*100000.0);
					seedArg ^= (intptr_t)randAct;
				}
				SCA_RandomActuator::KX_RANDOMACT_MODE modeArg 
					= SCA_RandomActuator::KX_RANDOMACT_NODEF;
				SCA_RandomActuator *tmprandomact;
				float paraArg1 = 0.0;
				float paraArg2 = 0.0;
				
				switch (randAct->distribution) {
				case ACT_RANDOM_BOOL_CONST:
					modeArg = SCA_RandomActuator::KX_RANDOMACT_BOOL_CONST;
					paraArg1 = (float) randAct->int_arg_1;
					break;
				case ACT_RANDOM_BOOL_UNIFORM:
					modeArg = SCA_RandomActuator::KX_RANDOMACT_BOOL_UNIFORM;
					break;
				case ACT_RANDOM_BOOL_BERNOUILLI:
					paraArg1 = randAct->float_arg_1;
					modeArg = SCA_RandomActuator::KX_RANDOMACT_BOOL_BERNOUILLI;
					break;
				case ACT_RANDOM_INT_CONST:
					modeArg = SCA_RandomActuator::KX_RANDOMACT_INT_CONST;
					paraArg1 = (float) randAct->int_arg_1;
					break;
				case ACT_RANDOM_INT_UNIFORM:
					paraArg1 = (float) randAct->int_arg_1;
					paraArg2 = (float) randAct->int_arg_2;
					modeArg = SCA_RandomActuator::KX_RANDOMACT_INT_UNIFORM;
					break;
				case ACT_RANDOM_INT_POISSON:
					paraArg1 = randAct->float_arg_1;
					modeArg = SCA_RandomActuator::KX_RANDOMACT_INT_POISSON;
					break;
				case ACT_RANDOM_FLOAT_CONST:
					paraArg1 = randAct->float_arg_1;
					modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_CONST;
					break;
				case ACT_RANDOM_FLOAT_UNIFORM:
					paraArg1 = randAct->float_arg_1;
					paraArg2 = randAct->float_arg_2;
					modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_UNIFORM;
					break;
				case ACT_RANDOM_FLOAT_NORMAL:
					paraArg1 = randAct->float_arg_1;
					paraArg2 = randAct->float_arg_2;
					modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_NORMAL;
					break;
				case ACT_RANDOM_FLOAT_NEGATIVE_EXPONENTIAL:
					paraArg1 = randAct->float_arg_1;
					modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL;
					break;
				default:
					; /* error */
				}
				tmprandomact = new SCA_RandomActuator(
				            gameobj,
				            seedArg,
				            modeArg,
				            paraArg1,
				            paraArg2,
				            randAct->propname);
				baseact = tmprandomact;
			}
			break;

		case ACT_VISIBILITY:
		{
			bVisibilityActuator *vis_act = (bVisibilityActuator *) bact->data;
			KX_VisibilityActuator * tmp_vis_act = NULL;
			bool v = ((vis_act->flag & ACT_VISIBILITY_INVISIBLE) != 0);
			bool o = ((vis_act->flag & ACT_VISIBILITY_OCCLUSION) != 0);
			bool recursive = ((vis_act->flag & ACT_VISIBILITY_RECURSIVE) != 0);

			tmp_vis_act = new KX_VisibilityActuator(gameobj, !v, o, recursive);
			
			baseact = tmp_vis_act;
		}
		break;

		case ACT_STATE:
		{
			bStateActuator *sta_act = (bStateActuator *) bact->data;
			KX_StateActuator * tmp_sta_act = NULL;

			tmp_sta_act = 
				new KX_StateActuator(gameobj, sta_act->type, sta_act->mask);
			
			baseact = tmp_sta_act;
		}
		break;

		case ACT_2DFILTER:
		{
			bTwoDFilterActuator *_2dfilter = (bTwoDFilterActuator*) bact->data;
			SCA_2DFilterActuator *tmp = NULL;

			RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode;
			switch (_2dfilter->type) {
				case ACT_2DFILTER_MOTIONBLUR:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_MOTIONBLUR;
					break;
				case ACT_2DFILTER_BLUR:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_BLUR;
					break;
				case ACT_2DFILTER_SHARPEN:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_SHARPEN;
					break;
				case ACT_2DFILTER_DILATION:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_DILATION;
					break;
				case ACT_2DFILTER_EROSION:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_EROSION;
					break;
				case ACT_2DFILTER_LAPLACIAN:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_LAPLACIAN;
					break;
				case ACT_2DFILTER_SOBEL:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_SOBEL;
					break;
				case ACT_2DFILTER_PREWITT:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_PREWITT;
					break;
				case ACT_2DFILTER_GRAYSCALE:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_GRAYSCALE;
					break;
				case ACT_2DFILTER_SEPIA:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_SEPIA;
					break;
				case ACT_2DFILTER_INVERT:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_INVERT;
					break;
				case ACT_2DFILTER_CUSTOMFILTER:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_CUSTOMFILTER;
					break;
				case ACT_2DFILTER_NOFILTER:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_NOFILTER;
					break;
				case ACT_2DFILTER_DISABLED:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_DISABLED;
					break;
				case ACT_2DFILTER_ENABLED:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_ENABLED;
					break;
				default:
					filtermode = RAS_2DFilterManager::RAS_2DFILTER_NOFILTER;
					break;
			}

			tmp = new SCA_2DFilterActuator(gameobj, filtermode,  _2dfilter->flag,
			                               _2dfilter->float_arg, _2dfilter->int_arg,
			                               ketsjiEngine->GetRasterizer(), scene);

			if (_2dfilter->text)
			{
				char *buf;
				// this is some blender specific code
				buf = txt_to_buf(_2dfilter->text);
				if (buf)
				{
					tmp->SetShaderText(buf);
					MEM_freeN(buf);
				}
			}

			baseact = tmp;

		}
		break;
		case ACT_PARENT:
			{
				bParentActuator *parAct = (bParentActuator *) bact->data;
				int mode = KX_ParentActuator::KX_PARENT_NODEF;
				bool addToCompound = true;
				bool ghost = true;
				KX_GameObject *tmpgob = NULL;

				switch (parAct->type) {
					case ACT_PARENT_SET:
						mode = KX_ParentActuator::KX_PARENT_SET;
						tmpgob = converter->FindGameObject(parAct->ob);
						addToCompound = !(parAct->flag & ACT_PARENT_COMPOUND);
						ghost = !(parAct->flag & ACT_PARENT_GHOST);
						break;
					case ACT_PARENT_REMOVE:
						mode = KX_ParentActuator::KX_PARENT_REMOVE;
						tmpgob = NULL;
						break;
				}
	
				KX_ParentActuator *tmpparact
					= new KX_ParentActuator(gameobj,
					mode,
					addToCompound,
					ghost,
					tmpgob);
				baseact = tmpparact;
				break;
			}
		
		case ACT_ARMATURE:
			{
				bArmatureActuator* armAct = (bArmatureActuator*) bact->data;
				KX_GameObject *tmpgob = converter->FindGameObject(armAct->target);
				KX_GameObject *subgob = converter->FindGameObject(armAct->subtarget);
				BL_ArmatureActuator* tmparmact = new BL_ArmatureActuator(
				            gameobj,
				            armAct->type,
				            armAct->posechannel,
				            armAct->constraint,
				            tmpgob,
				            subgob,
				            armAct->weight,
				            armAct->influence);
				baseact = tmparmact;
				break;
			}
		case ACT_STEERING:
			{
				bSteeringActuator *stAct = (bSteeringActuator *) bact->data;
				KX_GameObject *navmeshob = NULL;
				if (stAct->navmesh)
				{
					PointerRNA settings_ptr;
					RNA_pointer_create((ID *)stAct->navmesh, &RNA_GameObjectSettings, stAct->navmesh, &settings_ptr);
					if (RNA_enum_get(&settings_ptr, "physics_type") == OB_BODY_TYPE_NAVMESH)
						navmeshob = converter->FindGameObject(stAct->navmesh);
				}
				KX_GameObject *targetob = converter->FindGameObject(stAct->target);

				int mode = KX_SteeringActuator::KX_STEERING_NODEF;
				switch (stAct->type) {
				case ACT_STEERING_SEEK:
					mode = KX_SteeringActuator::KX_STEERING_SEEK;
					break;
				case ACT_STEERING_FLEE:
					mode = KX_SteeringActuator::KX_STEERING_FLEE;
					break;
				case ACT_STEERING_PATHFOLLOWING:
					mode = KX_SteeringActuator::KX_STEERING_PATHFOLLOWING;
					break;
				}

				bool selfTerminated = (stAct->flag & ACT_STEERING_SELFTERMINATED) !=0;
				bool enableVisualization = (stAct->flag & ACT_STEERING_ENABLEVISUALIZATION) !=0;
				short facingMode = (stAct->flag & ACT_STEERING_AUTOMATICFACING) ? stAct->facingaxis : 0;
				bool normalup = (stAct->flag & ACT_STEERING_NORMALUP) !=0;
				bool lockzvel = (stAct->flag & ACT_STEERING_LOCKZVEL) !=0;
				KX_SteeringActuator *tmpstact
					= new KX_SteeringActuator(gameobj, mode, targetob, navmeshob,stAct->dist, 
					stAct->velocity, stAct->acceleration, stAct->turnspeed, 
					selfTerminated, stAct->updateTime,
					scene->GetObstacleSimulation(), facingMode, normalup, enableVisualization, lockzvel);
				baseact = tmpstact;
				break;
			}
		case ACT_MOUSE:
			{
				bMouseActuator* mouAct = (bMouseActuator*) bact->data;
				int mode = KX_MouseActuator::KX_ACT_MOUSE_NODEF;

				switch (mouAct->type) {
					case ACT_MOUSE_VISIBILITY:
					{
						mode = KX_MouseActuator::KX_ACT_MOUSE_VISIBILITY;
						break;
					}
					case ACT_MOUSE_LOOK:
					{
						mode = KX_MouseActuator::KX_ACT_MOUSE_LOOK;
						break;
					}
				}

				bool visible = (mouAct->flag & ACT_MOUSE_VISIBLE) != 0;
				bool use_axis[2] = {(mouAct->flag & ACT_MOUSE_USE_AXIS_X) != 0, (mouAct->flag & ACT_MOUSE_USE_AXIS_Y) != 0};
				bool reset[2] = {(mouAct->flag & ACT_MOUSE_RESET_X) != 0, (mouAct->flag & ACT_MOUSE_RESET_Y) != 0};
				bool local[2] = {(mouAct->flag & ACT_MOUSE_LOCAL_X) != 0, (mouAct->flag & ACT_MOUSE_LOCAL_Y) != 0};

				SCA_MouseManager* eventmgr = (SCA_MouseManager*) logicmgr->FindEventManager(SCA_EventManager::MOUSE_EVENTMGR);
				if (eventmgr) {
					KX_MouseActuator* tmpbaseact = new KX_MouseActuator(gameobj,
																		ketsjiEngine,
																		eventmgr,
																		mode,
																		visible,
																		use_axis,
																		mouAct->threshold,
																		reset,
																		mouAct->object_axis,
																		local,
																		mouAct->sensitivity,
																		mouAct->limit_x,
																		mouAct->limit_y);
					baseact = tmpbaseact;
				} else {
					//cout << "\n Couldn't find mouse event manager..."; - should throw an error here...
				}
				break;
			}
		default:
			; /* generate some error */
		}
		
		if (baseact && !(bact->flag & ACT_DEACTIVATE))
		{
			baseact->SetExecutePriority(executePriority++);
			uniquename += "#ACT#";
			uniqueint++;
			CIntValue* uniqueval = new CIntValue(uniqueint);
			uniquename += uniqueval->GetText();
			uniqueval->Release();
			baseact->SetName(bact->name);
			baseact->SetLogicManager(logicmgr);
			//gameobj->SetProperty(uniquename,baseact);
			gameobj->AddActuator(baseact);
			
			converter->RegisterGameActuator(baseact, bact);
			// done with baseact, release it
			baseact->Release();
		}
		else if (baseact)
			baseact->Release();
		
		bact = bact->next;
	}
}
Example #20
0
/* returns 1 if its OK */
static int node_group_separate_selected(bNodeTree *ntree, bNodeTree *ngroup, float offx, float offy, int make_copy)
{
	bNodeLink *link, *link_next;
	bNode *node, *node_next, *newnode;
	ListBase anim_basepaths = {NULL, NULL};
	
	/* deselect all nodes in the target tree */
	for (node = ntree->nodes.first; node; node = node->next)
		nodeSetSelected(node, FALSE);
	
	/* clear new pointers, set in nodeCopyNode */
	for (node = ngroup->nodes.first; node; node = node->next)
		node->new_node = NULL;
	
	/* add selected nodes into the ntree */
	for (node = ngroup->nodes.first; node; node = node_next) {
		node_next = node->next;
		if (!(node->flag & NODE_SELECT))
			continue;
		
		/* ignore interface nodes */
		if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) {
			nodeSetSelected(node, FALSE);
			continue;
		}
		
		if (make_copy) {
			/* make a copy */
			newnode = nodeCopyNode(ngroup, node);
		}
		else {
			/* use the existing node */
			newnode = node;
		}
		
		/* keep track of this node's RNA "base" path (the part of the path identifying the node) 
		 * if the old nodetree has animation data which potentially covers this node
		 */
		if (ngroup->adt) {
			PointerRNA ptr;
			char *path;
			
			RNA_pointer_create(&ngroup->id, &RNA_Node, newnode, &ptr);
			path = RNA_path_from_ID_to_struct(&ptr);
			
			if (path)
				BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
		}
		
		/* ensure valid parent pointers, detach if parent stays inside the group */
		if (newnode->parent && !(newnode->parent->flag & NODE_SELECT))
			nodeDetachNode(newnode);
		
		/* migrate node */
		BLI_remlink(&ngroup->nodes, newnode);
		BLI_addtail(&ntree->nodes, newnode);
		
		/* ensure unique node name in the node tree */
		nodeUniqueName(ntree, newnode);

		if (!newnode->parent) {
			newnode->locx += offx;
			newnode->locy += offy;		
		}
	}
	
	/* add internal links to the ntree */
	for (link = ngroup->links.first; link; link = link_next) {
		int fromselect = (link->fromnode && (link->fromnode->flag & NODE_SELECT));
		int toselect = (link->tonode && (link->tonode->flag & NODE_SELECT));
		link_next = link->next;
		
		if (make_copy) {
			/* make a copy of internal links */
			if (fromselect && toselect)
				nodeAddLink(ntree, link->fromnode->new_node, link->fromsock->new_sock, link->tonode->new_node, link->tosock->new_sock);
		}
		else {
			/* move valid links over, delete broken links */
			if (fromselect && toselect) {
				BLI_remlink(&ngroup->links, link);
				BLI_addtail(&ntree->links, link);
			}
			else if (fromselect || toselect) {
				nodeRemLink(ngroup, link);
			}
		}
	}
	
	/* and copy across the animation,
	 * note that the animation data's action can be NULL here */
	if (ngroup->adt) {
		LinkData *ld, *ldn = NULL;
		
		/* now perform the moving */
		BKE_animdata_separate_by_basepath(&ngroup->id, &ntree->id, &anim_basepaths);
		
		/* paths + their wrappers need to be freed */
		for (ld = anim_basepaths.first; ld; ld = ldn) {
			ldn = ld->next;
			
			MEM_freeN(ld->data);
			BLI_freelinkN(&anim_basepaths, ld);
		}
	}
	
	ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
	if (!make_copy)
		ngroup->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
	
	return 1;
}
Example #21
0
static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree, bNode *gnode)
{
	bNodeTree *ngroup = (bNodeTree *)gnode->id;
	bNodeLink *link, *linkn;
	bNode *node, *nextn;
	bNodeSocket *sock;
	ListBase anim_basepaths = {NULL, NULL};
	float min[2], max[2], center[2];
	int totselect;
	int expose_all = FALSE;
	bNode *input_node, *output_node;
	
	/* XXX rough guess, not nice but we don't have access to UI constants here ... */
	static const float offsetx = 200;
	static const float offsety = 0.0f;
	
	/* deselect all nodes in the target tree */
	for (node = ngroup->nodes.first; node; node = node->next)
		nodeSetSelected(node, FALSE);
	
	totselect = node_get_selected_minmax(ntree, gnode, min, max);
	add_v2_v2v2(center, min, max);
	mul_v2_fl(center, 0.5f);
	
	/* auto-add interface for "solo" nodes */
	if (totselect == 1)
		expose_all = TRUE;
	
	/* move nodes over */
	for (node = ntree->nodes.first; node; node = nextn) {
		nextn = node->next;
		if (node_group_make_use_node(node, gnode)) {
			/* keep track of this node's RNA "base" path (the part of the pat identifying the node) 
			 * if the old nodetree has animation data which potentially covers this node
			 */
			if (ntree->adt) {
				PointerRNA ptr;
				char *path;
				
				RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr);
				path = RNA_path_from_ID_to_struct(&ptr);
				
				if (path)
					BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
			}
			
			/* ensure valid parent pointers, detach if parent stays outside the group */
			if (node->parent && !(node->parent->flag & NODE_SELECT))
				nodeDetachNode(node);
			
			/* change node-collection membership */
			BLI_remlink(&ntree->nodes, node);
			BLI_addtail(&ngroup->nodes, node);
			
			/* ensure unique node name in the ngroup */
			nodeUniqueName(ngroup, node);
		}
	}
	
	/* move animation data over */
	if (ntree->adt) {
		LinkData *ld, *ldn = NULL;
		
		BKE_animdata_separate_by_basepath(&ntree->id, &ngroup->id, &anim_basepaths);
		
		/* paths + their wrappers need to be freed */
		for (ld = anim_basepaths.first; ld; ld = ldn) {
			ldn = ld->next;
			
			MEM_freeN(ld->data);
			BLI_freelinkN(&anim_basepaths, ld);
		}
	}
	
	/* node groups don't use internal cached data */
	ntreeFreeCache(ngroup);
	
	/* create input node */
	input_node = nodeAddStaticNode(C, ngroup, NODE_GROUP_INPUT);
	input_node->locx = min[0] - center[0] - offsetx;
	input_node->locy = -offsety;
	
	/* create output node */
	output_node = nodeAddStaticNode(C, ngroup, NODE_GROUP_OUTPUT);
	output_node->locx = max[0] - center[0] + offsetx;
	output_node->locy = -offsety;
	
	/* relink external sockets */
	for (link = ntree->links.first; link; link = linkn) {
		int fromselect = node_group_make_use_node(link->fromnode, gnode);
		int toselect = node_group_make_use_node(link->tonode, gnode);
		
		linkn = link->next;
		
		if ((fromselect && link->tonode == gnode) || (toselect && link->fromnode == gnode)) {
			/* remove all links to/from the gnode.
			 * this can remove link information, but there's no general way to preserve it.
			 */
			nodeRemLink(ntree, link);
		}
		else if (fromselect && toselect) {
			BLI_remlink(&ntree->links, link);
			BLI_addtail(&ngroup->links, link);
		}
		else if (toselect) {
			bNodeSocket *iosock = ntreeAddSocketInterfaceFromSocket(ngroup, link->tonode, link->tosock);
			bNodeSocket *input_sock;
			
			/* update the group node and interface node sockets,
			 * so the new interface socket can be linked.
			 */
			node_group_verify(ntree, gnode, (ID *)ngroup);
			node_group_input_verify(ngroup, input_node, (ID *)ngroup);
			
			/* create new internal link */
			input_sock = node_group_input_find_socket(input_node, iosock->identifier);
			nodeAddLink(ngroup, input_node, input_sock, link->tonode, link->tosock);
			
			/* redirect external link */
			link->tonode = gnode;
			link->tosock = node_group_find_input_socket(gnode, iosock->identifier);
		}
		else if (fromselect) {
			bNodeSocket *iosock = ntreeAddSocketInterfaceFromSocket(ngroup, link->fromnode, link->fromsock);
			bNodeSocket *output_sock;
			
			/* update the group node and interface node sockets,
			 * so the new interface socket can be linked.
			 */
			node_group_verify(ntree, gnode, (ID *)ngroup);
			node_group_output_verify(ngroup, output_node, (ID *)ngroup);

			/* create new internal link */
			output_sock = node_group_output_find_socket(output_node, iosock->identifier);
			nodeAddLink(ngroup, link->fromnode, link->fromsock, output_node, output_sock);
			
			/* redirect external link */
			link->fromnode = gnode;
			link->fromsock = node_group_find_output_socket(gnode, iosock->identifier);
		}
	}

	/* move nodes in the group to the center */
	for (node = ngroup->nodes.first; node; node = node->next) {
		if (node_group_make_use_node(node, gnode) && !node->parent) {
			node->locx -= center[0];
			node->locy -= center[1];
		}
	}
	
	/* expose all unlinked sockets too */
	if (expose_all) {
		for (node = ngroup->nodes.first; node; node = node->next) {
			if (node_group_make_use_node(node, gnode)) {
				for (sock = node->inputs.first; sock; sock = sock->next) {
					bNodeSocket *iosock, *input_sock;
					int skip = FALSE;
					for (link = ngroup->links.first; link; link = link->next) {
						if (link->tosock == sock) {
							skip = TRUE;
							break;
						}
					}
					if (skip)
						continue;
					
					iosock = ntreeAddSocketInterfaceFromSocket(ngroup, node, sock);
					
					node_group_input_verify(ngroup, input_node, (ID *)ngroup);
					
					/* create new internal link */
					input_sock = node_group_input_find_socket(input_node, iosock->identifier);
					nodeAddLink(ngroup, input_node, input_sock, node, sock);
				}
				
				for (sock = node->outputs.first; sock; sock = sock->next) {
					bNodeSocket *iosock, *output_sock;
					int skip = FALSE;
					for (link = ngroup->links.first; link; link = link->next)
						if (link->fromsock == sock)
							skip = TRUE;
					if (skip)
						continue;
					
					iosock = ntreeAddSocketInterfaceFromSocket(ngroup, node, sock);
					
					node_group_output_verify(ngroup, output_node, (ID *)ngroup);
					
					/* create new internal link */
					output_sock = node_group_output_find_socket(output_node, iosock->identifier);
					nodeAddLink(ngroup, node, sock, output_node, output_sock);
				}
			}
		}
	}

	/* update of the group tree */
	ngroup->update |= NTREE_UPDATE | NTREE_UPDATE_LINKS;
	/* update of the tree containing the group instance node */
	ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
}
Example #22
0
/* driver settings for active F-Curve (only for 'Drivers' mode) */
static void graph_panel_drivers(const bContext *C, Panel *pa)
{
	bAnimListElem *ale;
	FCurve *fcu;
	ChannelDriver *driver;
	DriverVar *dvar;
	
	PointerRNA driver_ptr;
	uiLayout *col;
	uiBlock *block;
	uiBut *but;
	
	/* Get settings from context */
	if (!graph_panel_context(C, &ale, &fcu))
		return;
	driver = fcu->driver;
	
	/* set event handler for panel */
	block = uiLayoutGetBlock(pa->layout); // xxx?
	uiBlockSetHandleFunc(block, do_graph_region_driver_buttons, NULL);
	
	/* general actions - management */
	col = uiLayoutColumn(pa->layout, FALSE);
	block = uiLayoutGetBlock(col);
	but = uiDefBut(block, BUT, B_IPO_DEPCHANGE, IFACE_("Update Dependencies"), 0, 0, 10 * UI_UNIT_X, 22,
	               NULL, 0.0, 0.0, 0, 0, TIP_("Force updates of dependencies"));
	uiButSetFunc(but, driver_update_flags_cb, fcu, NULL);

	but = uiDefBut(block, BUT, B_IPO_DEPCHANGE, IFACE_("Remove Driver"), 0, 0, 10 * UI_UNIT_X, 18,
	               NULL, 0.0, 0.0, 0, 0, TIP_("Remove this driver"));
	uiButSetNFunc(but, driver_remove_cb, MEM_dupallocN(ale), NULL);
		
	/* driver-level settings - type, expressions, and errors */
	RNA_pointer_create(ale->id, &RNA_Driver, driver, &driver_ptr);
	
	col = uiLayoutColumn(pa->layout, TRUE);
	block = uiLayoutGetBlock(col);
	uiItemR(col, &driver_ptr, "type", 0, NULL, ICON_NONE);

	/* show expression box if doing scripted drivers, and/or error messages when invalid drivers exist */
	if (driver->type == DRIVER_TYPE_PYTHON) {
		/* expression */
		uiItemR(col, &driver_ptr, "expression", 0, IFACE_("Expr"), ICON_NONE);

		/* errors? */
		if (driver->flag & DRIVER_FLAG_INVALID)
			uiItemL(col, IFACE_("ERROR: invalid Python expression"), ICON_ERROR);
	}
	else {
		/* errors? */
		if (driver->flag & DRIVER_FLAG_INVALID)
			uiItemL(col, IFACE_("ERROR: invalid target channel(s)"), ICON_ERROR);
	}
		
	col = uiLayoutColumn(pa->layout, TRUE);
	/* debug setting */
	uiItemR(col, &driver_ptr, "show_debug_info", 0, NULL, ICON_NONE);
		
	/* value of driver */
	if (driver->flag & DRIVER_FLAG_SHOWDEBUG) {
		uiLayout *row = uiLayoutRow(col, TRUE);
		char valBuf[32];
			
		uiItemL(row, IFACE_("Driver Value:"), ICON_NONE);
			
		BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", driver->curval);
		uiItemL(row, valBuf, ICON_NONE);
	}
	
	/* add driver variables */
	col = uiLayoutColumn(pa->layout, FALSE);
	block = uiLayoutGetBlock(col);
	but = uiDefBut(block, BUT, B_IPO_DEPCHANGE, IFACE_("Add Variable"), 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y,
	               NULL, 0.0, 0.0, 0, 0, TIP_("Add a new target variable for this Driver"));
	uiButSetFunc(but, driver_add_var_cb, driver, NULL);
	
	/* loop over targets, drawing them */
	for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
		PointerRNA dvar_ptr;
		uiLayout *box, *row;
		
		/* sub-layout column for this variable's settings */
		col = uiLayoutColumn(pa->layout, TRUE);
		
		/* header panel */
		box = uiLayoutBox(col);
		/* first row context info for driver */
		RNA_pointer_create(ale->id, &RNA_DriverVariable, dvar, &dvar_ptr);

		row = uiLayoutRow(box, FALSE);
		block = uiLayoutGetBlock(row);
		/* variable name */
		uiItemR(row, &dvar_ptr, "name", 0, "", ICON_NONE);

		/* remove button */
		uiBlockSetEmboss(block, UI_EMBOSSN);
		but = uiDefIconBut(block, BUT, B_IPO_DEPCHANGE, ICON_X, 290, 0, UI_UNIT_X, UI_UNIT_Y,
		                   NULL, 0.0, 0.0, 0.0, 0.0, IFACE_("Delete target variable"));
		uiButSetFunc(but, driver_delete_var_cb, driver, dvar);
		uiBlockSetEmboss(block, UI_EMBOSS);

		/* variable type */
		row = uiLayoutRow(box, FALSE);
		uiItemR(row, &dvar_ptr, "type", 0, "", ICON_NONE);
				
		/* variable type settings */
		box = uiLayoutBox(col);
		/* controls to draw depends on the type of variable */
		switch (dvar->type) {
			case DVAR_TYPE_SINGLE_PROP:     /* single property */
				graph_panel_driverVar__singleProp(box, ale->id, dvar);
				break;
			case DVAR_TYPE_ROT_DIFF:     /* rotational difference */
				graph_panel_driverVar__rotDiff(box, ale->id, dvar);
				break;
			case DVAR_TYPE_LOC_DIFF:     /* location difference */
				graph_panel_driverVar__locDiff(box, ale->id, dvar);
				break;
			case DVAR_TYPE_TRANSFORM_CHAN:     /* transform channel */
				graph_panel_driverVar__transChan(box, ale->id, dvar);
				break;
		}

		/* value of variable */
		if (driver->flag & DRIVER_FLAG_SHOWDEBUG) {
			char valBuf[32];

			box = uiLayoutBox(col);
			row = uiLayoutRow(box, TRUE);
			uiItemL(row, IFACE_("Value:"), ICON_NONE);

			BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", dvar->curval);
			uiItemL(row, valBuf, ICON_NONE);
		}
	}
	
	/* cleanup */
	MEM_freeN(ale);
}
Example #23
0
/* returns 1 if its OK */
static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
{
	bNodeLink *link, *linkn, *tlink;
	bNode *node, *nextnode;
	bNodeTree *ngroup, *wgroup;
	ListBase anim_basepaths = {NULL, NULL};
	
	ngroup = (bNodeTree *)gnode->id;
	
	/* clear new pointers, set in copytree */
	for (node = ntree->nodes.first; node; node = node->next)
		node->new_node = NULL;
	
	/* wgroup is a temporary copy of the NodeTree we're merging in
	 * - all of wgroup's nodes are transferred across to their new home
	 * - ngroup (i.e. the source NodeTree) is left unscathed
	 * - temp copy. don't change ID usercount
	 */
	wgroup = ntreeCopyTree_ex(ngroup, FALSE);
	
	/* Add the nodes into the ntree */
	for (node = wgroup->nodes.first; node; node = nextnode) {
		nextnode = node->next;
		
		/* Remove interface nodes.
		 * This also removes remaining links to and from interface nodes.
		 */
		if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) {
			nodeFreeNode(wgroup, node);
			continue;
		}
		
		/* keep track of this node's RNA "base" path (the part of the path identifying the node) 
		 * if the old nodetree has animation data which potentially covers this node
		 */
		if (wgroup->adt) {
			PointerRNA ptr;
			char *path;
			
			RNA_pointer_create(&wgroup->id, &RNA_Node, node, &ptr);
			path = RNA_path_from_ID_to_struct(&ptr);
			
			if (path)
				BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
		}
		
		/* migrate node */
		BLI_remlink(&wgroup->nodes, node);
		BLI_addtail(&ntree->nodes, node);
		
		/* ensure unique node name in the node tree */
		nodeUniqueName(ntree, node);
		
		if (!node->parent) {
			node->locx += gnode->locx;
			node->locy += gnode->locy;
		}
		
		node->flag |= NODE_SELECT;
	}
	
	/* Add internal links to the ntree */
	for (link = wgroup->links.first; link; link = linkn) {
		linkn = link->next;
		BLI_remlink(&wgroup->links, link);
		BLI_addtail(&ntree->links, link);
	}
	
	/* and copy across the animation,
	 * note that the animation data's action can be NULL here */
	if (wgroup->adt) {
		LinkData *ld, *ldn = NULL;
		bAction *waction;
		
		/* firstly, wgroup needs to temporary dummy action that can be destroyed, as it shares copies */
		waction = wgroup->adt->action = BKE_action_copy(wgroup->adt->action);
		
		/* now perform the moving */
		BKE_animdata_separate_by_basepath(&wgroup->id, &ntree->id, &anim_basepaths);
		
		/* paths + their wrappers need to be freed */
		for (ld = anim_basepaths.first; ld; ld = ldn) {
			ldn = ld->next;
			
			MEM_freeN(ld->data);
			BLI_freelinkN(&anim_basepaths, ld);
		}
		
		/* free temp action too */
		if (waction) {
			BKE_libblock_free(&G.main->action, waction);
		}
	}
	
	/* free the group tree (takes care of user count) */
	BKE_libblock_free(&G.main->nodetree, wgroup);
	
	/* restore external links to and from the gnode */
	/* note: the nodes have been copied to intermediate wgroup first (so need to use new_node),
	 *       then transferred to ntree (new_node pointers remain valid).
	 */
	
	/* input links */
	for (link = ngroup->links.first; link; link = link->next) {
		if (link->fromnode->type == NODE_GROUP_INPUT) {
			const char *identifier = link->fromsock->identifier;
			int num_external_links = 0;
			
			/* find external links to this input */
			for (tlink = ntree->links.first; tlink; tlink = tlink->next) {
				if (tlink->tonode == gnode && STREQ(tlink->tosock->identifier, identifier)) {
					nodeAddLink(ntree, tlink->fromnode, tlink->fromsock, link->tonode->new_node, link->tosock->new_sock);
					++num_external_links;
				}
			}
			
			/* if group output is not externally linked,
			 * convert the constant input value to ensure somewhat consistent behavior */
			if (num_external_links == 0) {
				/* XXX TODO bNodeSocket *sock = node_group_find_input_socket(gnode, identifier);
				BLI_assert(sock);*/
				
				/* XXX TODO nodeSocketCopy(ntree, link->tosock->new_sock, link->tonode->new_node, ntree, sock, gnode);*/
			}
		}
	}
	
	/* output links */
	for (link = ntree->links.first; link; link = link->next) {
		if (link->fromnode == gnode) {
			const char *identifier = link->fromsock->identifier;
			int num_internal_links = 0;
			
			/* find internal links to this output */
			for (tlink = ngroup->links.first; tlink; tlink = tlink->next) {
				/* only use active output node */
				if (tlink->tonode->type == NODE_GROUP_OUTPUT && (tlink->tonode->flag & NODE_DO_OUTPUT)) {
					if (STREQ(tlink->tosock->identifier, identifier)) {
						nodeAddLink(ntree, tlink->fromnode->new_node, tlink->fromsock->new_sock, link->tonode, link->tosock);
						++num_internal_links;
					}
				}
			}
			
			/* if group output is not internally linked,
			 * convert the constant output value to ensure somewhat consistent behavior */
			if (num_internal_links == 0) {
				/* XXX TODO bNodeSocket *sock = node_group_find_output_socket(gnode, identifier);
				BLI_assert(sock);*/
				
				/* XXX TODO nodeSocketCopy(ntree, link->tosock, link->tonode, ntree, sock, gnode); */
			}
		}
	}
	
	/* delete the group instance */
	nodeFreeNode(ntree, gnode);
	
	ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
	
	return 1;
}
Example #24
0
static void graph_panel_key_properties(const bContext *C, Panel *pa)
{
	bAnimListElem *ale;
	FCurve *fcu;
	BezTriple *bezt, *prevbezt;
	
	uiLayout *layout = pa->layout;
	uiLayout *col;
	uiBlock *block;

	if (!graph_panel_context(C, &ale, &fcu))
		return;
	
	block = uiLayoutGetBlock(layout);
	uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL);
	
	/* only show this info if there are keyframes to edit */
	if (get_active_fcurve_keyframe_edit(fcu, &bezt, &prevbezt)) {
		PointerRNA bezt_ptr, id_ptr, fcu_prop_ptr;
		PropertyRNA *fcu_prop = NULL;
		uiBut *but;
		int unit = B_UNIT_NONE;
		
		/* RNA pointer to keyframe, to allow editing */
		RNA_pointer_create(ale->id, &RNA_Keyframe, bezt, &bezt_ptr);
		
		/* get property that F-Curve affects, for some unit-conversion magic */
		RNA_id_pointer_create(ale->id, &id_ptr);
		if (RNA_path_resolve(&id_ptr, fcu->rna_path, &fcu_prop_ptr, &fcu_prop) && fcu_prop) {
			/* determine the unit for this property */
			unit = RNA_SUBTYPE_UNIT(RNA_property_subtype(fcu_prop));
		}		
		
		/* interpolation */
		col = uiLayoutColumn(layout, FALSE);
		uiItemR(col, &bezt_ptr, "interpolation", 0, NULL, ICON_NONE);
			
		/* numerical coordinate editing 
		 *  - we use the button-versions of the calls so that we can attach special update handlers
		 *    and unit conversion magic that cannot be achieved using a purely RNA-approach
		 */
		// XXX: 
		col = uiLayoutColumn(layout, TRUE);
		/* keyframe itself */
		{
			uiItemL(col, IFACE_("Key:"), ICON_NONE);

			but = uiDefButR(block, NUM, B_REDR, IFACE_("Frame"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "co", 0, 0, 0, -1, -1, NULL);
			uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt);

			but = uiDefButR(block, NUM, B_REDR, IFACE_("Value"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "co", 1, 0, 0, -1, -1, NULL);
			uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt);
			uiButSetUnitType(but, unit);
		}

		/* previous handle - only if previous was Bezier interpolation */
		if ((prevbezt) && (prevbezt->ipo == BEZT_IPO_BEZ)) {
			uiItemL(col, IFACE_("Left Handle:"), ICON_NONE);

			but = uiDefButR(block, NUM, B_REDR, "X", 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "handle_left", 0, 0, 0, -1, -1, NULL);
			uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);

			but = uiDefButR(block, NUM, B_REDR, "Y", 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "handle_left", 1, 0, 0, -1, -1, NULL);
			uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);
			uiButSetUnitType(but, unit);
		}

		/* next handle - only if current is Bezier interpolation */
		if (bezt->ipo == BEZT_IPO_BEZ) {
			uiItemL(col, IFACE_("Right Handle:"), ICON_NONE);

			but = uiDefButR(block, NUM, B_REDR, "X", 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "handle_right", 0, 0, 0, -1, -1, NULL);
			uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);

			but = uiDefButR(block, NUM, B_REDR, "Y", 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "handle_right", 1, 0, 0, -1, -1, NULL);
			uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);
			uiButSetUnitType(but, unit);
		}
	}
	else {
		if ((fcu->bezt == NULL) && (fcu->modifiers.first)) {
			/* modifiers only - so no keyframes to be active */
			uiItemL(layout, IFACE_("F-Curve only has F-Modifiers"), ICON_NONE);
			uiItemL(layout, IFACE_("See Modifiers panel below"), ICON_INFO);
		}
		else if (fcu->fpt) {
			/* samples only */
			uiItemL(layout, IFACE_("F-Curve doesn't have any keyframes as it only contains sampled points"),
			        ICON_NONE);
		}
		else
			uiItemL(layout, IFACE_("No active keyframe on F-Curve"), ICON_NONE);
	}
	
	MEM_freeN(ale);
}
Example #25
0
static char *rna_ColorRampElement_path(PointerRNA *ptr)
{
	PointerRNA ramp_ptr;
	PropertyRNA *prop;
	char *path = NULL;
	int index;
	
	/* helper macro for use here to try and get the path
	 *	- this calls the standard code for getting a path to a texture...
	 */

#define COLRAMP_GETPATH                                                       \
{                                                                             \
	prop = RNA_struct_find_property(&ramp_ptr, "elements");                   \
	if (prop) {                                                               \
		index = RNA_property_collection_lookup_index(&ramp_ptr, prop, ptr);   \
		if (index != -1) {                                                    \
			char *texture_path = rna_ColorRamp_path(&ramp_ptr);               \
			path = BLI_sprintfN("%s.elements[%d]", texture_path, index);      \
			MEM_freeN(texture_path);                                          \
		}                                                                     \
	}                                                                         \
} (void)0

	/* determine the path from the ID-block to the ramp */
	/* FIXME: this is a very slow way to do it, but it will have to suffice... */
	if (ptr->id.data) {
		ID *id = ptr->id.data;
		
		switch (GS(id->name)) {
			case ID_MA: /* 2 cases for material - diffuse and spec */
			{
				Material *ma = (Material *)id;
				
				/* try diffuse first */
				if (ma->ramp_col) {
					RNA_pointer_create(id, &RNA_ColorRamp, ma->ramp_col, &ramp_ptr);
					COLRAMP_GETPATH;
				}
				/* try specular if not diffuse */
				if (!path && ma->ramp_spec) {
					RNA_pointer_create(id, &RNA_ColorRamp, ma->ramp_spec, &ramp_ptr);
					COLRAMP_GETPATH;
				}
				break;
			}
			case ID_NT:
			{
				bNodeTree *ntree = (bNodeTree *)id;
				bNode *node;
				
				for (node = ntree->nodes.first; node; node = node->next) {
					if (ELEM(node->type, SH_NODE_VALTORGB, CMP_NODE_VALTORGB, TEX_NODE_VALTORGB)) {
						RNA_pointer_create(id, &RNA_ColorRamp, node->storage, &ramp_ptr);
						COLRAMP_GETPATH;
					}
				}
				break;
			}
			case ID_LS:
			{
				ListBase listbase;
				LinkData *link;

				BKE_linestyle_modifier_list_color_ramps((FreestyleLineStyle *)id, &listbase);
				for (link = (LinkData *)listbase.first; link; link = link->next) {
					RNA_pointer_create(id, &RNA_ColorRamp, link->data, &ramp_ptr);
					COLRAMP_GETPATH;
				}
				BLI_freelistN(&listbase);
				break;
			}

			default: /* everything else should have a "color_ramp" property */
			{
				/* create pointer to the ID block, and try to resolve "color_ramp" pointer */
				RNA_id_pointer_create(id, &ramp_ptr);
				if (RNA_path_resolve(&ramp_ptr, "color_ramp", &ramp_ptr, &prop)) {
					COLRAMP_GETPATH;
				}
				break;
			}
		}
	}
	
	/* cleanup the macro we defined */
#undef COLRAMP_GETPATH
	
	return path;
}
Example #26
0
static char *rna_ColorRamp_path(PointerRNA *ptr)
{
	char *path = NULL;
	
	/* handle the cases where a single data-block may have 2 ramp types */
	if (ptr->id.data) {
		ID *id = ptr->id.data;
		
		switch (GS(id->name)) {
			case ID_MA: /* material has 2 cases - diffuse and specular */
			{
				Material *ma = (Material *)id;
				
				if (ptr->data == ma->ramp_col)
					path = BLI_strdup("diffuse_ramp");
				else if (ptr->data == ma->ramp_spec)
					path = BLI_strdup("specular_ramp");
				break;
			}
			
			case ID_NT:
			{
				bNodeTree *ntree = (bNodeTree *)id;
				bNode *node;
				PointerRNA node_ptr;
				char *node_path;
				
				for (node = ntree->nodes.first; node; node = node->next) {
					if (ELEM(node->type, SH_NODE_VALTORGB, CMP_NODE_VALTORGB, TEX_NODE_VALTORGB)) {
						if (node->storage == ptr->data) {
							/* all node color ramp properties called 'color_ramp'
							 * prepend path from ID to the node
							 */
							RNA_pointer_create(id, &RNA_Node, node, &node_ptr);
							node_path = RNA_path_from_ID_to_struct(&node_ptr);
							path = BLI_sprintfN("%s.color_ramp", node_path);
							MEM_freeN(node_path);
						}
					}
				}
				break;
			}
			
			case ID_LS:
			{
				/* may be NULL */
				path = BKE_linestyle_path_to_color_ramp((FreestyleLineStyle *)id, (ColorBand *)ptr->data);
				break;
			}
			
			default:
				/* everything else just uses 'color_ramp' */
				path = BLI_strdup("color_ramp");
				break;
		}
	}
	else {
		/* everything else just uses 'color_ramp' */
		path = BLI_strdup("color_ramp");
	}
	
	return path;
}
Example #27
0
void ANIM_uiTemplate_fmodifier_draw(uiLayout *layout, ID *id, ListBase *modifiers, FModifier *fcm)
{
	FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm);
	uiLayout *box, *row, *sub, *col;
	uiBlock *block;
	uiBut *but;
	short width = 314;
	PointerRNA ptr;
	
	/* init the RNA-pointer */
	RNA_pointer_create(id, &RNA_FModifier, fcm, &ptr);
	
	/* draw header */
	{
		/* get layout-row + UI-block for this */
		box = uiLayoutBox(layout);
		
		row = uiLayoutRow(box, FALSE);
		block = uiLayoutGetBlock(row); // err...
		
		/* left-align -------------------------------------------- */
		sub = uiLayoutRow(row, TRUE);
		uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
		
		uiBlockSetEmboss(block, UI_EMBOSSN);
		
		/* expand */
		uiItemR(sub, &ptr, "show_expanded", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
		
		/* checkbox for 'active' status (for now) */
		uiItemR(sub, &ptr, "active", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
		
		/* name */
		if (fmi)
			uiItemL(sub, IFACE_(fmi->name), ICON_NONE);
		else
			uiItemL(sub, IFACE_("<Unknown Modifier>"), ICON_NONE);
		
		/* right-align ------------------------------------------- */
		sub = uiLayoutRow(row, TRUE);
		uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_RIGHT);
		
		
		/* 'mute' button */
		uiItemR(sub, &ptr, "mute", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
		
		uiBlockSetEmboss(block, UI_EMBOSSN);
		
		/* delete button */
		but = uiDefIconBut(block, BUT, B_REDR, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y,
		                   NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Delete F-Curve Modifier"));
		uiButSetFunc(but, delete_fmodifier_cb, modifiers, fcm);
		
		uiBlockSetEmboss(block, UI_EMBOSS);
	}
	
	/* when modifier is expanded, draw settings */
	if (fcm->flag & FMODIFIER_FLAG_EXPANDED) {
		/* set up the flexible-box layout which acts as the backdrop for the modifier settings */
		box = uiLayoutBox(layout);
		
		/* draw settings for individual modifiers */
		switch (fcm->type) {
			case FMODIFIER_TYPE_GENERATOR: /* Generator */
				draw_modifier__generator(box, id, fcm, width);
				break;
				
			case FMODIFIER_TYPE_FN_GENERATOR: /* Built-In Function Generator */
				draw_modifier__fn_generator(box, id, fcm, width);
				break;
				
			case FMODIFIER_TYPE_CYCLES: /* Cycles */
				draw_modifier__cycles(box, id, fcm, width);
				break;
				
			case FMODIFIER_TYPE_ENVELOPE: /* Envelope */
				draw_modifier__envelope(box, id, fcm, width);
				break;
				
			case FMODIFIER_TYPE_LIMITS: /* Limits */
				draw_modifier__limits(box, id, fcm, width);
				break;
			
			case FMODIFIER_TYPE_NOISE: /* Noise */
				draw_modifier__noise(box, id, fcm, width);
				break;
				
			case FMODIFIER_TYPE_STEPPED: /* Stepped */
				draw_modifier__stepped(box, id, fcm, width);
				break;
			
			default: /* unknown type */
				break;
		}
		
		/* one last panel below this: FModifier range */
		// TODO: experiment with placement of this
		{
			box = uiLayoutBox(layout);
			
			/* restricted range ----------------------------------------------------- */
			col = uiLayoutColumn(box, TRUE);
			
			/* top row: use restricted range */
			row = uiLayoutRow(col, TRUE);
			uiItemR(row, &ptr, "use_restricted_range", 0, NULL, ICON_NONE);
			
			if (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) {
				/* second row: settings */
				row = uiLayoutRow(col, TRUE);
				
				uiItemR(row, &ptr, "frame_start", 0, IFACE_("Start"), ICON_NONE);
				uiItemR(row, &ptr, "frame_end", 0, IFACE_("End"), ICON_NONE);
				
				/* third row: blending influence */
				row = uiLayoutRow(col, TRUE);
				
				uiItemR(row, &ptr, "blend_in", 0, IFACE_("In"), ICON_NONE);
				uiItemR(row, &ptr, "blend_out", 0, IFACE_("Out"), ICON_NONE);
			}
			
			/* influence -------------------------------------------------------------- */
			col = uiLayoutColumn(box, TRUE);
			
			/* top row: use influence */
			uiItemR(col, &ptr, "use_influence", 0, NULL, ICON_NONE);
			
			if (fcm->flag & FMODIFIER_FLAG_USEINFLUENCE) {
				/* second row: influence value */
				uiItemR(col, &ptr, "influence", 0, NULL, ICON_NONE);
			}
		}
	}
}
Example #28
0
void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar)
{
  ScrArea *sa = CTX_wm_area(C);
  SpaceClip *sc = CTX_wm_space_clip(C);
  View2D *v2d = &ar->v2d;
  MovieClip *clip = ED_space_clip_get_clip(sc);
  uiStyle *style = UI_style_get();
  int fontid = style->widget.uifont_id;

  if (!clip) {
    return;
  }

  MovieTracking *tracking = &clip->tracking;
  MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
  int height = (dopesheet->tot_channel * CHANNEL_STEP) + (CHANNEL_HEIGHT);

  if (height > BLI_rcti_size_y(&v2d->mask)) {
    /* don't use totrect set, as the width stays the same
     * (NOTE: this is ok here, the configuration is pretty straightforward)
     */
    v2d->tot.ymin = (float)(-height);
  }

  /* need to do a view-sync here, so that the keys area doesn't jump around
   * (it must copy this) */
  UI_view2d_sync(NULL, sa, v2d, V2D_LOCK_COPY);

  /* loop through channels, and set up drawing depending on their type
   * first pass: just the standard GL-drawing for backdrop + text
   */
  float y = (float)CHANNEL_FIRST;

  GPUVertFormat *format = immVertexFormat();
  uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);

  immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);

  MovieTrackingDopesheetChannel *channel;
  for (channel = dopesheet->channels.first; channel; channel = channel->next) {
    float yminc = (float)(y - CHANNEL_HEIGHT_HALF);
    float ymaxc = (float)(y + CHANNEL_HEIGHT_HALF);

    /* check if visible */
    if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
        IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) {
      MovieTrackingTrack *track = channel->track;
      float color[3];
      track_channel_color(track, NULL, color);
      immUniformColor3fv(color);

      immRectf(pos,
               v2d->cur.xmin,
               (float)y - CHANNEL_HEIGHT_HALF,
               v2d->cur.xmax + EXTRA_SCROLL_PAD,
               (float)y + CHANNEL_HEIGHT_HALF);
    }

    /* adjust y-position for next one */
    y -= CHANNEL_STEP;
  }
  immUnbindProgram();

  /* second pass: text */
  y = (float)CHANNEL_FIRST;

  BLF_size(fontid, 11.0f * U.pixelsize, U.dpi);

  for (channel = dopesheet->channels.first; channel; channel = channel->next) {
    float yminc = (float)(y - CHANNEL_HEIGHT_HALF);
    float ymaxc = (float)(y + CHANNEL_HEIGHT_HALF);

    /* check if visible */
    if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
        IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) {
      MovieTrackingTrack *track = channel->track;
      bool sel = (track->flag & TRACK_DOPE_SEL) != 0;

      UI_FontThemeColor(fontid, sel ? TH_TEXT_HI : TH_TEXT);

      float font_height = BLF_height(fontid, channel->name, sizeof(channel->name));
      BLF_position(fontid, v2d->cur.xmin + CHANNEL_PAD, y - font_height / 2.0f, 0.0f);
      BLF_draw(fontid, channel->name, strlen(channel->name));
    }

    /* adjust y-position for next one */
    y -= CHANNEL_STEP;
  }

  /* third pass: widgets */
  uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
  y = (float)CHANNEL_FIRST;

  /* get RNA properties (once) */
  PropertyRNA *chan_prop_lock = RNA_struct_type_find_property(&RNA_MovieTrackingTrack, "lock");
  BLI_assert(chan_prop_lock);

  GPU_blend(true);
  for (channel = dopesheet->channels.first; channel; channel = channel->next) {
    float yminc = (float)(y - CHANNEL_HEIGHT_HALF);
    float ymaxc = (float)(y + CHANNEL_HEIGHT_HALF);

    /* check if visible */
    if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
        IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) {
      MovieTrackingTrack *track = channel->track;
      const int icon = (track->flag & TRACK_LOCKED) ? ICON_LOCKED : ICON_UNLOCKED;
      PointerRNA ptr;

      RNA_pointer_create(&clip->id, &RNA_MovieTrackingTrack, track, &ptr);

      UI_block_emboss_set(block, UI_EMBOSS_NONE);
      uiDefIconButR_prop(block,
                         UI_BTYPE_ICON_TOGGLE,
                         1,
                         icon,
                         v2d->cur.xmax - UI_UNIT_X - CHANNEL_PAD,
                         y - UI_UNIT_Y / 2.0f,
                         UI_UNIT_X,
                         UI_UNIT_Y,
                         &ptr,
                         chan_prop_lock,
                         0,
                         0,
                         0,
                         0,
                         0,
                         NULL);
      UI_block_emboss_set(block, UI_EMBOSS);
    }

    /* adjust y-position for next one */
    y -= CHANNEL_STEP;
  }
  GPU_blend(false);

  UI_block_end(C, block);
  UI_block_draw(C, block);
}
Example #29
0
bool nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA *nlt_ptr, PointerRNA *strip_ptr)
{
	bAnimContext ac;
	bAnimListElem *ale = NULL;
	ListBase anim_data = {NULL, NULL};
	short found = 0; /* not bool, since we need to indicate "found but not ideal" status */
	int filter;
	
	/* for now, only draw if we could init the anim-context info (necessary for all animation-related tools) 
	 * to work correctly is able to be correctly retrieved. There's no point showing empty panels?
	 */
	if (ANIM_animdata_get_context(C, &ac) == 0) 
		return false;
	
	/* extract list of active channel(s), of which we should only take the first one 
	 *	- we need the channels flag to get the active AnimData block when there are no NLA Tracks
	 */
	// XXX: double-check active!
	filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ACTIVE | ANIMFILTER_LIST_CHANNELS);
	ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
	
	for (ale = anim_data.first; ale; ale = ale->next) {
		switch (ale->type) {
			case ANIMTYPE_NLATRACK: /* NLA Track - The primary data type which should get caught */
			{
				NlaTrack *nlt = (NlaTrack *)ale->data;
				AnimData *adt = ale->adt;
				
				/* found it, now set the pointers */
				if (adt_ptr) {
					/* AnimData pointer */
					RNA_pointer_create(ale->id, &RNA_AnimData, adt, adt_ptr);
				}
				if (nlt_ptr) {
					/* NLA-Track pointer */
					RNA_pointer_create(ale->id, &RNA_NlaTrack, nlt, nlt_ptr);
				}
				if (strip_ptr) {
					/* NLA-Strip pointer */
					NlaStrip *strip = BKE_nlastrip_find_active(nlt);
					RNA_pointer_create(ale->id, &RNA_NlaStrip, strip, strip_ptr);
				}
				
				found = 1;
				break;
			}
			case ANIMTYPE_SCENE:    /* Top-Level Widgets doubling up as datablocks */
			case ANIMTYPE_OBJECT:
			case ANIMTYPE_DSMAT:    /* Datablock AnimData Expanders */
			case ANIMTYPE_DSLAM:
			case ANIMTYPE_DSCAM:
			case ANIMTYPE_DSCACHEFILE:
			case ANIMTYPE_DSCUR:
			case ANIMTYPE_DSSKEY:
			case ANIMTYPE_DSWOR:
			case ANIMTYPE_DSNTREE:
			case ANIMTYPE_DSPART:
			case ANIMTYPE_DSMBALL:
			case ANIMTYPE_DSARM:
			case ANIMTYPE_DSMESH:
			case ANIMTYPE_DSTEX:
			case ANIMTYPE_DSLAT:
			case ANIMTYPE_DSLINESTYLE:
			case ANIMTYPE_DSSPK:
			case ANIMTYPE_DSGPENCIL:
			{
				/* for these channels, we only do AnimData */
				if (ale->adt && adt_ptr) {
					ID *id;
					
					if ((ale->data == NULL) || (ale->type == ANIMTYPE_OBJECT)) {
						/* ale->data is not an ID block! */
						id = ale->id;
					}
					else {
						/* ale->data is always the proper ID block we need, but ale->id may not be (i.e. for textures) */
						id = (ID *)ale->data;
					}
					
					/* AnimData pointer */
					if (adt_ptr) {
						RNA_pointer_create(id, &RNA_AnimData, ale->adt, adt_ptr);
					}
					
					/* set found status to -1, since setting to 1 would break the loop 
					 * and potentially skip an active NLA-Track in some cases...
					 */
					found = -1;
				}
				break;
			}
		}
		
		if (found > 0)
			break;
	}
	
	/* free temp data */
	ANIM_animdata_freelist(&anim_data);
	
	return (found != 0);
}
Example #30
0
void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
{
	bScreen *screen = CTX_wm_screen(C);
	ScrArea *sa = CTX_wm_area(C);
	View3D *v3d = sa->spacedata.first;
	Scene *scene = CTX_data_scene(C);
	ToolSettings *ts = CTX_data_tool_settings(C);
	PointerRNA v3dptr, toolsptr, sceneptr;
	Object *ob = OBACT;
	Object *obedit = CTX_data_edit_object(C);
	uiBlock *block;
	uiBut *but;
	uiLayout *row;
	const float dpi_fac = UI_DPI_FAC;
	int is_paint = 0;
	
	RNA_pointer_create(&screen->id, &RNA_SpaceView3D, v3d, &v3dptr);	
	RNA_pointer_create(&scene->id, &RNA_ToolSettings, ts, &toolsptr);
	RNA_pointer_create(&scene->id, &RNA_Scene, scene, &sceneptr);

	block = uiLayoutGetBlock(layout);
	uiBlockSetHandleFunc(block, do_view3d_header_buttons, NULL);

	/* other buttons: */
	uiBlockSetEmboss(block, UI_EMBOSS);
	
	/* mode */
	if (ob) {
		v3d->modeselect = ob->mode;
		is_paint = ELEM4(ob->mode, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT);
	}
	else {
		v3d->modeselect = OB_MODE_OBJECT;
	}

	row = uiLayoutRow(layout, TRUE);
	uiDefIconTextButS(block, MENU, B_MODESELECT, object_mode_icon(v3d->modeselect), view3d_modeselect_pup(scene),
	                  0, 0, 126 * dpi_fac, UI_UNIT_Y, &(v3d->modeselect), 0, 0, 0, 0, TIP_("Mode"));
	
	/* Draw type */
	uiItemR(layout, &v3dptr, "viewport_shade", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);

	if (obedit == NULL && is_paint) {
		/* Manipulators aren't used in paint modes */
		if (!ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_PARTICLE_EDIT)) {
			/* masks aren't used for sculpt and particle painting */
			PointerRNA meshptr;

			RNA_pointer_create(&ob->id, &RNA_Mesh, ob->data, &meshptr);
			if (ob->mode & (OB_MODE_TEXTURE_PAINT | OB_MODE_VERTEX_PAINT)) {
				uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
			}
			else {
				row = uiLayoutRow(layout, TRUE);
				uiItemR(row, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
				uiItemR(row, &meshptr, "use_paint_mask_vertex", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
			}
		}
	}
	else {
		const char *str_menu;

		row = uiLayoutRow(layout, TRUE);
		uiItemR(row, &v3dptr, "pivot_point", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);

		/* pose/object only however we want to allow in weight paint mode too
		 * so don't be totally strict and just check not-editmode for now */
		if (obedit == NULL) {
			uiItemR(row, &v3dptr, "use_pivot_point_align", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
		}

		/* Transform widget / manipulators */
		row = uiLayoutRow(layout, TRUE);
		uiItemR(row, &v3dptr, "show_manipulator", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
		block = uiLayoutGetBlock(row);
		
		if (v3d->twflag & V3D_USE_MANIPULATOR) {
			but = uiDefIconButBitC(block, TOG, V3D_MANIP_TRANSLATE, B_MAN_TRANS, ICON_MAN_TRANS, 0, 0, UI_UNIT_X, UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, TIP_("Translate manipulator - Shift-Click for multiple modes"));
			uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
			but = uiDefIconButBitC(block, TOG, V3D_MANIP_ROTATE, B_MAN_ROT, ICON_MAN_ROT, 0, 0, UI_UNIT_X, UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, TIP_("Rotate manipulator - Shift-Click for multiple modes"));
			uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
			but = uiDefIconButBitC(block, TOG, V3D_MANIP_SCALE, B_MAN_SCALE, ICON_MAN_SCALE, 0, 0, UI_UNIT_X, UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, TIP_("Scale manipulator - Shift-Click for multiple modes"));
			uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
		}
			
		if (v3d->twmode > (BIF_countTransformOrientation(C) - 1) + V3D_MANIP_CUSTOM) {
			v3d->twmode = 0;
		}
			
		str_menu = BIF_menustringTransformOrientation(C, "Orientation");
		but = uiDefButC(block, MENU, B_MAN_MODE, str_menu, 0, 0, 70 * dpi_fac, UI_UNIT_Y, &v3d->twmode, 0, 0, 0, 0, TIP_("Transform Orientation"));
		uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
		MEM_freeN((void *)str_menu);
	}

	if (obedit == NULL && v3d->localvd == NULL) {
		unsigned int ob_lay = ob ? ob->lay : 0;

		/* Layers */
		uiTemplateLayers(layout, v3d->scenelock ? &sceneptr : &v3dptr, "layers", &v3dptr, "layers_used", ob_lay);

		/* Scene lock */
		uiItemR(layout, &v3dptr, "lock_camera_and_layers", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
	}
	
	uiTemplateEditModeSelection(layout, C);
}