static bool eyedropper_init(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Eyedropper *eye; op->customdata = eye = MEM_callocN(sizeof(Eyedropper), "Eyedropper"); UI_context_active_but_prop_get(C, &eye->ptr, &eye->prop, &eye->index); if ((eye->ptr.data == NULL) || (eye->prop == NULL) || (RNA_property_editable(&eye->ptr, eye->prop) == false) || (RNA_property_array_length(&eye->ptr, eye->prop) < 3) || (RNA_property_type(eye->prop) != PROP_FLOAT)) { return false; } if (RNA_property_subtype(eye->prop) == PROP_COLOR) { const char *display_device; float col[4]; display_device = scene->display_settings.display_device; eye->display = IMB_colormanagement_display_get_named(display_device); /* store inital color */ RNA_property_float_get_array(&eye->ptr, eye->prop, col); if (eye->display) { IMB_colormanagement_scene_linear_to_display_v3(col, eye->display); } copy_v3_v3(eye->init_col, col); } return true; }
/* sets the sample color RGB, maintaining A */ static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[3]) { float col_conv[4]; /* to maintain alpha */ RNA_property_float_get_array(&eye->ptr, eye->prop, col_conv); /* convert from display space to linear rgb space */ if (eye->display) { copy_v3_v3(col_conv, col); IMB_colormanagement_display_to_scene_linear_v3(col_conv, eye->display); } else { copy_v3_v3(col_conv, col); } RNA_property_float_set_array(&eye->ptr, eye->prop, col_conv); RNA_property_update(C, &eye->ptr, eye->prop); }
static void eyedropper_sample(bContext *C, Eyedropper *eye, int mx, int my) { if(RNA_property_type(eye->prop) == PROP_FLOAT) { const int color_manage = CTX_data_scene(C)->r.color_mgt_flag & R_COLOR_MANAGEMENT; float col[4]; RNA_property_float_get_array(&eye->ptr, eye->prop, col); glReadBuffer(GL_FRONT); glReadPixels(mx, my, 1, 1, GL_RGB, GL_FLOAT, col); glReadBuffer(GL_BACK); if (RNA_property_array_length(&eye->ptr, eye->prop) < 3) return; /* convert from screen (srgb) space to linear rgb space */ if (color_manage && RNA_property_subtype(eye->prop) == PROP_COLOR) srgb_to_linearrgb_v3_v3(col, col); RNA_property_float_set_array(&eye->ptr, eye->prop, col); RNA_property_update(C, &eye->ptr, eye->prop); } }
static int object_warp_verts_exec(bContext *C, wmOperator *op) { const float warp_angle = RNA_float_get(op->ptr, "warp_angle"); const float offset_angle = RNA_float_get(op->ptr, "offset_angle"); TransVertStore tvs = {NULL}; Object *obedit = CTX_data_edit_object(C); /* typically from 'rv3d' and 3d cursor */ float viewmat[4][4]; float center[3]; /* 'viewmat' relative vars */ float mat_view[4][4]; float center_view[3]; float min, max; ED_transverts_create_from_obedit(&tvs, obedit, TM_ALL_JOINTS | TM_SKIP_HANDLES); if (tvs.transverts == NULL) { return OPERATOR_CANCELLED; } /* get viewmatrix */ { PropertyRNA *prop_viewmat = RNA_struct_find_property(op->ptr, "viewmat"); if (RNA_property_is_set(op->ptr, prop_viewmat)) { RNA_property_float_get_array(op->ptr, prop_viewmat, (float *)viewmat); } else { RegionView3D *rv3d = CTX_wm_region_view3d(C); if (rv3d) { copy_m4_m4(viewmat, rv3d->viewmat); } else { unit_m4(viewmat); } RNA_property_float_set_array(op->ptr, prop_viewmat, (float *)viewmat); } } /* get center */ { PropertyRNA *prop_center = RNA_struct_find_property(op->ptr, "center"); if (RNA_property_is_set(op->ptr, prop_center)) { RNA_property_float_get_array(op->ptr, prop_center, center); } else { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); const float *cursor; cursor = ED_view3d_cursor3d_get(scene, v3d); copy_v3_v3(center, cursor); RNA_property_float_set_array(op->ptr, prop_center, center); } } object_warp_calc_view_matrix(mat_view, center_view, obedit, viewmat, center, offset_angle); /* get minmax */ { PropertyRNA *prop_min = RNA_struct_find_property(op->ptr, "min"); PropertyRNA *prop_max = RNA_struct_find_property(op->ptr, "max"); if (RNA_property_is_set(op->ptr, prop_min) || RNA_property_is_set(op->ptr, prop_max)) { min = RNA_property_float_get(op->ptr, prop_min); max = RNA_property_float_get(op->ptr, prop_max); } else { /* handy to set the bounds of the mesh */ object_warp_transverts_minmax_x(&tvs, mat_view, center_view, &min, &max); RNA_property_float_set(op->ptr, prop_min, min); RNA_property_float_set(op->ptr, prop_max, max); } if (min > max) { SWAP(float, min, max); } } if (min != max) { object_warp_transverts(&tvs, mat_view, center_view, warp_angle, min, max); } ED_transverts_update_obedit(&tvs, obedit); ED_transverts_free(&tvs); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit); return OPERATOR_FINISHED; }
/* TODO, multi-dimensional arrays */ int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value) { int len = RNA_property_array_length(ptr, prop); int type; int i; if (len == 0) /* possible with dynamic arrays */ return 0; if (RNA_property_array_dimension(ptr, prop, NULL) > 1) { PyErr_SetString(PyExc_TypeError, "PropertyRNA - multi dimensional arrays not supported yet"); return -1; } type = RNA_property_type(prop); switch (type) { case PROP_FLOAT: { float value_f = PyFloat_AsDouble(value); if (value_f == -1 && PyErr_Occurred()) { PyErr_Clear(); return 0; } else { float tmp[32]; float *tmp_arr; if (len * sizeof(float) > sizeof(tmp)) { tmp_arr = PyMem_MALLOC(len * sizeof(float)); } else { tmp_arr = tmp; } RNA_property_float_get_array(ptr, prop, tmp_arr); for (i = 0; i < len; i++) { if (tmp_arr[i] == value_f) { break; } } if (tmp_arr != tmp) PyMem_FREE(tmp_arr); return i < len ? 1 : 0; } break; } case PROP_BOOLEAN: case PROP_INT: { int value_i = PyLong_AsSsize_t(value); if (value_i == -1 && PyErr_Occurred()) { PyErr_Clear(); return 0; } else { int tmp[32]; int *tmp_arr; if (len * sizeof(int) > sizeof(tmp)) { tmp_arr = PyMem_MALLOC(len * sizeof(int)); } else { tmp_arr = tmp; } if (type == PROP_BOOLEAN) RNA_property_boolean_get_array(ptr, prop, tmp_arr); else RNA_property_int_get_array(ptr, prop, tmp_arr); for (i = 0; i < len; i++) { if (tmp_arr[i] == value_i) { break; } } if (tmp_arr != tmp) PyMem_FREE(tmp_arr); return i < len ? 1 : 0; } break; } } /* should never reach this */ PyErr_SetString(PyExc_TypeError, "PropertyRNA - type not in float/bool/int"); return -1; }
static int mesh_bisect_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); /* both can be NULL, fallbacks values are used */ View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = ED_view3d_context_rv3d(C); Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm; BMOperator bmop; float plane_co[3]; float plane_no[3]; float imat[4][4]; const float thresh = RNA_float_get(op->ptr, "threshold"); const bool use_fill = RNA_boolean_get(op->ptr, "use_fill"); const bool clear_inner = RNA_boolean_get(op->ptr, "clear_inner"); const bool clear_outer = RNA_boolean_get(op->ptr, "clear_outer"); PropertyRNA *prop_plane_co; PropertyRNA *prop_plane_no; prop_plane_co = RNA_struct_find_property(op->ptr, "plane_co"); if (RNA_property_is_set(op->ptr, prop_plane_co)) { RNA_property_float_get_array(op->ptr, prop_plane_co, plane_co); } else { copy_v3_v3(plane_co, ED_view3d_cursor3d_get(scene, v3d)); RNA_property_float_set_array(op->ptr, prop_plane_co, plane_co); } prop_plane_no = RNA_struct_find_property(op->ptr, "plane_no"); if (RNA_property_is_set(op->ptr, prop_plane_no)) { RNA_property_float_get_array(op->ptr, prop_plane_no, plane_no); } else { if (rv3d) { copy_v3_v3(plane_no, rv3d->viewinv[1]); } else { /* fallback... */ plane_no[0] = plane_no[1] = 0.0f; plane_no[2] = 1.0f; } RNA_property_float_set_array(op->ptr, prop_plane_no, plane_no); } /* -------------------------------------------------------------------- */ /* Modal support */ /* Note: keep this isolated, exec can work wihout this */ if ((op->customdata != NULL) && mesh_bisect_interactive_calc(C, op, em, plane_co, plane_no)) { /* write back to the props */ RNA_property_float_set_array(op->ptr, prop_plane_no, plane_no); RNA_property_float_set_array(op->ptr, prop_plane_co, plane_co); } /* End Modal */ /* -------------------------------------------------------------------- */ bm = em->bm; invert_m4_m4(imat, obedit->obmat); mul_m4_v3(imat, plane_co); mul_mat3_m4_v3(imat, plane_no); EDBM_op_init(em, &bmop, op, "bisect_plane geom=%hvef plane_co=%v plane_no=%v dist=%f clear_inner=%b clear_outer=%b", BM_ELEM_SELECT, plane_co, plane_no, thresh, clear_inner, clear_outer); BMO_op_exec(bm, &bmop); EDBM_flag_disable_all(em, BM_ELEM_SELECT); if (use_fill) { float normal_fill[3]; BMOperator bmop_fill; BMOperator bmop_attr; normalize_v3_v3(normal_fill, plane_no); if (clear_outer == true && clear_inner == false) { negate_v3(normal_fill); } /* Fill */ BMO_op_initf( bm, &bmop_fill, op->flag, "triangle_fill edges=%S normal=%v use_dissolve=%b", &bmop, "geom_cut.out", normal_fill, true); BMO_op_exec(bm, &bmop_fill); /* Copy Attributes */ BMO_op_initf(bm, &bmop_attr, op->flag, "face_attribute_fill faces=%S use_normals=%b use_data=%b", &bmop_fill, "geom.out", false, true); BMO_op_exec(bm, &bmop_attr); BMO_slot_buffer_hflag_enable(bm, bmop_fill.slots_out, "geom.out", BM_FACE, BM_ELEM_SELECT, true); BMO_op_finish(bm, &bmop_attr); BMO_op_finish(bm, &bmop_fill); } BMO_slot_buffer_hflag_enable(bm, bmop.slots_out, "geom_cut.out", BM_VERT | BM_EDGE, BM_ELEM_SELECT, true); if (!EDBM_op_finish(em, &bmop, op, true)) { return OPERATOR_CANCELLED; } else { EDBM_update_generic(em, true, true); EDBM_selectmode_flush(em); return OPERATOR_FINISHED; } }