Ejemplo n.º 1
0
static int reports_to_text_exec(bContext *C, wmOperator *UNUSED(op))
{
	ReportList *reports = CTX_wm_reports(C);
	Text *txt;
	char *str;
	
	/* create new text-block to write to */
	txt = add_empty_text("Recent Reports");
	
	/* convert entire list to a display string, and add this to the text-block
	 *	- if commandline debug option enabled, show debug reports too
	 *	- otherwise, up to info (which is what users normally see)
	 */
	str = BKE_reports_string(reports, (G.f & G_DEBUG)? RPT_DEBUG : RPT_INFO);

	if (str) {
		write_text(txt, str);
		MEM_freeN(str);

		return OPERATOR_FINISHED;
	}
	else {
		return OPERATOR_CANCELLED;
	}
}
Ejemplo n.º 2
0
void BKE_reports_print(ReportList *reports, ReportType level)
{
	char *cstring = BKE_reports_string(reports, level);
	
	if (cstring == NULL)
		return;
	
	puts(cstring);
	fflush(stdout);
	MEM_freeN(cstring);
}
Ejemplo n.º 3
0
static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData,
                                  ModifierApplyFlag UNUSED(flag))
{
	DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
	DerivedMesh *dm = derivedData;
	ReportList reports;

	/* Only used to check wehther we are operating on org data or not... */
	Mesh *me = ob->data;
	MVert *mvert;

	const bool invert_vgroup = (dtmd->flags & MOD_DATATRANSFER_INVERT_VGROUP) != 0;

	const float max_dist = (dtmd->flags & MOD_DATATRANSFER_MAP_MAXDIST) ? dtmd->map_max_distance : FLT_MAX;

	SpaceTransform space_transform_data;
	SpaceTransform *space_transform = (dtmd->flags & MOD_DATATRANSFER_OBSRC_TRANSFORM) ? &space_transform_data : NULL;

	if (space_transform) {
		BLI_SPACE_TRANSFORM_SETUP(space_transform, ob, dtmd->ob_source);
	}

	mvert = dm->getVertArray(dm);
	if ((me->mvert == mvert) && (dtmd->data_types & DT_TYPES_AFFECT_MESH)) {
		/* We need to duplicate data here, otherwise setting custom normals, edges' shaprness, etc., could
		 * modify org mesh, see T43671. */
		dm = CDDM_copy(dm);
	}

	BKE_reports_init(&reports, RPT_STORE);

	/* Note: no islands precision for now here. */
	BKE_object_data_transfer_dm(md->scene, dtmd->ob_source, ob, dm, dtmd->data_types, false,
	                     dtmd->vmap_mode, dtmd->emap_mode, dtmd->lmap_mode, dtmd->pmap_mode,
	                     space_transform, max_dist, dtmd->map_ray_radius, 0.0f,
	                     dtmd->layers_select_src, dtmd->layers_select_dst,
	                     dtmd->mix_mode, dtmd->mix_factor, dtmd->defgrp_name, invert_vgroup, &reports);

	if (BKE_reports_contain(&reports, RPT_ERROR)) {
		modifier_setError(md, "%s", BKE_reports_string(&reports, RPT_ERROR));
	}
	else if (dm->getNumVerts(dm) > HIGH_POLY_WARNING || ((Mesh *)(dtmd->ob_source->data))->totvert > HIGH_POLY_WARNING) {
		modifier_setError(md, "You are using a rather high poly as source or destination, computation might be slow");
	}

	return dm;
}
Ejemplo n.º 4
0
short BPy_reports_to_error(ReportList *reports, PyObject *exception, const bool clear)
{
	char *report_str;

	report_str = BKE_reports_string(reports, RPT_ERROR);

	if (clear == true) {
		BKE_reports_clear(reports);
	}

	if (report_str) {
		PyErr_SetString(exception, report_str);
		MEM_freeN(report_str);
	}

	return (report_str == NULL) ? 0 : -1;
}
Ejemplo n.º 5
0
static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
{
	wmOperatorType *ot;
	int error_val = 0;
	PointerRNA ptr;
	int operator_ret = OPERATOR_CANCELLED;

	char     *opname;
	char     *context_str = NULL;
	PyObject *kw = NULL; /* optional args */
	PyObject *context_dict = NULL; /* optional args */
	PyObject *context_dict_back;

	/* note that context is an int, python does the conversion in this case */
	int context = WM_OP_EXEC_DEFAULT;
	int is_undo = false;

	/* XXX Todo, work out a better solution for passing on context,
	 * could make a tuple from self and pack the name and Context into it... */
	bContext *C = (bContext *)BPy_GetContext();
	
	if (C == NULL) {
		PyErr_SetString(PyExc_RuntimeError, "Context is None, cant poll any operators");
		return NULL;
	}
	
	if (!PyArg_ParseTuple(args, "sO|O!si:_bpy.ops.call",
	                      &opname, &context_dict, &PyDict_Type, &kw, &context_str, &is_undo))
	{
		return NULL;
	}

	ot = WM_operatortype_find(opname, true);

	if (ot == NULL) {
		PyErr_Format(PyExc_AttributeError,
		             "Calling operator \"bpy.ops.%s\" error, "
		             "could not be found", opname);
		return NULL;
	}
	
	if (!pyrna_write_check()) {
		PyErr_Format(PyExc_RuntimeError,
		             "Calling operator \"bpy.ops.%s\" error, "
		             "can't modify blend data in this state (drawing/rendering)",
		             opname);
		return NULL;
	}

	if (context_str) {
		if (RNA_enum_value_from_id(operator_context_items, context_str, &context) == 0) {
			char *enum_str = BPy_enum_as_string(operator_context_items);
			PyErr_Format(PyExc_TypeError,
			             "Calling operator \"bpy.ops.%s\" error, "
			             "expected a string enum in (%.200s)",
			             opname, enum_str);
			MEM_freeN(enum_str);
			return NULL;
		}
	}

	if (context_dict == NULL || context_dict == Py_None) {
		context_dict = NULL;
	}
	else if (!PyDict_Check(context_dict)) {
		PyErr_Format(PyExc_TypeError,
		             "Calling operator \"bpy.ops.%s\" error, "
		             "custom context expected a dict or None, got a %.200s",
		             opname, Py_TYPE(context_dict)->tp_name);
		return NULL;
	}

	context_dict_back = CTX_py_dict_get(C);

	CTX_py_dict_set(C, (void *)context_dict);
	Py_XINCREF(context_dict); /* so we done loose it */

	if (WM_operator_poll_context((bContext *)C, ot, context) == false) {
		const char *msg = CTX_wm_operator_poll_msg_get(C);
		PyErr_Format(PyExc_RuntimeError,
		             "Operator bpy.ops.%.200s.poll() %.200s",
		             opname, msg ? msg : "failed, context is incorrect");
		CTX_wm_operator_poll_msg_set(C, NULL); /* better set to NULL else it could be used again */
		error_val = -1;
	}
	else {
		WM_operator_properties_create_ptr(&ptr, ot);
		WM_operator_properties_sanitize(&ptr, 0);

		if (kw && PyDict_Size(kw))
			error_val = pyrna_pydict_to_props(&ptr, kw, 0, "Converting py args to operator properties: ");


		if (error_val == 0) {
			ReportList *reports;

			reports = MEM_mallocN(sizeof(ReportList), "wmOperatorReportList");
			BKE_reports_init(reports, RPT_STORE | RPT_OP_HOLD); /* own so these don't move into global reports */

#ifdef BPY_RELEASE_GIL
			/* release GIL, since a thread could be started from an operator
			 * that updates a driver */
			/* note: I have not seen any examples of code that does this
			 * so it may not be officially supported but seems to work ok. */
			{
				PyThreadState *ts = PyEval_SaveThread();
#endif

				operator_ret = WM_operator_call_py(C, ot, context, &ptr, reports, is_undo);

#ifdef BPY_RELEASE_GIL
				/* regain GIL */
				PyEval_RestoreThread(ts);
			}
#endif

			error_val = BPy_reports_to_error(reports, PyExc_RuntimeError, false);

			/* operator output is nice to have in the terminal/console too */
			if (reports->list.first) {
				char *report_str = BKE_reports_string(reports, 0); /* all reports */
	
				if (report_str) {
					PySys_WriteStdout("%s\n", report_str);
					MEM_freeN(report_str);
				}
			}
	
			BKE_reports_clear(reports);
			if ((reports->flag & RPT_FREE) == 0) {
				MEM_freeN(reports);
			}
		}

		WM_operator_properties_free(&ptr);

#if 0
		/* if there is some way to know an operator takes args we should use this */
		{
			/* no props */
			if (kw != NULL) {
				PyErr_Format(PyExc_AttributeError,
				             "Operator \"%s\" does not take any args",
				             opname);
				return NULL;
			}

			WM_operator_name_call(C, opname, WM_OP_EXEC_DEFAULT, NULL);
		}
#endif
	}

	/* restore with original context dict, probably NULL but need this for nested operator calls */
	Py_XDECREF(context_dict);
	CTX_py_dict_set(C, (void *)context_dict_back);

	if (error_val == -1) {
		return NULL;
	}

	/* when calling  bpy.ops.wm.read_factory_settings() bpy.data's main pointer is freed by clear_globals(),
	 * further access will crash blender. setting context is not needed in this case, only calling because this
	 * function corrects bpy.data (internal Main pointer) */
	BPY_modules_update(C);

	/* needed for when WM_OT_read_factory_settings us called from within a script */
	bpy_import_main_set(CTX_data_main(C));

	/* return operator_ret as a bpy enum */
	return pyrna_enum_bitfield_to_py(operator_return_items, operator_ret);

}