Merge branch 'master' into temp_bmesh_multires
This commit is contained in:
commit
f0c35d16f3
|
@ -231,7 +231,7 @@ const UserDef U_default = {
|
|||
.collection_instance_empty_size = 1.0f,
|
||||
|
||||
.statusbar_flag = STATUSBAR_SHOW_VERSION,
|
||||
.file_preview_type = USER_FILE_PREVIEW_CAMERA,
|
||||
.file_preview_type = USER_FILE_PREVIEW_AUTO,
|
||||
|
||||
.runtime =
|
||||
{
|
||||
|
|
|
@ -63,16 +63,11 @@ def kmi_args_as_data(kmi):
|
|||
if kmi.any:
|
||||
s.append("\"any\": True")
|
||||
else:
|
||||
if kmi.shift:
|
||||
s.append("\"shift\": True")
|
||||
if kmi.ctrl:
|
||||
s.append("\"ctrl\": True")
|
||||
if kmi.alt:
|
||||
s.append("\"alt\": True")
|
||||
if kmi.oskey:
|
||||
s.append("\"oskey\": True")
|
||||
if kmi.key_modifier and kmi.key_modifier != 'NONE':
|
||||
s.append(f"\"key_modifier\": '{kmi.key_modifier}'")
|
||||
for attr in ("shift", "ctrl", "alt", "oskey"):
|
||||
if mod := getattr(kmi, attr):
|
||||
s.append(f"\"{attr:s}\": " + ("-1" if mod == -1 else "True"))
|
||||
if (mod := kmi.key_modifier) and (mod != 'NONE'):
|
||||
s.append(f"\"key_modifier\": '{mod:s}'")
|
||||
|
||||
if kmi.repeat:
|
||||
if (
|
||||
|
|
|
@ -199,10 +199,12 @@ def draw_kmi(display_keymaps, kc, km, kmi, layout, level):
|
|||
subrow = sub.row()
|
||||
subrow.scale_x = 0.75
|
||||
subrow.prop(kmi, "any", toggle=True)
|
||||
subrow.prop(kmi, "shift", toggle=True)
|
||||
subrow.prop(kmi, "ctrl", toggle=True)
|
||||
subrow.prop(kmi, "alt", toggle=True)
|
||||
subrow.prop(kmi, "oskey", text="Cmd", toggle=True)
|
||||
# Use `*_ui` properties as integers aren't practical.
|
||||
subrow.prop(kmi, "shift_ui", toggle=True)
|
||||
subrow.prop(kmi, "ctrl_ui", toggle=True)
|
||||
subrow.prop(kmi, "alt_ui", toggle=True)
|
||||
subrow.prop(kmi, "oskey_ui", text="Cmd", toggle=True)
|
||||
|
||||
subrow.prop(kmi, "key_modifier", text="", event=True)
|
||||
|
||||
# Operator properties
|
||||
|
|
|
@ -417,6 +417,7 @@ class MASK_MT_select(Menu):
|
|||
|
||||
layout.operator("mask.select_box")
|
||||
layout.operator("mask.select_circle")
|
||||
layout.operator_menu_enum("mask.select_lasso", "mode")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
|
|
@ -1578,6 +1578,7 @@ class CLIP_MT_select(Menu):
|
|||
|
||||
layout.operator("clip.select_box")
|
||||
layout.operator("clip.select_circle")
|
||||
layout.operator_menu_enum("clip.select_lasso", "mode")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
|
|
@ -394,6 +394,7 @@ class DOPESHEET_MT_select(Menu):
|
|||
layout.operator("action.select_box", text="Box Select (Axis Range)").axis_range = True
|
||||
|
||||
layout.operator("action.select_circle")
|
||||
layout.operator_menu_enum("action.select_lasso", "mode")
|
||||
|
||||
layout.separator()
|
||||
layout.operator("action.select_column", text="Columns on Selected Keys").mode = 'KEYS'
|
||||
|
|
|
@ -179,6 +179,7 @@ class GRAPH_MT_select(Menu):
|
|||
props.include_handles = True
|
||||
|
||||
layout.operator("graph.select_circle")
|
||||
layout.operator_menu_enum("graph.select_lasso", "mode")
|
||||
|
||||
layout.separator()
|
||||
layout.operator("graph.select_column", text="Columns on Selected Keys").mode = 'KEYS'
|
||||
|
|
|
@ -289,6 +289,7 @@ class NODE_MT_select(Menu):
|
|||
|
||||
layout.operator("node.select_box").tweak = False
|
||||
layout.operator("node.select_circle")
|
||||
layout.operator_menu_enum("node.select_lasso", "mode")
|
||||
|
||||
layout.separator()
|
||||
layout.operator("node.select_all").action = 'TOGGLE'
|
||||
|
|
|
@ -655,6 +655,7 @@ class TOPBAR_MT_window(Menu):
|
|||
layout.separator()
|
||||
|
||||
layout.operator("screen.screenshot")
|
||||
layout.operator("screen.screenshot_area")
|
||||
|
||||
if sys.platform[:3] == "win":
|
||||
layout.separator()
|
||||
|
|
|
@ -1363,6 +1363,7 @@ class VIEW3D_MT_select_object(Menu):
|
|||
|
||||
layout.operator("view3d.select_box")
|
||||
layout.operator("view3d.select_circle")
|
||||
layout.operator_menu_enum("view3d.select_lasso", "mode")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -1423,6 +1424,7 @@ class VIEW3D_MT_select_pose(Menu):
|
|||
|
||||
layout.operator("view3d.select_box")
|
||||
layout.operator("view3d.select_circle")
|
||||
layout.operator_menu_enum("view3d.select_lasso", "mode")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -1457,6 +1459,7 @@ class VIEW3D_MT_select_particle(Menu):
|
|||
|
||||
layout.operator("view3d.select_box")
|
||||
layout.operator("view3d.select_circle")
|
||||
layout.operator_menu_enum("view3d.select_lasso", "mode")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -1563,6 +1566,7 @@ class VIEW3D_MT_select_edit_mesh(Menu):
|
|||
|
||||
layout.operator("view3d.select_box")
|
||||
layout.operator("view3d.select_circle")
|
||||
layout.operator_menu_enum("view3d.select_lasso", "mode")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -1616,6 +1620,7 @@ class VIEW3D_MT_select_edit_curve(Menu):
|
|||
|
||||
layout.operator("view3d.select_box")
|
||||
layout.operator("view3d.select_circle")
|
||||
layout.operator_menu_enum("view3d.select_lasso", "mode")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -1651,6 +1656,7 @@ class VIEW3D_MT_select_edit_surface(Menu):
|
|||
|
||||
layout.operator("view3d.select_box")
|
||||
layout.operator("view3d.select_circle")
|
||||
layout.operator_menu_enum("view3d.select_lasso", "mode")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -1712,6 +1718,7 @@ class VIEW3D_MT_select_edit_metaball(Menu):
|
|||
|
||||
layout.operator("view3d.select_box")
|
||||
layout.operator("view3d.select_circle")
|
||||
layout.operator_menu_enum("view3d.select_lasso", "mode")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -1753,6 +1760,7 @@ class VIEW3D_MT_select_edit_lattice(Menu):
|
|||
|
||||
layout.operator("view3d.select_box")
|
||||
layout.operator("view3d.select_circle")
|
||||
layout.operator_menu_enum("view3d.select_lasso", "mode")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -1783,6 +1791,7 @@ class VIEW3D_MT_select_edit_armature(Menu):
|
|||
|
||||
layout.operator("view3d.select_box")
|
||||
layout.operator("view3d.select_circle")
|
||||
layout.operator_menu_enum("view3d.select_lasso", "mode")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -1850,6 +1859,7 @@ class VIEW3D_MT_select_gpencil(Menu):
|
|||
|
||||
layout.operator("gpencil.select_box")
|
||||
layout.operator("gpencil.select_circle")
|
||||
layout.operator_menu_enum("gpencil.select_lasso", "mode")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -1886,6 +1896,7 @@ class VIEW3D_MT_select_paint_mask(Menu):
|
|||
|
||||
layout.operator("view3d.select_box")
|
||||
layout.operator("view3d.select_circle")
|
||||
layout.operator_menu_enum("view3d.select_lasso", "mode")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -1906,6 +1917,7 @@ class VIEW3D_MT_select_paint_mask_vertex(Menu):
|
|||
|
||||
layout.operator("view3d.select_box")
|
||||
layout.operator("view3d.select_circle")
|
||||
layout.operator_menu_enum("view3d.select_lasso", "mode")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -3984,6 +3996,7 @@ class VIEW3D_MT_edit_mesh_vertices(Menu):
|
|||
layout.operator_context = 'INVOKE_REGION_WIN'
|
||||
|
||||
layout.operator("mesh.extrude_vertices_move", text="Extrude Vertices")
|
||||
layout.operator("mesh.dupli_extrude_cursor").rotate_source = True
|
||||
layout.operator("mesh.bevel", text="Bevel Vertices").affect = 'VERTICES'
|
||||
|
||||
layout.separator()
|
||||
|
@ -4415,6 +4428,7 @@ class VIEW3D_MT_edit_curve_ctrlpoints(Menu):
|
|||
|
||||
if edit_object.type in {'CURVE', 'SURFACE'}:
|
||||
layout.operator("curve.extrude_move")
|
||||
layout.operator("curve.vertex_add")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -4743,6 +4757,7 @@ class VIEW3D_MT_edit_armature(Menu):
|
|||
layout.separator()
|
||||
|
||||
layout.operator("armature.extrude_move")
|
||||
layout.operator("armature.click_extrude")
|
||||
|
||||
if arm.use_mirror_x:
|
||||
layout.operator("armature.extrude_forked")
|
||||
|
|
|
@ -500,8 +500,8 @@ geometry_node_categories = [
|
|||
NodeItem("GeometryNodeLegacyAttributeSeparateXYZ", poll=geometry_nodes_fields_legacy_poll),
|
||||
NodeItem("GeometryNodeLegacyAttributeMapRange", poll=geometry_nodes_fields_legacy_poll),
|
||||
NodeItem("GeometryNodeLegacyAttributeTransfer", poll=geometry_nodes_fields_legacy_poll),
|
||||
NodeItem("GeometryNodeAttributeRemove", poll=geometry_nodes_fields_legacy_poll),
|
||||
|
||||
NodeItem("GeometryNodeAttributeRemove"),
|
||||
NodeItem("GeometryNodeAttributeCapture", poll=geometry_nodes_fields_poll),
|
||||
]),
|
||||
GeometryNodeCategory("GEO_COLOR", "Color", items=[
|
||||
|
|
|
@ -92,6 +92,7 @@ set(SRC_DNA_INC
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_texture_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_tracking_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_userdef_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_uuid_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_vec_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_vfont_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_view2d_types.h
|
||||
|
|
|
@ -124,7 +124,7 @@ void BKE_mesh_eval_delete(struct Mesh *mesh_eval);
|
|||
|
||||
/* Performs copy for use during evaluation,
|
||||
* optional referencing original arrays to reduce memory. */
|
||||
struct Mesh *BKE_mesh_copy_for_eval(struct Mesh *source, bool reference);
|
||||
struct Mesh *BKE_mesh_copy_for_eval(const struct Mesh *source, bool reference);
|
||||
|
||||
/* These functions construct a new Mesh,
|
||||
* contrary to BKE_mesh_to_curve_nurblist which modifies ob itself. */
|
||||
|
|
|
@ -187,7 +187,7 @@ set(SRC
|
|||
intern/mball_tessellate.c
|
||||
intern/mesh.c
|
||||
intern/mesh_boolean_convert.cc
|
||||
intern/mesh_convert.c
|
||||
intern/mesh_convert.cc
|
||||
intern/mesh_evaluate.cc
|
||||
intern/mesh_fair.cc
|
||||
intern/mesh_iterators.c
|
||||
|
|
|
@ -1321,7 +1321,9 @@ const GVArray *AttributeFieldInput::get_varray_for_context(const fn::FieldContex
|
|||
const AttributeDomain domain = geometry_context->domain();
|
||||
const CustomDataType data_type = cpp_type_to_custom_data_type(*type_);
|
||||
GVArrayPtr attribute = component.attribute_try_get_for_read(name_, domain, data_type);
|
||||
return scope.add(std::move(attribute));
|
||||
if (attribute) {
|
||||
return scope.add(std::move(attribute));
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -1504,7 +1504,7 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph,
|
|||
cow_curve.curve_eval = nullptr;
|
||||
|
||||
ob->runtime.curve_cache = (CurveCache *)MEM_callocN(sizeof(CurveCache), __func__);
|
||||
ListBase *dispbase = &(ob->runtime.curve_cache->disp);
|
||||
ListBase *dispbase = &ob->runtime.curve_cache->disp;
|
||||
|
||||
if (ob->type == OB_SURF) {
|
||||
Mesh *mesh_eval;
|
||||
|
|
|
@ -1419,17 +1419,19 @@ static float eval_fmodifier_influence(FModifier *fcm, float evaltime)
|
|||
|
||||
/* restricted range or full range? */
|
||||
if (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) {
|
||||
if ((evaltime <= fcm->sfra) || (evaltime >= fcm->efra)) {
|
||||
if ((evaltime < fcm->sfra) || (evaltime > fcm->efra)) {
|
||||
/* out of range */
|
||||
return 0.0f;
|
||||
}
|
||||
if ((evaltime > fcm->sfra) && (evaltime < fcm->sfra + fcm->blendin)) {
|
||||
if ((fcm->blendin != 0.0f) && (evaltime >= fcm->sfra) &&
|
||||
(evaltime <= fcm->sfra + fcm->blendin)) {
|
||||
/* blend in range */
|
||||
float a = fcm->sfra;
|
||||
float b = fcm->sfra + fcm->blendin;
|
||||
return influence * (evaltime - a) / (b - a);
|
||||
}
|
||||
if ((evaltime < fcm->efra) && (evaltime > fcm->efra - fcm->blendout)) {
|
||||
if ((fcm->blendout != 0.0f) && (evaltime <= fcm->efra) &&
|
||||
(evaltime >= fcm->efra - fcm->blendout)) {
|
||||
/* blend out range */
|
||||
float a = fcm->efra;
|
||||
float b = fcm->efra - fcm->blendout;
|
||||
|
|
|
@ -3063,13 +3063,12 @@ void BKE_gpencil_update_layer_transforms(const Depsgraph *depsgraph, Object *ob)
|
|||
Object *ob_parent = DEG_get_evaluated_object(depsgraph, gpl->parent);
|
||||
/* calculate new matrix */
|
||||
if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
|
||||
copy_m4_m4(cur_mat, ob_parent->obmat);
|
||||
mul_m4_m4m4(cur_mat, ob->imat, ob_parent->obmat);
|
||||
}
|
||||
else if (gpl->partype == PARBONE) {
|
||||
bPoseChannel *pchan = BKE_pose_channel_find_name(ob_parent->pose, gpl->parsubstr);
|
||||
if (pchan != NULL) {
|
||||
copy_m4_m4(cur_mat, ob->imat);
|
||||
mul_m4_m4m4(cur_mat, ob_parent->obmat, pchan->pose_mat);
|
||||
mul_m4_series(cur_mat, ob->imat, ob_parent->obmat, pchan->pose_mat);
|
||||
}
|
||||
else {
|
||||
unit_m4(cur_mat);
|
||||
|
|
|
@ -633,12 +633,6 @@ void BKE_previewimg_blend_write(BlendWriter *writer, const PreviewImage *prv)
|
|||
}
|
||||
|
||||
PreviewImage prv_copy = *prv;
|
||||
/* don't write out large previews if not requested */
|
||||
if (U.file_preview_type == USER_FILE_PREVIEW_NONE) {
|
||||
prv_copy.w[1] = 0;
|
||||
prv_copy.h[1] = 0;
|
||||
prv_copy.rect[1] = nullptr;
|
||||
}
|
||||
BLO_write_struct_at_address(writer, PreviewImage, prv, &prv_copy);
|
||||
if (prv_copy.rect[0]) {
|
||||
BLO_write_uint32_array(writer, prv_copy.w[0] * prv_copy.h[0], prv_copy.rect[0]);
|
||||
|
|
|
@ -1111,7 +1111,7 @@ void BKE_mesh_eval_delete(struct Mesh *mesh_eval)
|
|||
MEM_freeN(mesh_eval);
|
||||
}
|
||||
|
||||
Mesh *BKE_mesh_copy_for_eval(struct Mesh *source, bool reference)
|
||||
Mesh *BKE_mesh_copy_for_eval(const Mesh *source, bool reference)
|
||||
{
|
||||
int flags = LIB_ID_COPY_LOCALIZE;
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
|
||||
#ifdef VALIDATE_MESH
|
||||
# define ASSERT_IS_VALID_MESH(mesh) \
|
||||
(BLI_assert((mesh == NULL) || (BKE_mesh_is_valid(mesh) == true)))
|
||||
(BLI_assert((mesh == nullptr) || (BKE_mesh_is_valid(mesh) == true)))
|
||||
#else
|
||||
# define ASSERT_IS_VALID_MESH(mesh)
|
||||
#endif
|
||||
|
@ -84,15 +84,16 @@ void BKE_mesh_from_metaball(ListBase *lb, Mesh *me)
|
|||
const float *nors, *verts;
|
||||
int a, *index;
|
||||
|
||||
dl = lb->first;
|
||||
if (dl == NULL) {
|
||||
dl = (DispList *)lb->first;
|
||||
if (dl == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dl->type == DL_INDEX4) {
|
||||
mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, dl->nr);
|
||||
allloop = mloop = CustomData_add_layer(&me->ldata, CD_MLOOP, CD_CALLOC, NULL, dl->parts * 4);
|
||||
mpoly = CustomData_add_layer(&me->pdata, CD_MPOLY, CD_CALLOC, NULL, dl->parts);
|
||||
mvert = (MVert *)CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, nullptr, dl->nr);
|
||||
allloop = mloop = (MLoop *)CustomData_add_layer(
|
||||
&me->ldata, CD_MLOOP, CD_CALLOC, nullptr, dl->parts * 4);
|
||||
mpoly = (MPoly *)CustomData_add_layer(&me->pdata, CD_MPOLY, CD_CALLOC, nullptr, dl->parts);
|
||||
me->mvert = mvert;
|
||||
me->mloop = mloop;
|
||||
me->mpoly = mpoly;
|
||||
|
@ -177,9 +178,10 @@ static void make_edges_mdata_extend(
|
|||
MEdge *medge;
|
||||
uint e_index = totedge;
|
||||
|
||||
*r_alledge = medge = (*r_alledge ?
|
||||
MEM_reallocN(*r_alledge, sizeof(MEdge) * (totedge + totedge_new)) :
|
||||
MEM_calloc_arrayN(totedge_new, sizeof(MEdge), __func__));
|
||||
*r_alledge = medge = (MEdge *)(*r_alledge ?
|
||||
MEM_reallocN(*r_alledge,
|
||||
sizeof(MEdge) * (totedge + totedge_new)) :
|
||||
MEM_calloc_arrayN(totedge_new, sizeof(MEdge), __func__));
|
||||
medge += totedge;
|
||||
|
||||
totedge += totedge_new;
|
||||
|
@ -209,7 +211,7 @@ static void make_edges_mdata_extend(
|
|||
}
|
||||
}
|
||||
|
||||
BLI_edgehash_free(eh, NULL);
|
||||
BLI_edgehash_free(eh, nullptr);
|
||||
}
|
||||
|
||||
/* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */
|
||||
|
@ -229,7 +231,7 @@ static int mesh_nurbs_displist_to_mdata(const Curve *cu,
|
|||
MVert *mvert;
|
||||
MPoly *mpoly;
|
||||
MLoop *mloop;
|
||||
MLoopUV *mloopuv = NULL;
|
||||
MLoopUV *mloopuv = nullptr;
|
||||
MEdge *medge;
|
||||
const float *data;
|
||||
int a, b, ofs, vertcount, startvert, totvert = 0, totedge = 0, totloop = 0, totpoly = 0;
|
||||
|
@ -277,14 +279,15 @@ static int mesh_nurbs_displist_to_mdata(const Curve *cu,
|
|||
return -1;
|
||||
}
|
||||
|
||||
*r_allvert = mvert = MEM_calloc_arrayN(totvert, sizeof(MVert), "nurbs_init mvert");
|
||||
*r_alledge = medge = MEM_calloc_arrayN(totedge, sizeof(MEdge), "nurbs_init medge");
|
||||
*r_allloop = mloop = MEM_calloc_arrayN(
|
||||
*r_allvert = mvert = (MVert *)MEM_calloc_arrayN(totvert, sizeof(MVert), "nurbs_init mvert");
|
||||
*r_alledge = medge = (MEdge *)MEM_calloc_arrayN(totedge, sizeof(MEdge), "nurbs_init medge");
|
||||
*r_allloop = mloop = (MLoop *)MEM_calloc_arrayN(
|
||||
totpoly, sizeof(MLoop[4]), "nurbs_init mloop"); /* totloop */
|
||||
*r_allpoly = mpoly = MEM_calloc_arrayN(totpoly, sizeof(MPoly), "nurbs_init mloop");
|
||||
*r_allpoly = mpoly = (MPoly *)MEM_calloc_arrayN(totpoly, sizeof(MPoly), "nurbs_init mloop");
|
||||
|
||||
if (r_alluv) {
|
||||
*r_alluv = mloopuv = MEM_calloc_arrayN(totpoly, sizeof(MLoopUV[4]), "nurbs_init mloopuv");
|
||||
*r_alluv = mloopuv = (MLoopUV *)MEM_calloc_arrayN(
|
||||
totpoly, sizeof(MLoopUV[4]), "nurbs_init mloopuv");
|
||||
}
|
||||
|
||||
/* verts and faces */
|
||||
|
@ -500,13 +503,13 @@ static void mesh_copy_texture_space_from_curve_type(const Curve *cu, Mesh *me)
|
|||
|
||||
Mesh *BKE_mesh_new_nomain_from_curve_displist(const Object *ob, const ListBase *dispbase)
|
||||
{
|
||||
const Curve *cu = ob->data;
|
||||
const Curve *cu = (const Curve *)ob->data;
|
||||
Mesh *mesh;
|
||||
MVert *allvert;
|
||||
MEdge *alledge;
|
||||
MLoop *allloop;
|
||||
MPoly *allpoly;
|
||||
MLoopUV *alluv = NULL;
|
||||
MLoopUV *alluv = nullptr;
|
||||
int totvert, totedge, totloop, totpoly;
|
||||
|
||||
if (mesh_nurbs_displist_to_mdata(cu,
|
||||
|
@ -561,7 +564,7 @@ Mesh *BKE_mesh_new_nomain_from_curve_displist(const Object *ob, const ListBase *
|
|||
|
||||
Mesh *BKE_mesh_new_nomain_from_curve(const Object *ob)
|
||||
{
|
||||
ListBase disp = {NULL, NULL};
|
||||
ListBase disp = {nullptr, nullptr};
|
||||
|
||||
if (ob->runtime.curve_cache) {
|
||||
disp = ob->runtime.curve_cache->disp;
|
||||
|
@ -578,16 +581,16 @@ static void mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const char
|
|||
|
||||
Mesh *me_eval = (Mesh *)ob->runtime.data_eval;
|
||||
Mesh *me;
|
||||
MVert *allvert = NULL;
|
||||
MEdge *alledge = NULL;
|
||||
MLoop *allloop = NULL;
|
||||
MLoopUV *alluv = NULL;
|
||||
MPoly *allpoly = NULL;
|
||||
MVert *allvert = nullptr;
|
||||
MEdge *alledge = nullptr;
|
||||
MLoop *allloop = nullptr;
|
||||
MLoopUV *alluv = nullptr;
|
||||
MPoly *allpoly = nullptr;
|
||||
int totvert, totedge, totloop, totpoly;
|
||||
|
||||
Curve *cu = ob->data;
|
||||
Curve *cu = (Curve *)ob->data;
|
||||
|
||||
if (me_eval == NULL) {
|
||||
if (me_eval == nullptr) {
|
||||
if (mesh_nurbs_displist_to_mdata(cu,
|
||||
dispbase,
|
||||
&allvert,
|
||||
|
@ -604,30 +607,34 @@ static void mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const char
|
|||
}
|
||||
|
||||
/* make mesh */
|
||||
me = BKE_id_new_nomain(ID_ME, obdata_name);
|
||||
me = (Mesh *)BKE_id_new_nomain(ID_ME, obdata_name);
|
||||
|
||||
me->totvert = totvert;
|
||||
me->totedge = totedge;
|
||||
me->totloop = totloop;
|
||||
me->totpoly = totpoly;
|
||||
|
||||
me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, allvert, me->totvert);
|
||||
me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, alledge, me->totedge);
|
||||
me->mloop = CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, allloop, me->totloop);
|
||||
me->mpoly = CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, allpoly, me->totpoly);
|
||||
me->mvert = (MVert *)CustomData_add_layer(
|
||||
&me->vdata, CD_MVERT, CD_ASSIGN, allvert, me->totvert);
|
||||
me->medge = (MEdge *)CustomData_add_layer(
|
||||
&me->edata, CD_MEDGE, CD_ASSIGN, alledge, me->totedge);
|
||||
me->mloop = (MLoop *)CustomData_add_layer(
|
||||
&me->ldata, CD_MLOOP, CD_ASSIGN, allloop, me->totloop);
|
||||
me->mpoly = (MPoly *)CustomData_add_layer(
|
||||
&me->pdata, CD_MPOLY, CD_ASSIGN, allpoly, me->totpoly);
|
||||
|
||||
if (alluv) {
|
||||
const char *uvname = "UVMap";
|
||||
me->mloopuv = CustomData_add_layer_named(
|
||||
me->mloopuv = (MLoopUV *)CustomData_add_layer_named(
|
||||
&me->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, me->totloop, uvname);
|
||||
}
|
||||
|
||||
BKE_mesh_calc_normals(me);
|
||||
}
|
||||
else {
|
||||
me = BKE_id_new_nomain(ID_ME, obdata_name);
|
||||
me = (Mesh *)BKE_id_new_nomain(ID_ME, obdata_name);
|
||||
|
||||
ob->runtime.data_eval = NULL;
|
||||
ob->runtime.data_eval = nullptr;
|
||||
BKE_mesh_nomain_to_mesh(me_eval, me, ob, &CD_MASK_MESH, true);
|
||||
}
|
||||
|
||||
|
@ -636,7 +643,7 @@ static void mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const char
|
|||
|
||||
mesh_copy_texture_space_from_curve_type(cu, me);
|
||||
|
||||
cu->mat = NULL;
|
||||
cu->mat = nullptr;
|
||||
cu->totcol = 0;
|
||||
|
||||
/* Do not decrement ob->data usercount here,
|
||||
|
@ -647,29 +654,29 @@ static void mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const char
|
|||
/* For temporary objects in BKE_mesh_new_from_object don't remap
|
||||
* the entire scene with associated depsgraph updates, which are
|
||||
* problematic for renderers exporting data. */
|
||||
BKE_id_free(NULL, cu);
|
||||
BKE_id_free(nullptr, cu);
|
||||
}
|
||||
|
||||
typedef struct EdgeLink {
|
||||
struct EdgeLink {
|
||||
struct EdgeLink *next, *prev;
|
||||
void *edge;
|
||||
} EdgeLink;
|
||||
};
|
||||
|
||||
typedef struct VertLink {
|
||||
struct VertLink {
|
||||
Link *next, *prev;
|
||||
uint index;
|
||||
} VertLink;
|
||||
};
|
||||
|
||||
static void prependPolyLineVert(ListBase *lb, uint index)
|
||||
{
|
||||
VertLink *vl = MEM_callocN(sizeof(VertLink), "VertLink");
|
||||
VertLink *vl = (VertLink *)MEM_callocN(sizeof(VertLink), "VertLink");
|
||||
vl->index = index;
|
||||
BLI_addhead(lb, vl);
|
||||
}
|
||||
|
||||
static void appendPolyLineVert(ListBase *lb, uint index)
|
||||
{
|
||||
VertLink *vl = MEM_callocN(sizeof(VertLink), "VertLink");
|
||||
VertLink *vl = (VertLink *)MEM_callocN(sizeof(VertLink), "VertLink");
|
||||
vl->index = index;
|
||||
BLI_addtail(lb, vl);
|
||||
}
|
||||
|
@ -689,10 +696,10 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed
|
|||
/* only to detect edge polylines */
|
||||
int *edge_users;
|
||||
|
||||
ListBase edges = {NULL, NULL};
|
||||
ListBase edges = {nullptr, nullptr};
|
||||
|
||||
/* get boundary edges */
|
||||
edge_users = MEM_calloc_arrayN(medge_len, sizeof(int), __func__);
|
||||
edge_users = (int *)MEM_calloc_arrayN(medge_len, sizeof(int), __func__);
|
||||
for (i = 0, mp = mpoly; i < mpoly_len; i++, mp++) {
|
||||
MLoop *ml = &mloop[mp->loopstart];
|
||||
int j;
|
||||
|
@ -705,7 +712,7 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed
|
|||
med = medge;
|
||||
for (i = 0; i < medge_len; i++, med++) {
|
||||
if (edge_users[i] == edge_users_test) {
|
||||
EdgeLink *edl = MEM_callocN(sizeof(EdgeLink), "EdgeLink");
|
||||
EdgeLink *edl = (EdgeLink *)MEM_callocN(sizeof(EdgeLink), "EdgeLink");
|
||||
edl->edge = med;
|
||||
|
||||
BLI_addtail(&edges, edl);
|
||||
|
@ -718,10 +725,10 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed
|
|||
while (edges.first) {
|
||||
/* each iteration find a polyline and add this as a nurbs poly spline */
|
||||
|
||||
ListBase polyline = {NULL, NULL}; /* store a list of VertLink's */
|
||||
ListBase polyline = {nullptr, nullptr}; /* store a list of VertLink's */
|
||||
bool closed = false;
|
||||
int totpoly = 0;
|
||||
MEdge *med_current = ((EdgeLink *)edges.last)->edge;
|
||||
MEdge *med_current = (MEdge *)((EdgeLink *)edges.last)->edge;
|
||||
uint startVert = med_current->v1;
|
||||
uint endVert = med_current->v2;
|
||||
bool ok = true;
|
||||
|
@ -734,12 +741,12 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed
|
|||
totedges--;
|
||||
|
||||
while (ok) { /* while connected edges are found... */
|
||||
EdgeLink *edl = edges.last;
|
||||
EdgeLink *edl = (EdgeLink *)edges.last;
|
||||
ok = false;
|
||||
while (edl) {
|
||||
EdgeLink *edl_prev = edl->prev;
|
||||
|
||||
med = edl->edge;
|
||||
med = (MEdge *)edl->edge;
|
||||
|
||||
if (med->v1 == endVert) {
|
||||
endVert = med->v2;
|
||||
|
@ -803,7 +810,7 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed
|
|||
nu->bp = (BPoint *)MEM_calloc_arrayN(totpoly, sizeof(BPoint), "bpoints");
|
||||
|
||||
/* add points */
|
||||
vl = polyline.first;
|
||||
vl = (VertLink *)polyline.first;
|
||||
for (i = 0, bp = nu->bp; i < totpoly; i++, bp++, vl = (VertLink *)vl->next) {
|
||||
copy_v3_v3(bp->vec, mvert[vl->index].co);
|
||||
bp->f1 = SELECT;
|
||||
|
@ -825,7 +832,7 @@ void BKE_mesh_to_curve(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(scene),
|
|||
Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
|
||||
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
|
||||
Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &CD_MASK_MESH);
|
||||
ListBase nurblist = {NULL, NULL};
|
||||
ListBase nurblist = {nullptr, nullptr};
|
||||
|
||||
BKE_mesh_to_curve_nurblist(me_eval, &nurblist, 0);
|
||||
BKE_mesh_to_curve_nurblist(me_eval, &nurblist, 1);
|
||||
|
@ -846,16 +853,13 @@ void BKE_mesh_to_curve(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(scene),
|
|||
|
||||
void BKE_pointcloud_from_mesh(Mesh *me, PointCloud *pointcloud)
|
||||
{
|
||||
BLI_assert(me != NULL);
|
||||
BLI_assert(me != nullptr);
|
||||
|
||||
pointcloud->totpoint = me->totvert;
|
||||
CustomData_realloc(&pointcloud->pdata, pointcloud->totpoint);
|
||||
|
||||
/* Copy over all attributes. */
|
||||
const CustomData_MeshMasks mask = {
|
||||
.vmask = CD_MASK_PROP_ALL,
|
||||
};
|
||||
CustomData_merge(&me->vdata, &pointcloud->pdata, mask.vmask, CD_DUPLICATE, me->totvert);
|
||||
CustomData_merge(&me->vdata, &pointcloud->pdata, CD_MASK_PROP_ALL, CD_DUPLICATE, me->totvert);
|
||||
BKE_pointcloud_update_customdata_pointers(pointcloud);
|
||||
CustomData_update_typemap(&pointcloud->pdata);
|
||||
|
||||
|
@ -874,7 +878,7 @@ void BKE_mesh_to_pointcloud(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(sce
|
|||
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
|
||||
Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &CD_MASK_MESH);
|
||||
|
||||
PointCloud *pointcloud = BKE_pointcloud_add(bmain, ob->id.name + 2);
|
||||
PointCloud *pointcloud = (PointCloud *)BKE_pointcloud_add(bmain, ob->id.name + 2);
|
||||
|
||||
BKE_pointcloud_from_mesh(me_eval, pointcloud);
|
||||
|
||||
|
@ -889,24 +893,22 @@ void BKE_mesh_to_pointcloud(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(sce
|
|||
|
||||
void BKE_mesh_from_pointcloud(const PointCloud *pointcloud, Mesh *me)
|
||||
{
|
||||
BLI_assert(pointcloud != NULL);
|
||||
BLI_assert(pointcloud != nullptr);
|
||||
|
||||
me->totvert = pointcloud->totpoint;
|
||||
|
||||
/* Merge over all attributes. */
|
||||
const CustomData_MeshMasks mask = {
|
||||
.vmask = CD_MASK_PROP_ALL,
|
||||
};
|
||||
CustomData_merge(&pointcloud->pdata, &me->vdata, mask.vmask, CD_DUPLICATE, pointcloud->totpoint);
|
||||
CustomData_merge(
|
||||
&pointcloud->pdata, &me->vdata, CD_MASK_PROP_ALL, CD_DUPLICATE, pointcloud->totpoint);
|
||||
|
||||
/* Convert the Position attribute to a mesh vertex. */
|
||||
me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert);
|
||||
me->mvert = (MVert *)CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, nullptr, me->totvert);
|
||||
CustomData_update_typemap(&me->vdata);
|
||||
|
||||
const int layer_idx = CustomData_get_named_layer_index(
|
||||
&me->vdata, CD_PROP_FLOAT3, POINTCLOUD_ATTR_POSITION);
|
||||
CustomDataLayer *pos_layer = &me->vdata.layers[layer_idx];
|
||||
float(*positions)[3] = pos_layer->data;
|
||||
float(*positions)[3] = (float(*)[3])pos_layer->data;
|
||||
|
||||
MVert *mvert;
|
||||
mvert = me->mvert;
|
||||
|
@ -956,7 +958,8 @@ static Object *object_for_curve_to_mesh_create(Object *object)
|
|||
Curve *curve = (Curve *)object->data;
|
||||
|
||||
/* Create object itself. */
|
||||
Object *temp_object = (Object *)BKE_id_copy_ex(NULL, &object->id, NULL, LIB_ID_COPY_LOCALIZE);
|
||||
Object *temp_object = (Object *)BKE_id_copy_ex(
|
||||
nullptr, &object->id, nullptr, LIB_ID_COPY_LOCALIZE);
|
||||
|
||||
/* Remove all modifiers, since we don't want them to be applied. */
|
||||
BKE_object_free_modifiers(temp_object, LIB_ID_CREATE_NO_USER_REFCOUNT);
|
||||
|
@ -965,26 +968,27 @@ static Object *object_for_curve_to_mesh_create(Object *object)
|
|||
*
|
||||
* Note that there are extra fields in there like bevel and path, but those are not needed during
|
||||
* conversion, so they are not copied to save unnecessary allocations. */
|
||||
if (temp_object->runtime.curve_cache == NULL) {
|
||||
temp_object->runtime.curve_cache = MEM_callocN(sizeof(CurveCache),
|
||||
"CurveCache for curve types");
|
||||
if (temp_object->runtime.curve_cache == nullptr) {
|
||||
temp_object->runtime.curve_cache = (CurveCache *)MEM_callocN(sizeof(CurveCache),
|
||||
"CurveCache for curve types");
|
||||
}
|
||||
|
||||
if (object->runtime.curve_cache != NULL) {
|
||||
if (object->runtime.curve_cache != nullptr) {
|
||||
BKE_displist_copy(&temp_object->runtime.curve_cache->disp, &object->runtime.curve_cache->disp);
|
||||
}
|
||||
|
||||
/* Constructive modifiers will use mesh to store result. */
|
||||
if (object->runtime.data_eval != NULL) {
|
||||
if (object->runtime.data_eval != nullptr) {
|
||||
BKE_id_copy_ex(
|
||||
NULL, object->runtime.data_eval, &temp_object->runtime.data_eval, LIB_ID_COPY_LOCALIZE);
|
||||
nullptr, object->runtime.data_eval, &temp_object->runtime.data_eval, LIB_ID_COPY_LOCALIZE);
|
||||
}
|
||||
|
||||
/* Need to create copy of curve itself as well, it will be freed by underlying conversion
|
||||
* functions.
|
||||
*
|
||||
* NOTE: Copies the data, but not the shapekeys. */
|
||||
BKE_id_copy_ex(NULL, object->data, (ID **)&temp_object->data, LIB_ID_COPY_LOCALIZE);
|
||||
BKE_id_copy_ex(
|
||||
nullptr, (const ID *)object->data, (ID **)&temp_object->data, LIB_ID_COPY_LOCALIZE);
|
||||
Curve *temp_curve = (Curve *)temp_object->data;
|
||||
|
||||
/* Make sure texture space is calculated for a copy of curve, it will be used for the final
|
||||
|
@ -1011,8 +1015,9 @@ static void curve_to_mesh_eval_ensure(Object *object)
|
|||
|
||||
remapped_object.data = &remapped_curve;
|
||||
|
||||
if (object->runtime.curve_cache == NULL) {
|
||||
object->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve");
|
||||
if (object->runtime.curve_cache == nullptr) {
|
||||
object->runtime.curve_cache = (CurveCache *)MEM_callocN(sizeof(CurveCache),
|
||||
"CurveCache for Curve");
|
||||
}
|
||||
|
||||
/* Temporarily share the curve-cache with the temporary object, owned by `object`. */
|
||||
|
@ -1025,8 +1030,8 @@ static void curve_to_mesh_eval_ensure(Object *object)
|
|||
*
|
||||
* So we create temporary copy of the object which will use same data as the original bevel, but
|
||||
* will have no modifiers. */
|
||||
Object bevel_object = {{NULL}};
|
||||
if (remapped_curve.bevobj != NULL) {
|
||||
Object bevel_object = {{nullptr}};
|
||||
if (remapped_curve.bevobj != nullptr) {
|
||||
bevel_object = *remapped_curve.bevobj;
|
||||
BLI_listbase_clear(&bevel_object.modifiers);
|
||||
BKE_object_runtime_reset(&bevel_object);
|
||||
|
@ -1034,34 +1039,34 @@ static void curve_to_mesh_eval_ensure(Object *object)
|
|||
}
|
||||
|
||||
/* Same thing for taper. */
|
||||
Object taper_object = {{NULL}};
|
||||
if (remapped_curve.taperobj != NULL) {
|
||||
Object taper_object = {{nullptr}};
|
||||
if (remapped_curve.taperobj != nullptr) {
|
||||
taper_object = *remapped_curve.taperobj;
|
||||
BLI_listbase_clear(&taper_object.modifiers);
|
||||
BKE_object_runtime_reset(&taper_object);
|
||||
remapped_curve.taperobj = &taper_object;
|
||||
}
|
||||
|
||||
/* NOTE: We don't have dependency graph or scene here, so we pass NULL. This is all fine since
|
||||
/* NOTE: We don't have dependency graph or scene here, so we pass nullptr. This is all fine since
|
||||
* they are only used for modifier stack, which we have explicitly disabled for all objects.
|
||||
*
|
||||
* TODO(sergey): This is a very fragile logic, but proper solution requires re-writing quite a
|
||||
* bit of internal functions (#mesh_from_nurbs_displist, BKE_mesh_nomain_to_mesh) and also
|
||||
* Mesh From Curve operator.
|
||||
* Brecht says hold off with that. */
|
||||
Mesh *mesh_eval = NULL;
|
||||
Mesh *mesh_eval = nullptr;
|
||||
BKE_displist_make_curveTypes_forRender(
|
||||
NULL, NULL, &remapped_object, &remapped_object.runtime.curve_cache->disp, &mesh_eval);
|
||||
nullptr, nullptr, &remapped_object, &remapped_object.runtime.curve_cache->disp, &mesh_eval);
|
||||
|
||||
/* NOTE: this is to be consistent with `BKE_displist_make_curveTypes()`, however that is not a
|
||||
* real issue currently, code here is broken in more than one way, fix(es) will be done
|
||||
* separately. */
|
||||
if (mesh_eval != NULL) {
|
||||
if (mesh_eval != nullptr) {
|
||||
BKE_object_eval_assign_data(&remapped_object, &mesh_eval->id, true);
|
||||
}
|
||||
|
||||
/* Owned by `object` & needed by the caller to create the mesh. */
|
||||
remapped_object.runtime.curve_cache = NULL;
|
||||
remapped_object.runtime.curve_cache = nullptr;
|
||||
|
||||
BKE_object_runtime_free_data(&remapped_object);
|
||||
BKE_object_runtime_free_data(&taper_object);
|
||||
|
@ -1070,7 +1075,7 @@ static void curve_to_mesh_eval_ensure(Object *object)
|
|||
|
||||
static Mesh *mesh_new_from_curve_type_object(Object *object)
|
||||
{
|
||||
Curve *curve = object->data;
|
||||
Curve *curve = (Curve *)object->data;
|
||||
Object *temp_object = object_for_curve_to_mesh_create(object);
|
||||
Curve *temp_curve = (Curve *)temp_object->data;
|
||||
|
||||
|
@ -1081,8 +1086,8 @@ static Mesh *mesh_new_from_curve_type_object(Object *object)
|
|||
}
|
||||
|
||||
/* Reset pointers before conversion. */
|
||||
temp_curve->editfont = NULL;
|
||||
temp_curve->editnurb = NULL;
|
||||
temp_curve->editfont = nullptr;
|
||||
temp_curve->editnurb = nullptr;
|
||||
|
||||
/* Convert to mesh. */
|
||||
mesh_from_nurbs_displist(
|
||||
|
@ -1091,14 +1096,14 @@ static Mesh *mesh_new_from_curve_type_object(Object *object)
|
|||
/* #mesh_from_nurbs_displist changes the type to a mesh, check it worked. If it didn't
|
||||
* the curve did not have any segments or otherwise would have generated an empty mesh. */
|
||||
if (temp_object->type != OB_MESH) {
|
||||
BKE_id_free(NULL, temp_object->data);
|
||||
BKE_id_free(NULL, temp_object);
|
||||
return NULL;
|
||||
BKE_id_free(nullptr, temp_object->data);
|
||||
BKE_id_free(nullptr, temp_object);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Mesh *mesh_result = temp_object->data;
|
||||
Mesh *mesh_result = (Mesh *)temp_object->data;
|
||||
|
||||
BKE_id_free(NULL, temp_object);
|
||||
BKE_id_free(nullptr, temp_object);
|
||||
|
||||
/* NOTE: Materials are copied in #mesh_from_nurbs_displist(). */
|
||||
|
||||
|
@ -1114,19 +1119,19 @@ static Mesh *mesh_new_from_mball_object(Object *object)
|
|||
* ball).
|
||||
*
|
||||
* We create empty mesh so scripters don't run into None objects. */
|
||||
if (!DEG_is_evaluated_object(object) || object->runtime.curve_cache == NULL ||
|
||||
if (!DEG_is_evaluated_object(object) || object->runtime.curve_cache == nullptr ||
|
||||
BLI_listbase_is_empty(&object->runtime.curve_cache->disp)) {
|
||||
return BKE_id_new_nomain(ID_ME, ((ID *)object->data)->name + 2);
|
||||
return (Mesh *)BKE_id_new_nomain(ID_ME, ((ID *)object->data)->name + 2);
|
||||
}
|
||||
|
||||
Mesh *mesh_result = BKE_id_new_nomain(ID_ME, ((ID *)object->data)->name + 2);
|
||||
Mesh *mesh_result = (Mesh *)BKE_id_new_nomain(ID_ME, ((ID *)object->data)->name + 2);
|
||||
BKE_mesh_from_metaball(&object->runtime.curve_cache->disp, mesh_result);
|
||||
BKE_mesh_texspace_copy_from_object(mesh_result, object);
|
||||
|
||||
/* Copy materials. */
|
||||
mesh_result->totcol = mball->totcol;
|
||||
mesh_result->mat = MEM_dupallocN(mball->mat);
|
||||
if (mball->mat != NULL) {
|
||||
mesh_result->mat = (Material **)MEM_dupallocN(mball->mat);
|
||||
if (mball->mat != nullptr) {
|
||||
for (int i = mball->totcol; i-- > 0;) {
|
||||
mesh_result->mat[i] = BKE_object_material_get(object, i + 1);
|
||||
}
|
||||
|
@ -1142,7 +1147,7 @@ static Mesh *mesh_new_from_mesh(Object *object, Mesh *mesh)
|
|||
BKE_mesh_wrapper_ensure_mdata(mesh);
|
||||
|
||||
Mesh *mesh_result = (Mesh *)BKE_id_copy_ex(
|
||||
NULL, &mesh->id, NULL, LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT);
|
||||
nullptr, &mesh->id, nullptr, LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT);
|
||||
/* NOTE: Materials should already be copied. */
|
||||
/* Copy original mesh name. This is because edit meshes might not have one properly set name. */
|
||||
BLI_strncpy(mesh_result->id.name, ((ID *)object->data)->name, sizeof(mesh_result->id.name));
|
||||
|
@ -1157,12 +1162,12 @@ static Mesh *mesh_new_from_mesh_object_with_layers(Depsgraph *depsgraph,
|
|||
return mesh_new_from_mesh(object, (Mesh *)object->data);
|
||||
}
|
||||
|
||||
if (depsgraph == NULL) {
|
||||
return NULL;
|
||||
if (depsgraph == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Object object_for_eval = *object;
|
||||
if (object_for_eval.runtime.data_orig != NULL) {
|
||||
if (object_for_eval.runtime.data_orig != nullptr) {
|
||||
object_for_eval.data = object_for_eval.runtime.data_orig;
|
||||
}
|
||||
|
||||
|
@ -1186,10 +1191,10 @@ static Mesh *mesh_new_from_mesh_object(Depsgraph *depsgraph,
|
|||
if (preserve_all_data_layers || preserve_origindex) {
|
||||
return mesh_new_from_mesh_object_with_layers(depsgraph, object, preserve_origindex);
|
||||
}
|
||||
Mesh *mesh_input = object->data;
|
||||
Mesh *mesh_input = (Mesh *)object->data;
|
||||
/* If we are in edit mode, use evaluated mesh from edit structure, matching to what
|
||||
* viewport is using for visualization. */
|
||||
if (mesh_input->edit_mesh != NULL && mesh_input->edit_mesh->mesh_eval_final) {
|
||||
if (mesh_input->edit_mesh != nullptr && mesh_input->edit_mesh->mesh_eval_final) {
|
||||
mesh_input = mesh_input->edit_mesh->mesh_eval_final;
|
||||
}
|
||||
return mesh_new_from_mesh(object, mesh_input);
|
||||
|
@ -1200,7 +1205,7 @@ Mesh *BKE_mesh_new_from_object(Depsgraph *depsgraph,
|
|||
const bool preserve_all_data_layers,
|
||||
const bool preserve_origindex)
|
||||
{
|
||||
Mesh *new_mesh = NULL;
|
||||
Mesh *new_mesh = nullptr;
|
||||
switch (object->type) {
|
||||
case OB_FONT:
|
||||
case OB_CURVE:
|
||||
|
@ -1216,11 +1221,11 @@ Mesh *BKE_mesh_new_from_object(Depsgraph *depsgraph,
|
|||
break;
|
||||
default:
|
||||
/* Object does not have geometry data. */
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
if (new_mesh == NULL) {
|
||||
if (new_mesh == nullptr) {
|
||||
/* Happens in special cases like request of mesh for non-mother meta ball. */
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* The result must have 0 users, since it's just a mesh which is free-dangling data-block.
|
||||
|
@ -1233,9 +1238,9 @@ Mesh *BKE_mesh_new_from_object(Depsgraph *depsgraph,
|
|||
* ownership.
|
||||
*
|
||||
* Here we are constructing a mesh which is supposed to be independent, which means no shared
|
||||
* ownership is allowed, so we make sure edit mesh is reset to NULL (which is similar to as if
|
||||
* ownership is allowed, so we make sure edit mesh is reset to nullptr (which is similar to as if
|
||||
* one duplicates the objects and applies all the modifiers). */
|
||||
new_mesh->edit_mesh = NULL;
|
||||
new_mesh->edit_mesh = nullptr;
|
||||
|
||||
return new_mesh;
|
||||
}
|
||||
|
@ -1243,7 +1248,7 @@ Mesh *BKE_mesh_new_from_object(Depsgraph *depsgraph,
|
|||
static int foreach_libblock_make_original_callback(LibraryIDLinkCallbackData *cb_data)
|
||||
{
|
||||
ID **id_p = cb_data->id_pointer;
|
||||
if (*id_p == NULL) {
|
||||
if (*id_p == nullptr) {
|
||||
return IDWALK_RET_NOP;
|
||||
}
|
||||
*id_p = DEG_get_original_id(*id_p);
|
||||
|
@ -1254,7 +1259,7 @@ static int foreach_libblock_make_original_callback(LibraryIDLinkCallbackData *cb
|
|||
static int foreach_libblock_make_usercounts_callback(LibraryIDLinkCallbackData *cb_data)
|
||||
{
|
||||
ID **id_p = cb_data->id_pointer;
|
||||
if (*id_p == NULL) {
|
||||
if (*id_p == nullptr) {
|
||||
return IDWALK_RET_NOP;
|
||||
}
|
||||
|
||||
|
@ -1278,7 +1283,7 @@ Mesh *BKE_mesh_new_from_object_to_bmain(Main *bmain,
|
|||
BLI_assert(ELEM(object->type, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_MESH));
|
||||
|
||||
Mesh *mesh = BKE_mesh_new_from_object(depsgraph, object, preserve_all_data_layers, false);
|
||||
if (mesh == NULL) {
|
||||
if (mesh == nullptr) {
|
||||
/* Unable to convert the object to a mesh, return an empty one. */
|
||||
Mesh *mesh_in_bmain = BKE_mesh_add(bmain, ((ID *)object->data)->name + 2);
|
||||
id_us_min(&mesh_in_bmain->id);
|
||||
|
@ -1294,7 +1299,7 @@ Mesh *BKE_mesh_new_from_object_to_bmain(Main *bmain,
|
|||
* Note that user-count updates has to be done *after* mesh has been transferred to Main database
|
||||
* (since doing refcounting on non-Main IDs is forbidden). */
|
||||
BKE_library_foreach_ID_link(
|
||||
NULL, &mesh->id, foreach_libblock_make_original_callback, NULL, IDWALK_NOP);
|
||||
nullptr, &mesh->id, foreach_libblock_make_original_callback, nullptr, IDWALK_NOP);
|
||||
|
||||
/* Append the mesh to 'bmain'.
|
||||
* We do it a bit longer way since there is no simple and clear way of adding existing data-block
|
||||
|
@ -1311,14 +1316,14 @@ Mesh *BKE_mesh_new_from_object_to_bmain(Main *bmain,
|
|||
mesh_in_bmain->totcol = mesh->totcol;
|
||||
mesh_in_bmain->flag = mesh->flag;
|
||||
mesh_in_bmain->smoothresh = mesh->smoothresh;
|
||||
mesh->mat = NULL;
|
||||
mesh->mat = nullptr;
|
||||
|
||||
BKE_mesh_nomain_to_mesh(mesh, mesh_in_bmain, NULL, &CD_MASK_MESH, true);
|
||||
BKE_mesh_nomain_to_mesh(mesh, mesh_in_bmain, nullptr, &CD_MASK_MESH, true);
|
||||
|
||||
/* User-count is required because so far mesh was in a limbo, where library management does
|
||||
* not perform any user management (i.e. copy of a mesh will not increase users of materials). */
|
||||
BKE_library_foreach_ID_link(
|
||||
NULL, &mesh_in_bmain->id, foreach_libblock_make_usercounts_callback, NULL, IDWALK_NOP);
|
||||
nullptr, &mesh_in_bmain->id, foreach_libblock_make_usercounts_callback, nullptr, IDWALK_NOP);
|
||||
|
||||
/* Make sure user count from BKE_mesh_add() is the one we expect here and bring it down to 0. */
|
||||
BLI_assert(mesh_in_bmain->id.us == 1);
|
||||
|
@ -1347,7 +1352,7 @@ static void add_shapekey_layers(Mesh *mesh_dest, Mesh *mesh_src)
|
|||
return;
|
||||
}
|
||||
|
||||
for (i = 0, kb = key->block.first; kb; kb = kb->next, i++) {
|
||||
for (i = 0, kb = (KeyBlock *)key->block.first; kb; kb = kb->next, i++) {
|
||||
int ci;
|
||||
float *array;
|
||||
|
||||
|
@ -1358,10 +1363,10 @@ static void add_shapekey_layers(Mesh *mesh_dest, Mesh *mesh_src)
|
|||
mesh_src->totvert,
|
||||
kb->name,
|
||||
kb->totelem);
|
||||
array = MEM_calloc_arrayN((size_t)mesh_src->totvert, sizeof(float[3]), __func__);
|
||||
array = (float *)MEM_calloc_arrayN((size_t)mesh_src->totvert, sizeof(float[3]), __func__);
|
||||
}
|
||||
else {
|
||||
array = MEM_malloc_arrayN((size_t)mesh_src->totvert, sizeof(float[3]), __func__);
|
||||
array = (float *)MEM_malloc_arrayN((size_t)mesh_src->totvert, sizeof(float[3]), __func__);
|
||||
memcpy(array, kb->data, sizeof(float[3]) * (size_t)mesh_src->totvert);
|
||||
}
|
||||
|
||||
|
@ -1379,9 +1384,10 @@ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph,
|
|||
ModifierData *md_eval,
|
||||
const bool build_shapekey_layers)
|
||||
{
|
||||
Mesh *me = ob_eval->runtime.data_orig ? ob_eval->runtime.data_orig : ob_eval->data;
|
||||
const ModifierTypeInfo *mti = BKE_modifier_get_info(md_eval->type);
|
||||
Mesh *result = NULL;
|
||||
Mesh *me = ob_eval->runtime.data_orig ? (Mesh *)ob_eval->runtime.data_orig :
|
||||
(Mesh *)ob_eval->data;
|
||||
const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md_eval->type);
|
||||
Mesh *result = nullptr;
|
||||
KeyBlock *kb;
|
||||
ModifierEvalContext mectx = {depsgraph, ob_eval, MOD_APPLY_TO_BASE_MESH};
|
||||
|
||||
|
@ -1389,12 +1395,12 @@ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph,
|
|||
return result;
|
||||
}
|
||||
|
||||
if (mti->isDisabled && mti->isDisabled(scene, md_eval, 0)) {
|
||||
if (mti->isDisabled && mti->isDisabled(scene, md_eval, false)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (build_shapekey_layers && me->key &&
|
||||
(kb = BLI_findlink(&me->key->block, ob_eval->shapenr - 1))) {
|
||||
(kb = (KeyBlock *)BLI_findlink(&me->key->block, ob_eval->shapenr - 1))) {
|
||||
BKE_keyblock_convert_to_mesh(kb, me);
|
||||
}
|
||||
|
||||
|
@ -1402,7 +1408,7 @@ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph,
|
|||
int numVerts;
|
||||
float(*deformedVerts)[3] = BKE_mesh_vert_coords_alloc(me, &numVerts);
|
||||
|
||||
result = (Mesh *)BKE_id_copy_ex(NULL, &me->id, NULL, LIB_ID_COPY_LOCALIZE);
|
||||
result = (Mesh *)BKE_id_copy_ex(nullptr, &me->id, nullptr, LIB_ID_COPY_LOCALIZE);
|
||||
mti->deformVerts(md_eval, &mectx, result, deformedVerts, numVerts);
|
||||
BKE_mesh_vert_coords_apply(result, deformedVerts);
|
||||
|
||||
|
@ -1413,7 +1419,7 @@ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph,
|
|||
MEM_freeN(deformedVerts);
|
||||
}
|
||||
else {
|
||||
Mesh *mesh_temp = (Mesh *)BKE_id_copy_ex(NULL, &me->id, NULL, LIB_ID_COPY_LOCALIZE);
|
||||
Mesh *mesh_temp = (Mesh *)BKE_id_copy_ex(nullptr, &me->id, nullptr, LIB_ID_COPY_LOCALIZE);
|
||||
|
||||
if (build_shapekey_layers) {
|
||||
add_shapekey_layers(mesh_temp, me);
|
||||
|
@ -1423,7 +1429,7 @@ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph,
|
|||
ASSERT_IS_VALID_MESH(result);
|
||||
|
||||
if (mesh_temp != result) {
|
||||
BKE_id_free(NULL, mesh_temp);
|
||||
BKE_id_free(nullptr, mesh_temp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1446,7 +1452,7 @@ static void shapekey_layers_to_keyblocks(Mesh *mesh_src, Mesh *mesh_dst, int act
|
|||
&mesh_src->vdata.layers[CustomData_get_layer_index_n(&mesh_src->vdata, CD_SHAPEKEY, i)];
|
||||
float(*cos)[3], (*kbcos)[3];
|
||||
|
||||
for (kb = mesh_dst->key->block.first; kb; kb = kb->next) {
|
||||
for (kb = (KeyBlock *)mesh_dst->key->block.first; kb; kb = kb->next) {
|
||||
if (kb->uid == layer->uid) {
|
||||
break;
|
||||
}
|
||||
|
@ -1461,10 +1467,10 @@ static void shapekey_layers_to_keyblocks(Mesh *mesh_src, Mesh *mesh_dst, int act
|
|||
MEM_freeN(kb->data);
|
||||
}
|
||||
|
||||
cos = CustomData_get_layer_n(&mesh_src->vdata, CD_SHAPEKEY, i);
|
||||
cos = (float(*)[3])CustomData_get_layer_n(&mesh_src->vdata, CD_SHAPEKEY, i);
|
||||
kb->totelem = mesh_src->totvert;
|
||||
|
||||
kb->data = kbcos = MEM_malloc_arrayN(kb->totelem, sizeof(float[3]), __func__);
|
||||
kb->data = kbcos = (float(*)[3])MEM_malloc_arrayN(kb->totelem, sizeof(float[3]), __func__);
|
||||
if (kb->uid == actshape_uid) {
|
||||
MVert *mvert = mesh_src->mvert;
|
||||
|
||||
|
@ -1479,7 +1485,7 @@ static void shapekey_layers_to_keyblocks(Mesh *mesh_src, Mesh *mesh_dst, int act
|
|||
}
|
||||
}
|
||||
|
||||
for (kb = mesh_dst->key->block.first; kb; kb = kb->next) {
|
||||
for (kb = (KeyBlock *)mesh_dst->key->block.first; kb; kb = kb->next) {
|
||||
if (kb->totelem != mesh_src->totvert) {
|
||||
if (kb->data) {
|
||||
MEM_freeN(kb->data);
|
||||
|
@ -1544,7 +1550,7 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src,
|
|||
int uid;
|
||||
|
||||
if (ob) {
|
||||
kb = BLI_findlink(&mesh_dst->key->block, ob->shapenr - 1);
|
||||
kb = (KeyBlock *)BLI_findlink(&mesh_dst->key->block, ob->shapenr - 1);
|
||||
if (kb) {
|
||||
uid = kb->uid;
|
||||
}
|
||||
|
@ -1607,11 +1613,11 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src,
|
|||
/* NOTE(nazgul): maybe some other layers should be copied? */
|
||||
if (CustomData_has_layer(&mesh_dst->ldata, CD_MDISPS)) {
|
||||
if (totloop == mesh_dst->totloop) {
|
||||
MDisps *mdisps = CustomData_get_layer(&mesh_dst->ldata, CD_MDISPS);
|
||||
MDisps *mdisps = (MDisps *)CustomData_get_layer(&mesh_dst->ldata, CD_MDISPS);
|
||||
CustomData_add_layer(&tmp.ldata, CD_MDISPS, alloctype, mdisps, totloop);
|
||||
if (alloctype == CD_ASSIGN) {
|
||||
/* Assign NULL to prevent double-free. */
|
||||
CustomData_set_layer(&mesh_dst->ldata, CD_MDISPS, NULL);
|
||||
/* Assign nullptr to prevent double-free. */
|
||||
CustomData_set_layer(&mesh_dst->ldata, CD_MDISPS, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1633,7 +1639,7 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src,
|
|||
if (tmp.key && !(tmp.id.tag & LIB_TAG_NO_MAIN)) {
|
||||
id_us_min(&tmp.key->id);
|
||||
}
|
||||
tmp.key = NULL;
|
||||
tmp.key = nullptr;
|
||||
}
|
||||
|
||||
/* Clear selection history */
|
||||
|
@ -1660,7 +1666,7 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src,
|
|||
CustomData_free_typemask(&mesh_src->ldata, mesh_src->totloop, ~mask->lmask);
|
||||
CustomData_free_typemask(&mesh_src->pdata, mesh_src->totpoly, ~mask->pmask);
|
||||
}
|
||||
BKE_id_free(NULL, mesh_src);
|
||||
BKE_id_free(nullptr, mesh_src);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1682,7 +1688,7 @@ void BKE_mesh_nomain_to_meshkey(Mesh *mesh_src, Mesh *mesh_dst, KeyBlock *kb)
|
|||
kb->data = MEM_malloc_arrayN(mesh_dst->key->elemsize, mesh_dst->totvert, "kb->data");
|
||||
kb->totelem = totvert;
|
||||
|
||||
fp = kb->data;
|
||||
fp = (float *)kb->data;
|
||||
mvert = mesh_src->mvert;
|
||||
|
||||
for (a = 0; a < kb->totelem; a++, fp += 3, mvert++) {
|
|
@ -3947,6 +3947,9 @@ void nodeDeclarationEnsure(bNodeTree *UNUSED(ntree), bNode *node)
|
|||
if (node->typeinfo->declare == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (node->declaration != nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
node->declaration = new blender::nodes::NodeDeclaration();
|
||||
blender::nodes::NodeDeclarationBuilder builder{*node->declaration};
|
||||
|
|
|
@ -18,6 +18,13 @@
|
|||
|
||||
/** \file
|
||||
* \ingroup bli
|
||||
*
|
||||
* Functions for generating and handling "Session UUIDs".
|
||||
*
|
||||
* Note that these are not true universally-unique identifiers, but only unique during the current
|
||||
* Blender session.
|
||||
*
|
||||
* For true UUIDs, see `BLI_uuid.h`.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/** \file
|
||||
* \ingroup bli
|
||||
*
|
||||
* Functions for generating and handling UUID structs according to RFC4122.
|
||||
*
|
||||
* Note that these are true UUIDs, not to be confused with the "session uuid" defined in
|
||||
* `BLI_session_uuid.h`.
|
||||
*/
|
||||
#include "DNA_uuid_types.h"
|
||||
|
||||
#include "BLI_compiler_attrs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* UUID generator for random (version 4) UUIDs. See RFC4122 section 4.4.
|
||||
* This function is not thread-safe. */
|
||||
UUID BLI_uuid_generate_random(void);
|
||||
|
||||
/** Compare two UUIDs, return true iff they are equal. */
|
||||
bool BLI_uuid_equal(UUID uuid1, UUID uuid2);
|
||||
|
||||
/**
|
||||
* Format UUID as string.
|
||||
* The buffer must be at least 37 bytes (36 bytes for the UUID + terminating 0).
|
||||
*/
|
||||
void BLI_uuid_format(char *buffer, UUID uuid) ATTR_NONNULL();
|
||||
|
||||
/**
|
||||
* Parse a string as UUID.
|
||||
* The string MUST be in the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,
|
||||
* as produced by #BLI_uuid_format().
|
||||
*
|
||||
* Return true if the string could be parsed, and false otherwise. In the latter case, the UUID may
|
||||
* have been partially updated.
|
||||
*/
|
||||
bool BLI_uuid_parse_string(UUID *uuid, const char *buffer) ATTR_NONNULL();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
# include <ostream>
|
||||
|
||||
/** Output the UUID as formatted ASCII string, see #BLI_uuid_format(). */
|
||||
std::ostream &operator<<(std::ostream &stream, UUID uuid);
|
||||
|
||||
#endif
|
|
@ -147,6 +147,7 @@ set(SRC
|
|||
intern/time.c
|
||||
intern/timecode.c
|
||||
intern/timeit.cc
|
||||
intern/uuid.cc
|
||||
intern/uvproject.c
|
||||
intern/voronoi_2d.c
|
||||
intern/voxel.c
|
||||
|
@ -311,6 +312,7 @@ set(SRC
|
|||
BLI_utildefines_stack.h
|
||||
BLI_utildefines_variadic.h
|
||||
BLI_utility_mixins.hh
|
||||
BLI_uuid.h
|
||||
BLI_uvproject.h
|
||||
BLI_vector.hh
|
||||
BLI_vector_adaptor.hh
|
||||
|
@ -456,6 +458,7 @@ if(WITH_GTESTS)
|
|||
tests/BLI_string_utf8_test.cc
|
||||
tests/BLI_task_graph_test.cc
|
||||
tests/BLI_task_test.cc
|
||||
tests/BLI_uuid_test.cc
|
||||
tests/BLI_vector_set_test.cc
|
||||
tests/BLI_vector_test.cc
|
||||
tests/BLI_virtual_array_test.cc
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup bli
|
||||
*/
|
||||
|
||||
#include "BLI_uuid.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <random>
|
||||
|
||||
/* Ensure the UUID struct doesn't have any padding, to be compatible with memcmp(). */
|
||||
static_assert(sizeof(UUID) == 16, "expect UUIDs to be 128 bit exactly");
|
||||
|
||||
UUID BLI_uuid_generate_random()
|
||||
{
|
||||
static std::mt19937_64 rng = []() {
|
||||
std::mt19937_64 rng;
|
||||
|
||||
/* Ensure the RNG really can output 64-bit values. */
|
||||
static_assert(std::mt19937_64::min() == 0LL);
|
||||
static_assert(std::mt19937_64::max() == 0xffffffffffffffffLL);
|
||||
|
||||
struct timespec ts;
|
||||
timespec_get(&ts, TIME_UTC);
|
||||
rng.seed(ts.tv_nsec);
|
||||
|
||||
return rng;
|
||||
}();
|
||||
|
||||
UUID uuid;
|
||||
|
||||
/* RFC4122 suggests setting certain bits to a fixed value, and then randomizing the remaining
|
||||
* bits. The opposite is easier to implement, though, so that's what's done here. */
|
||||
|
||||
/* Read two 64-bit numbers to randomize all 128 bits of the UUID. */
|
||||
uint64_t *uuid_as_int64 = reinterpret_cast<uint64_t *>(&uuid);
|
||||
uuid_as_int64[0] = rng();
|
||||
uuid_as_int64[1] = rng();
|
||||
|
||||
/* Set the most significant four bits to 0b0100 to indicate version 4 (random UUID). */
|
||||
uuid.time_hi_and_version &= ~0xF000;
|
||||
uuid.time_hi_and_version |= 0x4000;
|
||||
|
||||
/* Set the most significant two bits to 0b10 to indicate compatibility with RFC4122. */
|
||||
uuid.clock_seq_hi_and_reserved &= ~0x40;
|
||||
uuid.clock_seq_hi_and_reserved |= 0x80;
|
||||
|
||||
return uuid;
|
||||
}
|
||||
|
||||
bool BLI_uuid_equal(const UUID uuid1, const UUID uuid2)
|
||||
{
|
||||
return std::memcmp(&uuid1, &uuid2, sizeof(uuid1)) == 0;
|
||||
}
|
||||
|
||||
void BLI_uuid_format(char *buffer, const UUID uuid)
|
||||
{
|
||||
std::sprintf(buffer,
|
||||
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
uuid.time_low,
|
||||
uuid.time_mid,
|
||||
uuid.time_hi_and_version,
|
||||
uuid.clock_seq_hi_and_reserved,
|
||||
uuid.clock_seq_low,
|
||||
uuid.node[0],
|
||||
uuid.node[1],
|
||||
uuid.node[2],
|
||||
uuid.node[3],
|
||||
uuid.node[4],
|
||||
uuid.node[5]);
|
||||
}
|
||||
|
||||
bool BLI_uuid_parse_string(UUID *uuid, const char *buffer)
|
||||
{
|
||||
const int num_fields_parsed = std::sscanf(
|
||||
buffer,
|
||||
"%8x-%4hx-%4hx-%2hhx%2hhx-%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx",
|
||||
&uuid->time_low,
|
||||
&uuid->time_mid,
|
||||
&uuid->time_hi_and_version,
|
||||
&uuid->clock_seq_hi_and_reserved,
|
||||
&uuid->clock_seq_low,
|
||||
&uuid->node[0],
|
||||
&uuid->node[1],
|
||||
&uuid->node[2],
|
||||
&uuid->node[3],
|
||||
&uuid->node[4],
|
||||
&uuid->node[5]);
|
||||
return num_fields_parsed == 11;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &stream, UUID uuid)
|
||||
{
|
||||
std::string buffer(36, '\0');
|
||||
BLI_uuid_format(buffer.data(), uuid);
|
||||
stream << buffer;
|
||||
return stream;
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#include "testing/testing.h"
|
||||
#include <cstring>
|
||||
|
||||
#include "BLI_uuid.h"
|
||||
|
||||
TEST(BLI_uuid, generate_random)
|
||||
{
|
||||
const UUID uuid = BLI_uuid_generate_random();
|
||||
|
||||
// The 4 MSbits represent the "version" of the UUID.
|
||||
const uint16_t version = uuid.time_hi_and_version >> 12;
|
||||
EXPECT_EQ(version, 4);
|
||||
|
||||
// The 2 MSbits should be 0b10, indicating compliance with RFC4122.
|
||||
const uint8_t reserved = uuid.clock_seq_hi_and_reserved >> 6;
|
||||
EXPECT_EQ(reserved, 0b10);
|
||||
}
|
||||
|
||||
TEST(BLI_uuid, generate_many_random)
|
||||
{
|
||||
const UUID first_uuid = BLI_uuid_generate_random();
|
||||
|
||||
/* Generate lots of UUIDs to get some indication that the randomness is okay. */
|
||||
for (int i = 0; i < 1000000; ++i) {
|
||||
const UUID uuid = BLI_uuid_generate_random();
|
||||
EXPECT_FALSE(BLI_uuid_equal(first_uuid, uuid));
|
||||
|
||||
// Check that the non-random bits are set according to RFC4122.
|
||||
const uint16_t version = uuid.time_hi_and_version >> 12;
|
||||
EXPECT_EQ(version, 4);
|
||||
const uint8_t reserved = uuid.clock_seq_hi_and_reserved >> 6;
|
||||
EXPECT_EQ(reserved, 0b10);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(BLI_uuid, equality)
|
||||
{
|
||||
const UUID uuid1 = BLI_uuid_generate_random();
|
||||
const UUID uuid2 = BLI_uuid_generate_random();
|
||||
|
||||
EXPECT_TRUE(BLI_uuid_equal(uuid1, uuid1));
|
||||
EXPECT_FALSE(BLI_uuid_equal(uuid1, uuid2));
|
||||
}
|
||||
|
||||
TEST(BLI_uuid, string_formatting)
|
||||
{
|
||||
UUID uuid;
|
||||
std::string buffer(36, '\0');
|
||||
|
||||
memset(&uuid, 0, sizeof(uuid));
|
||||
BLI_uuid_format(buffer.data(), uuid);
|
||||
EXPECT_EQ("00000000-0000-0000-0000-000000000000", buffer);
|
||||
|
||||
/* Demo of where the bits end up in the formatted string. */
|
||||
uuid.time_low = 1;
|
||||
uuid.time_mid = 2;
|
||||
uuid.time_hi_and_version = 3;
|
||||
uuid.clock_seq_hi_and_reserved = 4;
|
||||
uuid.clock_seq_low = 5;
|
||||
uuid.node[0] = 6;
|
||||
uuid.node[5] = 7;
|
||||
BLI_uuid_format(buffer.data(), uuid);
|
||||
EXPECT_EQ("00000001-0002-0003-0405-060000000007", buffer);
|
||||
|
||||
/* Somewhat more complex bit patterns. This is a version 1 UUID generated from Python. */
|
||||
const UUID uuid1 = {3540651616, 5282, 4588, 139, 153, 0xf7, 0x73, 0x69, 0x44, 0xdb, 0x8b};
|
||||
BLI_uuid_format(buffer.data(), uuid1);
|
||||
EXPECT_EQ("d30a0e60-14a2-11ec-8b99-f7736944db8b", buffer);
|
||||
|
||||
/* Namespace UUID, example listed in RFC4211. */
|
||||
const UUID namespace_dns = {
|
||||
0x6ba7b810, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8};
|
||||
BLI_uuid_format(buffer.data(), namespace_dns);
|
||||
EXPECT_EQ("6ba7b810-9dad-11d1-80b4-00c04fd430c8", buffer);
|
||||
}
|
||||
|
||||
TEST(BLI_uuid, string_parsing_ok)
|
||||
{
|
||||
UUID uuid;
|
||||
std::string buffer(36, '\0');
|
||||
|
||||
const bool parsed_ok = BLI_uuid_parse_string(&uuid, "d30a0e60-14a2-11ec-8b99-f7736944db8b");
|
||||
EXPECT_TRUE(parsed_ok);
|
||||
BLI_uuid_format(buffer.data(), uuid);
|
||||
EXPECT_EQ("d30a0e60-14a2-11ec-8b99-f7736944db8b", buffer);
|
||||
}
|
||||
|
||||
TEST(BLI_uuid, string_parsing_capitalisation)
|
||||
{
|
||||
UUID uuid;
|
||||
std::string buffer(36, '\0');
|
||||
|
||||
/* RFC4122 demands acceptance of upper-case hex digits. */
|
||||
const bool parsed_ok = BLI_uuid_parse_string(&uuid, "D30A0E60-14A2-11EC-8B99-F7736944DB8B");
|
||||
EXPECT_TRUE(parsed_ok);
|
||||
BLI_uuid_format(buffer.data(), uuid);
|
||||
|
||||
/* Software should still output lower-case hex digits, though. */
|
||||
EXPECT_EQ("d30a0e60-14a2-11ec-8b99-f7736944db8b", buffer);
|
||||
}
|
||||
|
||||
TEST(BLI_uuid, string_parsing_fail)
|
||||
{
|
||||
UUID uuid;
|
||||
std::string buffer(36, '\0');
|
||||
|
||||
const bool parsed_ok = BLI_uuid_parse_string(&uuid, "d30a0e60!14a2-11ec-8b99-f7736944db8b");
|
||||
EXPECT_FALSE(parsed_ok);
|
||||
}
|
||||
|
||||
TEST(BLI_uuid, stream_operator)
|
||||
{
|
||||
std::stringstream ss;
|
||||
const UUID uuid = {3540651616, 5282, 4588, 139, 153, 0xf7, 0x73, 0x69, 0x44, 0xdb, 0x8b};
|
||||
ss << uuid;
|
||||
EXPECT_EQ(ss.str(), "d30a0e60-14a2-11ec-8b99-f7736944db8b");
|
||||
}
|
|
@ -887,7 +887,7 @@ void blo_do_versions_userdef(UserDef *userdef)
|
|||
|
||||
if (!USER_VERSION_ATLEAST(300, 21)) {
|
||||
/* Deprecated userdef->flag USER_SAVE_PREVIEWS */
|
||||
userdef->file_preview_type = (userdef->flag & USER_FLAG_UNUSED_5) ? USER_FILE_PREVIEW_CAMERA :
|
||||
userdef->file_preview_type = (userdef->flag & USER_FLAG_UNUSED_5) ? USER_FILE_PREVIEW_AUTO :
|
||||
USER_FILE_PREVIEW_NONE;
|
||||
/* Clear for reuse. */
|
||||
userdef->flag &= ~USER_FLAG_UNUSED_5;
|
||||
|
|
|
@ -240,8 +240,9 @@ void GPENCIL_cache_init(void *ved)
|
|||
}
|
||||
else {
|
||||
pd->do_onion = true;
|
||||
pd->simplify_fill = false;
|
||||
pd->simplify_fx = false;
|
||||
Scene *scene = draw_ctx->scene;
|
||||
pd->simplify_fill = GPENCIL_SIMPLIFY_FILL(scene, false);
|
||||
pd->simplify_fx = GPENCIL_SIMPLIFY_FX(scene, false);
|
||||
pd->fade_layer_opacity = -1.0f;
|
||||
pd->playing = false;
|
||||
}
|
||||
|
|
|
@ -259,7 +259,7 @@ static int armature_click_extrude_invoke(bContext *C, wmOperator *op, const wmEv
|
|||
void ARMATURE_OT_click_extrude(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Click-Extrude";
|
||||
ot->name = "Extrude to Cursor";
|
||||
ot->idname = "ARMATURE_OT_click_extrude";
|
||||
ot->description = "Create a new bone going from the last selected joint to the mouse position";
|
||||
|
||||
|
@ -269,7 +269,7 @@ void ARMATURE_OT_click_extrude(wmOperatorType *ot)
|
|||
ot->poll = ED_operator_editarmature;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* props */
|
||||
}
|
||||
|
|
|
@ -5620,7 +5620,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
void CURVE_OT_vertex_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Add Vertex";
|
||||
ot->name = "Extrude to Cursor or Add";
|
||||
ot->idname = "CURVE_OT_vertex_add";
|
||||
ot->description = "Add a new control point (linked to only selected end-curve one, if any)";
|
||||
|
||||
|
@ -5630,7 +5630,7 @@ void CURVE_OT_vertex_add(wmOperatorType *ot)
|
|||
ot->poll = ED_operator_editcurve;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* properties */
|
||||
RNA_def_float_vector_xyz(ot->srna,
|
||||
|
|
|
@ -5243,7 +5243,7 @@ void GPENCIL_OT_stroke_cutter(wmOperatorType *ot)
|
|||
ot->cancel = WM_gesture_lasso_cancel;
|
||||
|
||||
/* flag */
|
||||
ot->flag = OPTYPE_UNDO;
|
||||
ot->flag = OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* properties */
|
||||
WM_operator_properties_gesture_lasso(ot);
|
||||
|
|
|
@ -2347,7 +2347,7 @@ void GPENCIL_OT_select_lasso(wmOperatorType *ot)
|
|||
ot->cancel = WM_gesture_lasso_cancel;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO;
|
||||
ot->flag = OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* properties */
|
||||
WM_operator_properties_select_operation(ot);
|
||||
|
|
|
@ -508,6 +508,7 @@ typedef struct uiAfterFunc {
|
|||
bContextStore *context;
|
||||
|
||||
char undostr[BKE_UNDO_STR_MAX];
|
||||
char drawstr[UI_MAX_DRAW_STR];
|
||||
} uiAfterFunc;
|
||||
|
||||
static void button_activate_init(bContext *C,
|
||||
|
@ -790,6 +791,10 @@ static void ui_handle_afterfunc_add_operator_ex(wmOperatorType *ot,
|
|||
if (context_but && context_but->context) {
|
||||
after->context = CTX_store_copy(context_but->context);
|
||||
}
|
||||
|
||||
if (context_but) {
|
||||
ui_but_drawstr_without_sep_char(context_but, after->drawstr, sizeof(after->drawstr));
|
||||
}
|
||||
}
|
||||
|
||||
void ui_handle_afterfunc_add_operator(wmOperatorType *ot, int opcontext)
|
||||
|
@ -900,6 +905,8 @@ static void ui_apply_but_func(bContext *C, uiBut *but)
|
|||
after->context = CTX_store_copy(but->context);
|
||||
}
|
||||
|
||||
ui_but_drawstr_without_sep_char(but, after->drawstr, sizeof(after->drawstr));
|
||||
|
||||
but->optype = NULL;
|
||||
but->opcontext = 0;
|
||||
but->opptr = NULL;
|
||||
|
@ -1021,7 +1028,8 @@ static void ui_apply_but_funcs_after(bContext *C)
|
|||
}
|
||||
|
||||
if (after.optype) {
|
||||
WM_operator_name_call_ptr(C, after.optype, after.opcontext, (after.opptr) ? &opptr : NULL);
|
||||
WM_operator_name_call_ptr_with_depends_on_cursor(
|
||||
C, after.optype, after.opcontext, (after.opptr) ? &opptr : NULL, after.drawstr);
|
||||
}
|
||||
|
||||
if (after.opptr) {
|
||||
|
@ -4190,10 +4198,11 @@ static void ui_but_extra_operator_icon_apply(bContext *C, uiBut *but, uiButExtra
|
|||
ui_apply_but(C, but->block, but, but->active, true);
|
||||
}
|
||||
button_activate_state(C, but, BUTTON_STATE_EXIT);
|
||||
WM_operator_name_call_ptr(C,
|
||||
op_icon->optype_params->optype,
|
||||
op_icon->optype_params->opcontext,
|
||||
op_icon->optype_params->opptr);
|
||||
WM_operator_name_call_ptr_with_depends_on_cursor(C,
|
||||
op_icon->optype_params->optype,
|
||||
op_icon->optype_params->opcontext,
|
||||
op_icon->optype_params->opptr,
|
||||
NULL);
|
||||
|
||||
/* Force recreation of extra operator icons (pseudo update). */
|
||||
ui_but_extra_operator_icons_free(but);
|
||||
|
|
|
@ -921,10 +921,10 @@ static void ui_keymap_but_cb(bContext *UNUSED(C), void *but_v, void *UNUSED(key_
|
|||
{
|
||||
uiBut *but = but_v;
|
||||
|
||||
RNA_boolean_set(&but->rnapoin, "shift", (but->modifier_key & KM_SHIFT) != 0);
|
||||
RNA_boolean_set(&but->rnapoin, "ctrl", (but->modifier_key & KM_CTRL) != 0);
|
||||
RNA_boolean_set(&but->rnapoin, "alt", (but->modifier_key & KM_ALT) != 0);
|
||||
RNA_boolean_set(&but->rnapoin, "oskey", (but->modifier_key & KM_OSKEY) != 0);
|
||||
RNA_int_set(&but->rnapoin, "shift", (but->modifier_key & KM_SHIFT) ? KM_MOD_HELD : KM_NOTHING);
|
||||
RNA_int_set(&but->rnapoin, "ctrl", (but->modifier_key & KM_CTRL) ? KM_MOD_HELD : KM_NOTHING);
|
||||
RNA_int_set(&but->rnapoin, "alt", (but->modifier_key & KM_ALT) ? KM_MOD_HELD : KM_NOTHING);
|
||||
RNA_int_set(&but->rnapoin, "oskey", (but->modifier_key & KM_OSKEY) ? KM_MOD_HELD : KM_NOTHING);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -955,7 +955,8 @@ static void menu_search_exec_fn(bContext *C, void *UNUSED(arg1), void *arg2)
|
|||
switch (item->type) {
|
||||
case MENU_SEARCH_TYPE_OP: {
|
||||
CTX_store_set(C, item->op.context);
|
||||
WM_operator_name_call_ptr(C, item->op.type, item->op.opcontext, item->op.opptr);
|
||||
WM_operator_name_call_ptr_with_depends_on_cursor(
|
||||
C, item->op.type, item->op.opcontext, item->op.opptr, item->drawstr);
|
||||
CTX_store_set(C, NULL);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -629,7 +629,7 @@ void MASK_OT_select_lasso(wmOperatorType *ot)
|
|||
ot->cancel = WM_gesture_lasso_cancel;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO;
|
||||
ot->flag = OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* properties */
|
||||
WM_operator_properties_gesture_lasso(ot);
|
||||
|
|
|
@ -925,7 +925,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w
|
|||
void MESH_OT_dupli_extrude_cursor(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Duplicate or Extrude to Cursor";
|
||||
ot->name = "Extrude to Cursor or Add";
|
||||
ot->idname = "MESH_OT_dupli_extrude_cursor";
|
||||
ot->description =
|
||||
"Duplicate and extrude selected vertices, edges or faces towards the mouse cursor";
|
||||
|
@ -935,7 +935,7 @@ void MESH_OT_dupli_extrude_cursor(wmOperatorType *ot)
|
|||
ot->poll = ED_operator_editmesh_region_view3d;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
RNA_def_boolean(ot->srna,
|
||||
"rotate_source",
|
||||
|
|
|
@ -1124,7 +1124,7 @@ void MESH_OT_rip(wmOperatorType *ot)
|
|||
ot->poll = EDBM_view3d_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* to give to transform */
|
||||
Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR_DUMMY);
|
||||
|
|
|
@ -249,7 +249,7 @@ void MESH_OT_rip_edge(wmOperatorType *ot)
|
|||
ot->poll = EDBM_view3d_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* to give to transform */
|
||||
Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR_DUMMY);
|
||||
|
|
|
@ -4323,7 +4323,7 @@ void MESH_OT_knife_cut(wmOperatorType *ot)
|
|||
ot->poll = EDBM_view3d_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* properties */
|
||||
PropertyRNA *prop;
|
||||
|
|
|
@ -191,6 +191,7 @@ void OBJECT_OT_skin_radii_equalize(struct wmOperatorType *ot);
|
|||
void OBJECT_OT_skin_armature_create(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_laplaciandeform_bind(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_surfacedeform_bind(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_geometry_nodes_input_attribute_toggle(struct wmOperatorType *ot);
|
||||
|
||||
/* object_gpencil_modifiers.c */
|
||||
void OBJECT_OT_gpencil_modifier_add(struct wmOperatorType *ot);
|
||||
|
|
|
@ -3256,3 +3256,54 @@ void OBJECT_OT_surfacedeform_bind(wmOperatorType *ot)
|
|||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
/** \name Toggle Value or Attribute Operator
|
||||
*
|
||||
* \note This operator basically only exists to provide a better tooltip for the toggle button,
|
||||
* since it is stored as an IDProperty. It also stops the button from being highlighted when
|
||||
* "use_attribute" is on, which isn't expected.
|
||||
* \{ */
|
||||
|
||||
static int geometry_nodes_input_attribute_toggle_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob = ED_object_active_context(C);
|
||||
|
||||
char modifier_name[MAX_NAME];
|
||||
RNA_string_get(op->ptr, "modifier_name", modifier_name);
|
||||
NodesModifierData *nmd = (NodesModifierData *)BKE_modifiers_findby_name(ob, modifier_name);
|
||||
if (nmd == NULL) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
char prop_path[MAX_NAME];
|
||||
RNA_string_get(op->ptr, "prop_path", prop_path);
|
||||
|
||||
PointerRNA mod_ptr;
|
||||
RNA_pointer_create(&ob->id, &RNA_Modifier, nmd, &mod_ptr);
|
||||
|
||||
const int old_value = RNA_int_get(&mod_ptr, prop_path);
|
||||
const int new_value = !old_value;
|
||||
RNA_int_set(&mod_ptr, prop_path, new_value);
|
||||
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_geometry_nodes_input_attribute_toggle(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Input Attribute Toggle";
|
||||
ot->description =
|
||||
"Switch between an attribute and a single value to define the data for every element";
|
||||
ot->idname = "OBJECT_OT_geometry_nodes_input_attribute_toggle";
|
||||
|
||||
ot->exec = geometry_nodes_input_attribute_toggle_exec;
|
||||
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
|
||||
|
||||
RNA_def_string(ot->srna, "prop_path", NULL, 0, "Prop Path", "");
|
||||
RNA_def_string(ot->srna, "modifier_name", NULL, MAX_NAME, "Modifier Name", "");
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -145,6 +145,7 @@ void ED_operatortypes_object(void)
|
|||
WM_operatortype_append(OBJECT_OT_skin_loose_mark_clear);
|
||||
WM_operatortype_append(OBJECT_OT_skin_radii_equalize);
|
||||
WM_operatortype_append(OBJECT_OT_skin_armature_create);
|
||||
WM_operatortype_append(OBJECT_OT_geometry_nodes_input_attribute_toggle);
|
||||
|
||||
/* grease pencil modifiers */
|
||||
WM_operatortype_append(OBJECT_OT_gpencil_modifier_add);
|
||||
|
|
|
@ -128,6 +128,7 @@ extern const char *screen_context_dir[]; /* doc access */
|
|||
|
||||
/* screendump.c */
|
||||
void SCREEN_OT_screenshot(struct wmOperatorType *ot);
|
||||
void SCREEN_OT_screenshot_area(struct wmOperatorType *ot);
|
||||
|
||||
/* workspace_layout_edit.c */
|
||||
bool workspace_layout_set_poll(const struct WorkSpaceLayout *layout);
|
||||
|
|
|
@ -5690,6 +5690,7 @@ void ED_operatortypes_screen(void)
|
|||
WM_operatortype_append(SCREEN_OT_back_to_previous);
|
||||
WM_operatortype_append(SCREEN_OT_spacedata_cleanup);
|
||||
WM_operatortype_append(SCREEN_OT_screenshot);
|
||||
WM_operatortype_append(SCREEN_OT_screenshot_area);
|
||||
WM_operatortype_append(SCREEN_OT_userpref_show);
|
||||
WM_operatortype_append(SCREEN_OT_drivers_editor_show);
|
||||
WM_operatortype_append(SCREEN_OT_info_log_show);
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "BKE_image.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
|
@ -57,12 +58,13 @@ typedef struct ScreenshotData {
|
|||
uint *dumprect;
|
||||
int dumpsx, dumpsy;
|
||||
rcti crop;
|
||||
bool use_crop;
|
||||
|
||||
ImageFormatData im_format;
|
||||
} ScreenshotData;
|
||||
|
||||
/* call from both exec and invoke */
|
||||
static int screenshot_data_create(bContext *C, wmOperator *op)
|
||||
static int screenshot_data_create(bContext *C, wmOperator *op, ScrArea *area)
|
||||
{
|
||||
int dumprect_size[2];
|
||||
|
||||
|
@ -76,7 +78,6 @@ static int screenshot_data_create(bContext *C, wmOperator *op)
|
|||
|
||||
if (dumprect) {
|
||||
ScreenshotData *scd = MEM_callocN(sizeof(ScreenshotData), "screenshot");
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
|
||||
scd->dumpsx = dumprect_size[0];
|
||||
scd->dumpsy = dumprect_size[1];
|
||||
|
@ -110,12 +111,13 @@ static void screenshot_data_free(wmOperator *op)
|
|||
|
||||
static int screenshot_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
const bool use_crop = STREQ(op->idname, "SCREEN_OT_screenshot_area");
|
||||
ScreenshotData *scd = op->customdata;
|
||||
bool ok = false;
|
||||
|
||||
if (scd == NULL) {
|
||||
/* when running exec directly */
|
||||
screenshot_data_create(C, op);
|
||||
screenshot_data_create(C, op, use_crop ? CTX_wm_area(C) : NULL);
|
||||
scd = op->customdata;
|
||||
}
|
||||
|
||||
|
@ -132,7 +134,7 @@ static int screenshot_exec(bContext *C, wmOperator *op)
|
|||
ibuf->rect = scd->dumprect;
|
||||
|
||||
/* crop to show only single editor */
|
||||
if (!RNA_boolean_get(op->ptr, "full")) {
|
||||
if (use_crop) {
|
||||
IMB_rect_crop(ibuf, &scd->crop);
|
||||
scd->dumprect = ibuf->rect;
|
||||
}
|
||||
|
@ -157,9 +159,20 @@ static int screenshot_exec(bContext *C, wmOperator *op)
|
|||
return ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
static int screenshot_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
||||
static int screenshot_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
if (screenshot_data_create(C, op)) {
|
||||
const bool use_crop = STREQ(op->idname, "SCREEN_OT_screenshot_area");
|
||||
ScrArea *area = NULL;
|
||||
if (use_crop) {
|
||||
area = CTX_wm_area(C);
|
||||
bScreen *screen = CTX_wm_screen(C);
|
||||
ScrArea *area_test = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, event->x, event->y);
|
||||
if (area_test != NULL) {
|
||||
area = area_test;
|
||||
}
|
||||
}
|
||||
|
||||
if (screenshot_data_create(C, op, area)) {
|
||||
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
|
||||
return screenshot_exec(C, op);
|
||||
}
|
||||
|
@ -226,12 +239,8 @@ static bool screenshot_poll(bContext *C)
|
|||
return WM_operator_winactive(C);
|
||||
}
|
||||
|
||||
void SCREEN_OT_screenshot(wmOperatorType *ot)
|
||||
static void screen_screenshot_impl(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Save Screenshot";
|
||||
ot->idname = "SCREEN_OT_screenshot";
|
||||
ot->description = "Capture a picture of the active area or whole Blender window";
|
||||
|
||||
ot->invoke = screenshot_invoke;
|
||||
ot->check = screenshot_check;
|
||||
ot->exec = screenshot_exec;
|
||||
|
@ -239,8 +248,6 @@ void SCREEN_OT_screenshot(wmOperatorType *ot)
|
|||
ot->ui = screenshot_draw;
|
||||
ot->poll = screenshot_poll;
|
||||
|
||||
ot->flag = 0;
|
||||
|
||||
WM_operator_properties_filesel(ot,
|
||||
FILE_TYPE_FOLDER | FILE_TYPE_IMAGE,
|
||||
FILE_SPECIAL,
|
||||
|
@ -248,9 +255,26 @@ void SCREEN_OT_screenshot(wmOperatorType *ot)
|
|||
WM_FILESEL_FILEPATH,
|
||||
FILE_DEFAULTDISPLAY,
|
||||
FILE_SORT_DEFAULT);
|
||||
RNA_def_boolean(ot->srna,
|
||||
"full",
|
||||
1,
|
||||
"Full Screen",
|
||||
"Capture the whole window (otherwise only capture the active area)");
|
||||
}
|
||||
|
||||
void SCREEN_OT_screenshot(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Save Screenshot";
|
||||
ot->idname = "SCREEN_OT_screenshot";
|
||||
ot->description = "Capture a picture of the whole Blender window";
|
||||
|
||||
screen_screenshot_impl(ot);
|
||||
|
||||
ot->flag = 0;
|
||||
}
|
||||
|
||||
void SCREEN_OT_screenshot_area(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Save Screenshot (Area)";
|
||||
ot->idname = "SCREEN_OT_screenshot_area";
|
||||
ot->description = "Capture a picture of the active area";
|
||||
|
||||
screen_screenshot_impl(ot);
|
||||
|
||||
ot->flag = OPTYPE_DEPENDS_ON_CURSOR;
|
||||
}
|
||||
|
|
|
@ -1683,7 +1683,7 @@ void PAINT_OT_mask_lasso_gesture(wmOperatorType *ot)
|
|||
|
||||
ot->poll = SCULPT_mode_poll_view3d;
|
||||
|
||||
ot->flag = OPTYPE_REGISTER;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* Properties. */
|
||||
WM_operator_properties_gesture_lasso(ot);
|
||||
|
@ -1746,6 +1746,8 @@ void SCULPT_OT_face_set_lasso_gesture(wmOperatorType *ot)
|
|||
|
||||
ot->poll = SCULPT_mode_poll_view3d;
|
||||
|
||||
ot->flag = OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* Properties. */
|
||||
WM_operator_properties_gesture_lasso(ot);
|
||||
sculpt_gesture_operator_properties(ot);
|
||||
|
@ -1782,7 +1784,7 @@ void SCULPT_OT_trim_lasso_gesture(wmOperatorType *ot)
|
|||
|
||||
ot->poll = SCULPT_mode_poll_view3d;
|
||||
|
||||
ot->flag = OPTYPE_REGISTER;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* Properties. */
|
||||
WM_operator_properties_gesture_lasso(ot);
|
||||
|
|
|
@ -834,7 +834,7 @@ void ACTION_OT_select_lasso(wmOperatorType *ot)
|
|||
ot->cancel = WM_gesture_lasso_cancel;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO;
|
||||
ot->flag = OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* properties */
|
||||
WM_operator_properties_gesture_lasso(ot);
|
||||
|
|
|
@ -721,7 +721,7 @@ void CLIP_OT_select_lasso(wmOperatorType *ot)
|
|||
ot->cancel = WM_gesture_lasso_cancel;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO;
|
||||
ot->flag = OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* properties */
|
||||
WM_operator_properties_gesture_lasso(ot);
|
||||
|
|
|
@ -1006,7 +1006,7 @@ void GRAPH_OT_select_lasso(wmOperatorType *ot)
|
|||
ot->cancel = WM_gesture_lasso_cancel;
|
||||
|
||||
/* Flags. */
|
||||
ot->flag = OPTYPE_UNDO;
|
||||
ot->flag = OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* Properties. */
|
||||
WM_operator_properties_gesture_lasso(ot);
|
||||
|
|
|
@ -312,7 +312,7 @@ void NODE_OT_add_reroute(wmOperatorType *ot)
|
|||
ot->poll = ED_operator_node_editable;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* properties */
|
||||
PropertyRNA *prop;
|
||||
|
|
|
@ -1427,7 +1427,7 @@ void NODE_OT_links_cut(wmOperatorType *ot)
|
|||
ot->poll = ED_operator_node_editable;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* properties */
|
||||
PropertyRNA *prop;
|
||||
|
@ -1533,7 +1533,7 @@ void NODE_OT_links_mute(wmOperatorType *ot)
|
|||
ot->poll = ED_operator_node_editable;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* properties */
|
||||
PropertyRNA *prop;
|
||||
|
|
|
@ -923,7 +923,7 @@ void NODE_OT_select_lasso(wmOperatorType *ot)
|
|||
ot->cancel = WM_gesture_lasso_cancel;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO;
|
||||
ot->flag = OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* properties */
|
||||
RNA_def_boolean(ot->srna,
|
||||
|
|
|
@ -1438,7 +1438,7 @@ void VIEW3D_OT_select_lasso(wmOperatorType *ot)
|
|||
ot->cancel = WM_gesture_lasso_cancel;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO;
|
||||
ot->flag = OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* properties */
|
||||
WM_operator_properties_gesture_lasso(ot);
|
||||
|
|
|
@ -911,7 +911,8 @@ static void TRANSFORM_OT_bend(struct wmOperatorType *ot)
|
|||
ot->name = "Bend";
|
||||
ot->description = "Bend selected items between the 3D cursor and the mouse";
|
||||
ot->idname = OP_BEND;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
|
||||
/* Depend on cursor location because the cursor location is used to define the region to bend. */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke = transform_invoke;
|
||||
|
@ -1091,7 +1092,7 @@ static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot)
|
|||
ot->name = "Edge Slide";
|
||||
ot->description = "Slide an edge loop along a mesh";
|
||||
ot->idname = OP_EDGE_SLIDE;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke = transform_invoke;
|
||||
|
@ -1129,7 +1130,7 @@ static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot)
|
|||
ot->name = "Vertex Slide";
|
||||
ot->description = "Slide a vertex along a mesh";
|
||||
ot->idname = OP_VERT_SLIDE;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke = transform_invoke;
|
||||
|
|
|
@ -953,7 +953,7 @@ void UV_OT_rip(wmOperatorType *ot)
|
|||
ot->name = "UV Rip";
|
||||
ot->description = "Rip selected vertices or a selected region";
|
||||
ot->idname = "UV_OT_rip";
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = uv_rip_exec;
|
||||
|
|
|
@ -3450,7 +3450,7 @@ void UV_OT_select_lasso(wmOperatorType *ot)
|
|||
ot->cancel = WM_gesture_lasso_cancel;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO;
|
||||
ot->flag = OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
/* properties */
|
||||
WM_operator_properties_gesture_lasso(ot);
|
||||
|
|
|
@ -1016,6 +1016,7 @@ typedef enum eUserPref_Flag {
|
|||
/** #UserDef.file_preview_type */
|
||||
typedef enum eUserpref_File_Preview_Type {
|
||||
USER_FILE_PREVIEW_NONE = 0,
|
||||
USER_FILE_PREVIEW_AUTO,
|
||||
USER_FILE_PREVIEW_SCREENSHOT,
|
||||
USER_FILE_PREVIEW_CAMERA,
|
||||
} eUserpref_File_Preview_Type;
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup DNA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DNA_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Universally Unique Identifier according to RFC4122.
|
||||
*/
|
||||
typedef struct UUID {
|
||||
uint32_t time_low;
|
||||
uint16_t time_mid;
|
||||
uint16_t time_hi_and_version;
|
||||
uint8_t clock_seq_hi_and_reserved;
|
||||
uint8_t clock_seq_low;
|
||||
uint8_t node[6];
|
||||
} UUID;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -141,6 +141,7 @@ static const char *includefiles[] = {
|
|||
"DNA_volume_types.h",
|
||||
"DNA_simulation_types.h",
|
||||
"DNA_pointcache_types.h",
|
||||
"DNA_uuid_types.h",
|
||||
"DNA_asset_types.h",
|
||||
"DNA_sculpt_brush_types.h",
|
||||
|
||||
|
@ -1680,6 +1681,7 @@ int main(int argc, char **argv)
|
|||
#include "DNA_texture_types.h"
|
||||
#include "DNA_tracking_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
#include "DNA_uuid_types.h"
|
||||
#include "DNA_vec_types.h"
|
||||
#include "DNA_vfont_types.h"
|
||||
#include "DNA_view2d_types.h"
|
||||
|
|
|
@ -6060,6 +6060,7 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna)
|
|||
|
||||
static const EnumPropertyItem preview_type_items[] = {
|
||||
{USER_FILE_PREVIEW_NONE, "NONE", 0, "None", "Do not create blend previews"},
|
||||
{USER_FILE_PREVIEW_AUTO, "AUTO", 0, "Auto", "Automatically select best preview type"},
|
||||
{USER_FILE_PREVIEW_SCREENSHOT, "SCREENSHOT", 0, "Screenshot", "Capture the entire window"},
|
||||
{USER_FILE_PREVIEW_CAMERA, "CAMERA", 0, "Camera View", "Workbench render of scene"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
|
|
|
@ -440,8 +440,7 @@ const EnumPropertyItem rna_enum_event_type_mask_items[] = {
|
|||
static const EnumPropertyItem keymap_modifiers_items[] = {
|
||||
{KM_ANY, "ANY", 0, "Any", ""},
|
||||
{0, "NONE", 0, "None", ""},
|
||||
{1, "FIRST", 0, "First", ""},
|
||||
{2, "SECOND", 0, "Second", ""},
|
||||
{KM_MOD_HELD, "HELD", 0, "Held", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
#endif
|
||||
|
@ -468,6 +467,13 @@ const EnumPropertyItem rna_enum_operator_type_flag_items[] = {
|
|||
"is enabled"},
|
||||
{OPTYPE_GRAB_CURSOR_X, "GRAB_CURSOR_X", 0, "Grab Pointer X", "Grab, only warping the X axis"},
|
||||
{OPTYPE_GRAB_CURSOR_Y, "GRAB_CURSOR_Y", 0, "Grab Pointer Y", "Grab, only warping the Y axis"},
|
||||
{OPTYPE_DEPENDS_ON_CURSOR,
|
||||
"DEPENDS_ON_CURSOR",
|
||||
0,
|
||||
"Depends on Cursor",
|
||||
"The initial cursor location is used, "
|
||||
"when running from a menus or buttons the user is prompted to place the cursor "
|
||||
"before beginning the operation"},
|
||||
{OPTYPE_PRESET, "PRESET", 0, "Preset", "Display a preset button with the operators settings"},
|
||||
{OPTYPE_INTERNAL, "INTERNAL", 0, "Internal", "Removes the operator from search results"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
|
@ -2725,38 +2731,62 @@ static void rna_def_keyconfig(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Any", "Any modifier keys pressed");
|
||||
RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
|
||||
|
||||
prop = RNA_def_property(srna, "shift", PROP_BOOLEAN, PROP_NONE);
|
||||
prop = RNA_def_property(srna, "shift", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "shift");
|
||||
RNA_def_property_range(prop, KM_ANY, KM_MOD_HELD);
|
||||
RNA_def_property_ui_text(prop, "Shift", "Shift key pressed, -1 for any state");
|
||||
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_WINDOWMANAGER);
|
||||
RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
|
||||
|
||||
prop = RNA_def_property(srna, "ctrl", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "ctrl");
|
||||
RNA_def_property_range(prop, KM_ANY, KM_MOD_HELD);
|
||||
RNA_def_property_ui_text(prop, "Ctrl", "Control key pressed, -1 for any state");
|
||||
RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
|
||||
|
||||
prop = RNA_def_property(srna, "alt", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "alt");
|
||||
RNA_def_property_range(prop, KM_ANY, KM_MOD_HELD);
|
||||
RNA_def_property_ui_text(prop, "Alt", "Alt key pressed, -1 for any state");
|
||||
RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
|
||||
|
||||
prop = RNA_def_property(srna, "oskey", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "oskey");
|
||||
RNA_def_property_range(prop, KM_ANY, KM_MOD_HELD);
|
||||
RNA_def_property_ui_text(prop, "OS Key", "Operating system key pressed, -1 for any state");
|
||||
RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
|
||||
|
||||
/* XXX(@campbellbarton): the `*_ui` suffix is only for the UI, may be removed,
|
||||
* since this is only exposed so the UI can show these settings as toggle-buttons. */
|
||||
prop = RNA_def_property(srna, "shift_ui", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "shift", 0);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_KeyMapItem_shift_get", NULL);
|
||||
/* RNA_def_property_enum_sdna(prop, NULL, "shift"); */
|
||||
/* RNA_def_property_enum_items(prop, keymap_modifiers_items); */
|
||||
RNA_def_property_ui_text(prop, "Shift", "Shift key pressed");
|
||||
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_WINDOWMANAGER);
|
||||
RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
|
||||
|
||||
prop = RNA_def_property(srna, "ctrl", PROP_BOOLEAN, PROP_NONE);
|
||||
prop = RNA_def_property(srna, "ctrl_ui", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "ctrl", 0);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_KeyMapItem_ctrl_get", NULL);
|
||||
/* RNA_def_property_enum_sdna(prop, NULL, "ctrl"); */
|
||||
/* RNA_def_property_enum_items(prop, keymap_modifiers_items); */
|
||||
RNA_def_property_ui_text(prop, "Ctrl", "Control key pressed");
|
||||
RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
|
||||
|
||||
prop = RNA_def_property(srna, "alt", PROP_BOOLEAN, PROP_NONE);
|
||||
prop = RNA_def_property(srna, "alt_ui", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "alt", 0);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_KeyMapItem_alt_get", NULL);
|
||||
/* RNA_def_property_enum_sdna(prop, NULL, "alt"); */
|
||||
/* RNA_def_property_enum_items(prop, keymap_modifiers_items); */
|
||||
RNA_def_property_ui_text(prop, "Alt", "Alt key pressed");
|
||||
RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
|
||||
|
||||
prop = RNA_def_property(srna, "oskey", PROP_BOOLEAN, PROP_NONE);
|
||||
prop = RNA_def_property(srna, "oskey_ui", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "oskey", 0);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_KeyMapItem_oskey_get", NULL);
|
||||
/* RNA_def_property_enum_sdna(prop, NULL, "oskey"); */
|
||||
/* RNA_def_property_enum_items(prop, keymap_modifiers_items); */
|
||||
RNA_def_property_ui_text(prop, "OS Key", "Operating system key pressed");
|
||||
RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
|
||||
/* End `_ui` modifiers. */
|
||||
|
||||
prop = RNA_def_property(srna, "key_modifier", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "keymodifier");
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
#include "wm_cursors.h"
|
||||
#include "wm_event_types.h"
|
||||
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "rna_internal.h" /* own include */
|
||||
|
||||
/* confusing 2 enums mixed up here */
|
||||
|
@ -216,50 +218,71 @@ static int rna_Operator_props_popup(bContext *C, wmOperator *op, wmEvent *event)
|
|||
return WM_operator_props_popup(C, op, event);
|
||||
}
|
||||
|
||||
static int keymap_item_modifier_flag_from_args(bool any, int shift, int ctrl, int alt, int oskey)
|
||||
{
|
||||
int modifier = 0;
|
||||
if (any) {
|
||||
modifier = KM_ANY;
|
||||
}
|
||||
else {
|
||||
if (shift == KM_MOD_HELD) {
|
||||
modifier |= KM_SHIFT;
|
||||
}
|
||||
else if (shift == KM_ANY) {
|
||||
modifier |= KM_SHIFT_ANY;
|
||||
}
|
||||
|
||||
if (ctrl == KM_MOD_HELD) {
|
||||
modifier |= KM_CTRL;
|
||||
}
|
||||
else if (ctrl == KM_ANY) {
|
||||
modifier |= KM_CTRL_ANY;
|
||||
}
|
||||
|
||||
if (alt == KM_MOD_HELD) {
|
||||
modifier |= KM_ALT;
|
||||
}
|
||||
else if (alt == KM_ANY) {
|
||||
modifier |= KM_ALT_ANY;
|
||||
}
|
||||
|
||||
if (oskey == KM_MOD_HELD) {
|
||||
modifier |= KM_OSKEY;
|
||||
}
|
||||
else if (oskey == KM_ANY) {
|
||||
modifier |= KM_OSKEY_ANY;
|
||||
}
|
||||
}
|
||||
return modifier;
|
||||
}
|
||||
|
||||
static wmKeyMapItem *rna_KeyMap_item_new(wmKeyMap *km,
|
||||
ReportList *reports,
|
||||
const char *idname,
|
||||
int type,
|
||||
int value,
|
||||
bool any,
|
||||
bool shift,
|
||||
bool ctrl,
|
||||
bool alt,
|
||||
bool oskey,
|
||||
int shift,
|
||||
int ctrl,
|
||||
int alt,
|
||||
int oskey,
|
||||
int keymodifier,
|
||||
bool repeat,
|
||||
bool head)
|
||||
{
|
||||
// wmWindowManager *wm = CTX_wm_manager(C);
|
||||
wmKeyMapItem *kmi = NULL;
|
||||
char idname_bl[OP_MAX_TYPENAME];
|
||||
int modifier = 0;
|
||||
|
||||
/* only on non-modal maps */
|
||||
if (km->flag & KEYMAP_MODAL) {
|
||||
BKE_report(reports, RPT_ERROR, "Not a non-modal keymap");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// wmWindowManager *wm = CTX_wm_manager(C);
|
||||
wmKeyMapItem *kmi = NULL;
|
||||
char idname_bl[OP_MAX_TYPENAME];
|
||||
const int modifier = keymap_item_modifier_flag_from_args(any, shift, ctrl, alt, oskey);
|
||||
|
||||
WM_operator_bl_idname(idname_bl, idname);
|
||||
|
||||
if (shift) {
|
||||
modifier |= KM_SHIFT;
|
||||
}
|
||||
if (ctrl) {
|
||||
modifier |= KM_CTRL;
|
||||
}
|
||||
if (alt) {
|
||||
modifier |= KM_ALT;
|
||||
}
|
||||
if (oskey) {
|
||||
modifier |= KM_OSKEY;
|
||||
}
|
||||
|
||||
if (any) {
|
||||
modifier = KM_ANY;
|
||||
}
|
||||
|
||||
/* create keymap item */
|
||||
kmi = WM_keymap_add_item(km, idname_bl, type, value, modifier, keymodifier);
|
||||
|
||||
|
@ -305,39 +328,22 @@ static wmKeyMapItem *rna_KeyMap_item_new_modal(wmKeyMap *km,
|
|||
int type,
|
||||
int value,
|
||||
bool any,
|
||||
bool shift,
|
||||
bool ctrl,
|
||||
bool alt,
|
||||
bool oskey,
|
||||
int shift,
|
||||
int ctrl,
|
||||
int alt,
|
||||
int oskey,
|
||||
int keymodifier,
|
||||
bool repeat)
|
||||
{
|
||||
wmKeyMapItem *kmi = NULL;
|
||||
int modifier = 0;
|
||||
int propvalue = 0;
|
||||
|
||||
/* only modal maps */
|
||||
if ((km->flag & KEYMAP_MODAL) == 0) {
|
||||
BKE_report(reports, RPT_ERROR, "Not a modal keymap");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (shift) {
|
||||
modifier |= KM_SHIFT;
|
||||
}
|
||||
if (ctrl) {
|
||||
modifier |= KM_CTRL;
|
||||
}
|
||||
if (alt) {
|
||||
modifier |= KM_ALT;
|
||||
}
|
||||
if (oskey) {
|
||||
modifier |= KM_OSKEY;
|
||||
}
|
||||
|
||||
if (any) {
|
||||
modifier = KM_ANY;
|
||||
}
|
||||
wmKeyMapItem *kmi = NULL;
|
||||
const int modifier = keymap_item_modifier_flag_from_args(any, shift, ctrl, alt, oskey);
|
||||
int propvalue = 0;
|
||||
|
||||
/* not initialized yet, do delayed lookup */
|
||||
if (!km->modal_items) {
|
||||
|
@ -641,7 +647,7 @@ static wmEvent *rna_Window_event_add_simulate(wmWindow *win,
|
|||
e.is_repeat = false;
|
||||
e.x = x;
|
||||
e.y = y;
|
||||
/* NOTE: KM_MOD_FIRST, KM_MOD_SECOND aren't used anywhere, set as bools. */
|
||||
|
||||
e.shift = shift;
|
||||
e.ctrl = ctrl;
|
||||
e.alt = alt;
|
||||
|
@ -1131,10 +1137,10 @@ void RNA_api_keymapitems(StructRNA *srna)
|
|||
parm = RNA_def_enum(func, "value", rna_enum_event_value_all_items, 0, "Value", "");
|
||||
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
|
||||
RNA_def_boolean(func, "any", 0, "Any", "");
|
||||
RNA_def_boolean(func, "shift", 0, "Shift", "");
|
||||
RNA_def_boolean(func, "ctrl", 0, "Ctrl", "");
|
||||
RNA_def_boolean(func, "alt", 0, "Alt", "");
|
||||
RNA_def_boolean(func, "oskey", 0, "OS Key", "");
|
||||
RNA_def_int(func, "shift", KM_NOTHING, KM_ANY, KM_MOD_HELD, "Shift", "", KM_ANY, KM_MOD_HELD);
|
||||
RNA_def_int(func, "ctrl", KM_NOTHING, KM_ANY, KM_MOD_HELD, "Ctrl", "", KM_ANY, KM_MOD_HELD);
|
||||
RNA_def_int(func, "alt", KM_NOTHING, KM_ANY, KM_MOD_HELD, "Alt", "", KM_ANY, KM_MOD_HELD);
|
||||
RNA_def_int(func, "oskey", KM_NOTHING, KM_ANY, KM_MOD_HELD, "OS Key", "", KM_ANY, KM_MOD_HELD);
|
||||
RNA_def_enum(func, "key_modifier", rna_enum_event_type_items, 0, "Key Modifier", "");
|
||||
RNA_def_boolean(func, "repeat", false, "Repeat", "When set, accept key-repeat events");
|
||||
RNA_def_boolean(func,
|
||||
|
@ -1155,10 +1161,10 @@ void RNA_api_keymapitems(StructRNA *srna)
|
|||
parm = RNA_def_enum(func, "value", rna_enum_event_value_all_items, 0, "Value", "");
|
||||
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
|
||||
RNA_def_boolean(func, "any", 0, "Any", "");
|
||||
RNA_def_boolean(func, "shift", 0, "Shift", "");
|
||||
RNA_def_boolean(func, "ctrl", 0, "Ctrl", "");
|
||||
RNA_def_boolean(func, "alt", 0, "Alt", "");
|
||||
RNA_def_boolean(func, "oskey", 0, "OS Key", "");
|
||||
RNA_def_int(func, "shift", KM_NOTHING, KM_ANY, KM_MOD_HELD, "Shift", "", KM_ANY, KM_MOD_HELD);
|
||||
RNA_def_int(func, "ctrl", KM_NOTHING, KM_ANY, KM_MOD_HELD, "Ctrl", "", KM_ANY, KM_MOD_HELD);
|
||||
RNA_def_int(func, "alt", KM_NOTHING, KM_ANY, KM_MOD_HELD, "Alt", "", KM_ANY, KM_MOD_HELD);
|
||||
RNA_def_int(func, "oskey", KM_NOTHING, KM_ANY, KM_MOD_HELD, "OS Key", "", KM_ANY, KM_MOD_HELD);
|
||||
RNA_def_enum(func, "key_modifier", rna_enum_event_type_items, 0, "Key Modifier", "");
|
||||
RNA_def_boolean(func, "repeat", false, "Repeat", "When set, accept key-repeat events");
|
||||
parm = RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item");
|
||||
|
|
|
@ -68,6 +68,8 @@
|
|||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_enum_types.h"
|
||||
|
||||
|
@ -291,6 +293,17 @@ static bool logging_enabled(const ModifierEvalContext *ctx)
|
|||
return true;
|
||||
}
|
||||
|
||||
static const std::string use_attribute_suffix = "_use_attribute";
|
||||
static const std::string attribute_name_suffix = "_attribute_name";
|
||||
|
||||
/**
|
||||
* \return Whether using an attribute to input values of this type is supported.
|
||||
*/
|
||||
static bool socket_type_has_attribute_toggle(const bNodeSocket &socket)
|
||||
{
|
||||
return ELEM(socket.type, SOCK_FLOAT, SOCK_VECTOR, SOCK_BOOLEAN, SOCK_RGBA, SOCK_INT);
|
||||
}
|
||||
|
||||
static IDProperty *id_property_create_from_socket(const bNodeSocket &socket)
|
||||
{
|
||||
switch (socket.type) {
|
||||
|
@ -546,6 +559,32 @@ void MOD_nodes_update_interface(Object *object, NodesModifierData *nmd)
|
|||
new_prop->ui_data = ui_data;
|
||||
}
|
||||
}
|
||||
|
||||
if (socket_type_has_attribute_toggle(*socket)) {
|
||||
const std::string use_attribute_id = socket->identifier + use_attribute_suffix;
|
||||
const std::string attribute_name_id = socket->identifier + attribute_name_suffix;
|
||||
|
||||
IDPropertyTemplate idprop = {0};
|
||||
IDProperty *use_attribute_prop = IDP_New(IDP_INT, &idprop, use_attribute_id.c_str());
|
||||
IDP_AddToGroup(nmd->settings.properties, use_attribute_prop);
|
||||
|
||||
IDProperty *attribute_prop = IDP_New(IDP_STRING, &idprop, attribute_name_id.c_str());
|
||||
IDP_AddToGroup(nmd->settings.properties, attribute_prop);
|
||||
|
||||
if (old_properties != nullptr) {
|
||||
IDProperty *old_prop_use_attribute = IDP_GetPropertyFromGroup(old_properties,
|
||||
use_attribute_id.c_str());
|
||||
if (old_prop_use_attribute != nullptr) {
|
||||
IDP_CopyPropertyContent(use_attribute_prop, old_prop_use_attribute);
|
||||
}
|
||||
|
||||
IDProperty *old_attribute_name_prop = IDP_GetPropertyFromGroup(old_properties,
|
||||
attribute_name_id.c_str());
|
||||
if (old_attribute_name_prop != nullptr) {
|
||||
IDP_CopyPropertyContent(attribute_prop, old_attribute_name_prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (old_properties != nullptr) {
|
||||
|
@ -601,8 +640,33 @@ static void initialize_group_input(NodesModifierData &nmd,
|
|||
return;
|
||||
}
|
||||
|
||||
init_socket_cpp_value_from_property(
|
||||
*property, static_cast<eNodeSocketDatatype>(socket.type), r_value);
|
||||
if (!socket_type_has_attribute_toggle(socket)) {
|
||||
init_socket_cpp_value_from_property(
|
||||
*property, static_cast<eNodeSocketDatatype>(socket.type), r_value);
|
||||
return;
|
||||
}
|
||||
|
||||
const IDProperty *property_use_attribute = IDP_GetPropertyFromGroup(
|
||||
nmd.settings.properties, (socket.identifier + use_attribute_suffix).c_str());
|
||||
const IDProperty *property_attribute_name = IDP_GetPropertyFromGroup(
|
||||
nmd.settings.properties, (socket.identifier + attribute_name_suffix).c_str());
|
||||
if (property_use_attribute == nullptr || property_attribute_name == nullptr) {
|
||||
init_socket_cpp_value_from_property(
|
||||
*property, static_cast<eNodeSocketDatatype>(socket.type), r_value);
|
||||
return;
|
||||
}
|
||||
|
||||
const bool use_attribute = IDP_Int(property_use_attribute) != 0;
|
||||
if (use_attribute) {
|
||||
const StringRef attribute_name{IDP_String(property_attribute_name)};
|
||||
auto attribute_input = std::make_shared<blender::bke::AttributeFieldInput>(
|
||||
attribute_name, *socket.typeinfo->get_base_cpp_type());
|
||||
new (r_value) blender::fn::GField(std::move(attribute_input), 0);
|
||||
}
|
||||
else {
|
||||
init_socket_cpp_value_from_property(
|
||||
*property, static_cast<eNodeSocketDatatype>(socket.type), r_value);
|
||||
}
|
||||
}
|
||||
|
||||
static Vector<SpaceSpreadsheet *> find_spreadsheet_editors(Main *bmain)
|
||||
|
@ -912,13 +976,13 @@ static void modifyGeometrySet(ModifierData *md,
|
|||
* the node socket identifier for the property names, since they are unique, but also having
|
||||
* the correct label displayed in the UI. */
|
||||
static void draw_property_for_socket(uiLayout *layout,
|
||||
NodesModifierData *nmd,
|
||||
PointerRNA *bmain_ptr,
|
||||
PointerRNA *md_ptr,
|
||||
const IDProperty *modifier_props,
|
||||
const bNodeSocket &socket)
|
||||
{
|
||||
/* The property should be created in #MOD_nodes_update_interface with the correct type. */
|
||||
IDProperty *property = IDP_GetPropertyFromGroup(modifier_props, socket.identifier);
|
||||
IDProperty *property = IDP_GetPropertyFromGroup(nmd->settings.properties, socket.identifier);
|
||||
|
||||
/* IDProperties can be removed with python, so there could be a situation where
|
||||
* there isn't a property for a socket or it doesn't have the correct type. */
|
||||
|
@ -959,8 +1023,38 @@ static void draw_property_for_socket(uiLayout *layout,
|
|||
uiItemPointerR(layout, md_ptr, rna_path, bmain_ptr, "textures", socket.name, ICON_TEXTURE);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
uiItemR(layout, md_ptr, rna_path, 0, socket.name, ICON_NONE);
|
||||
default: {
|
||||
if (socket_type_has_attribute_toggle(socket) &&
|
||||
USER_EXPERIMENTAL_TEST(&U, use_geometry_nodes_fields)) {
|
||||
const std::string rna_path_use_attribute = "[\"" + std::string(socket_id_esc) +
|
||||
use_attribute_suffix + "\"]";
|
||||
const std::string rna_path_attribute_name = "[\"" + std::string(socket_id_esc) +
|
||||
attribute_name_suffix + "\"]";
|
||||
|
||||
uiLayout *row = uiLayoutRow(layout, true);
|
||||
const int use_attribute = RNA_int_get(md_ptr, rna_path_use_attribute.c_str()) != 0;
|
||||
if (use_attribute) {
|
||||
uiItemR(row, md_ptr, rna_path_attribute_name.c_str(), 0, socket.name, ICON_NONE);
|
||||
}
|
||||
else {
|
||||
uiItemR(row, md_ptr, rna_path, 0, socket.name, ICON_NONE);
|
||||
}
|
||||
PointerRNA props;
|
||||
uiItemFullO(row,
|
||||
"object.geometry_nodes_input_attribute_toggle",
|
||||
"",
|
||||
ICON_SPREADSHEET,
|
||||
nullptr,
|
||||
WM_OP_INVOKE_DEFAULT,
|
||||
0,
|
||||
&props);
|
||||
RNA_string_set(&props, "modifier_name", nmd->modifier.name);
|
||||
RNA_string_set(&props, "prop_path", rna_path_use_attribute.c_str());
|
||||
}
|
||||
else {
|
||||
uiItemR(layout, md_ptr, rna_path, 0, socket.name, ICON_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -991,7 +1085,7 @@ static void panel_draw(const bContext *C, Panel *panel)
|
|||
RNA_main_pointer_create(bmain, &bmain_ptr);
|
||||
|
||||
LISTBASE_FOREACH (bNodeSocket *, socket, &nmd->node_group->inputs) {
|
||||
draw_property_for_socket(layout, &bmain_ptr, ptr, nmd->settings.properties, *socket);
|
||||
draw_property_for_socket(layout, nmd, &bmain_ptr, ptr, *socket);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -472,6 +472,12 @@ int WM_operator_call_py(struct bContext *C,
|
|||
struct ReportList *reports,
|
||||
const bool is_undo);
|
||||
|
||||
void WM_operator_name_call_ptr_with_depends_on_cursor(struct bContext *C,
|
||||
wmOperatorType *ot,
|
||||
short opcontext,
|
||||
PointerRNA *properties,
|
||||
const char *drawstr);
|
||||
|
||||
/* Used for keymap and macro items. */
|
||||
void WM_operator_properties_alloc(struct PointerRNA **ptr,
|
||||
struct IDProperty **properties,
|
||||
|
|
|
@ -184,6 +184,17 @@ enum {
|
|||
OPTYPE_LOCK_BYPASS = (1 << 9),
|
||||
/** Special type of undo which doesn't store itself multiple times. */
|
||||
OPTYPE_UNDO_GROUPED = (1 << 10),
|
||||
|
||||
/**
|
||||
* Depends on the cursor location, when activated from a menu wait for mouse press.
|
||||
*
|
||||
* In practice these operators often end up being accessed:
|
||||
* - Directly from key bindings.
|
||||
* - As tools in the toolbar.
|
||||
*
|
||||
* Even so, accessing from the menu should behave usefully.
|
||||
*/
|
||||
OPTYPE_DEPENDS_ON_CURSOR = (1 << 11),
|
||||
};
|
||||
|
||||
/** For #WM_cursor_grab_enable wrap axis. */
|
||||
|
@ -228,16 +239,16 @@ typedef enum eOperatorPropTags {
|
|||
#define KM_CTRL 2
|
||||
#define KM_ALT 4
|
||||
#define KM_OSKEY 8
|
||||
/* means modifier should be pressed 2nd */
|
||||
#define KM_SHIFT2 16
|
||||
#define KM_CTRL2 32
|
||||
#define KM_ALT2 64
|
||||
#define KM_OSKEY2 128
|
||||
|
||||
/* Used for key-map item creation function arguments (never stored in DNA). */
|
||||
#define KM_SHIFT_ANY 16
|
||||
#define KM_CTRL_ANY 32
|
||||
#define KM_ALT_ANY 64
|
||||
#define KM_OSKEY_ANY 128
|
||||
|
||||
/* KM_MOD_ flags for `wmKeyMapItem` and `wmEvent.alt/shift/oskey/ctrl`. */
|
||||
/* note that KM_ANY and KM_NOTHING are used with these defines too */
|
||||
#define KM_MOD_FIRST 1
|
||||
#define KM_MOD_SECOND 2
|
||||
#define KM_MOD_HELD 1
|
||||
|
||||
/* type: defined in wm_event_types.c */
|
||||
#define KM_TEXTINPUT -2
|
||||
|
|
|
@ -1146,5 +1146,31 @@ void wm_init_cursor_data(void)
|
|||
BlenderCursor[WM_CURSOR_ZOOM_OUT] = &ZoomOutCursor;
|
||||
END_CURSOR_BLOCK;
|
||||
|
||||
/********************** Area Pick Cursor ***********************/
|
||||
BEGIN_CURSOR_BLOCK;
|
||||
|
||||
static char pick_area_bitmap[] = {
|
||||
0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0xfe, 0x00, 0x10,
|
||||
0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0xbf, 0x00, 0x81, 0x00, 0x81,
|
||||
0x00, 0x81, 0x00, 0x81, 0x00, 0x81, 0x00, 0x80, 0x00, 0xff,
|
||||
};
|
||||
|
||||
static char pick_area_mask[] = {
|
||||
0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0xff, 0x01, 0xff, 0x01, 0xff,
|
||||
0x01, 0x38, 0x00, 0xb8, 0x7f, 0xb8, 0xff, 0x80, 0xc1, 0x80, 0xc1,
|
||||
0x80, 0xc1, 0x80, 0xc1, 0x80, 0xc1, 0x80, 0xff, 0x00, 0xff,
|
||||
};
|
||||
|
||||
static BCursor PickAreaCursor = {
|
||||
pick_area_bitmap,
|
||||
pick_area_mask,
|
||||
4,
|
||||
4,
|
||||
false,
|
||||
};
|
||||
|
||||
BlenderCursor[WM_CURSOR_PICK_AREA] = &PickAreaCursor;
|
||||
END_CURSOR_BLOCK;
|
||||
|
||||
/********************** Put the cursors in the array ***********************/
|
||||
}
|
||||
|
|
|
@ -1672,6 +1672,172 @@ int WM_operator_call_py(bContext *C,
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Operator Wait For Input
|
||||
*
|
||||
* Delay executing operators that depend on cursor location.
|
||||
*
|
||||
* See: #OPTYPE_DEPENDS_ON_CURSOR doc-string for more information.
|
||||
* \{ */
|
||||
|
||||
typedef struct uiOperatorWaitForInput {
|
||||
ScrArea *area;
|
||||
wmOperatorCallParams optype_params;
|
||||
bContextStore *context;
|
||||
} uiOperatorWaitForInput;
|
||||
|
||||
static void ui_handler_wait_for_input_remove(bContext *C, void *userdata)
|
||||
{
|
||||
uiOperatorWaitForInput *opwait = userdata;
|
||||
if (opwait->optype_params.opptr) {
|
||||
if (opwait->optype_params.opptr->data) {
|
||||
IDP_FreeProperty(opwait->optype_params.opptr->data);
|
||||
}
|
||||
MEM_freeN(opwait->optype_params.opptr);
|
||||
}
|
||||
if (opwait->context) {
|
||||
CTX_store_free(opwait->context);
|
||||
}
|
||||
|
||||
if (opwait->area != NULL) {
|
||||
ED_area_status_text(opwait->area, NULL);
|
||||
}
|
||||
else {
|
||||
ED_workspace_status_text(C, NULL);
|
||||
}
|
||||
|
||||
MEM_freeN(opwait);
|
||||
}
|
||||
|
||||
static int ui_handler_wait_for_input(bContext *C, const wmEvent *event, void *userdata)
|
||||
{
|
||||
uiOperatorWaitForInput *opwait = userdata;
|
||||
enum { CONTINUE = 0, EXECUTE, CANCEL } state = CONTINUE;
|
||||
state = CONTINUE;
|
||||
|
||||
switch (event->type) {
|
||||
case LEFTMOUSE: {
|
||||
if (event->val == KM_PRESS) {
|
||||
state = EXECUTE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Useful if the operator isn't convenient to access while the mouse button is held.
|
||||
* If it takes numeric input for example. */
|
||||
case EVT_SPACEKEY:
|
||||
case EVT_RETKEY: {
|
||||
if (event->val == KM_PRESS) {
|
||||
state = EXECUTE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RIGHTMOUSE: {
|
||||
if (event->val == KM_PRESS) {
|
||||
state = CANCEL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVT_ESCKEY: {
|
||||
if (event->val == KM_PRESS) {
|
||||
state = CANCEL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (state != CONTINUE) {
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
WM_cursor_modal_restore(win);
|
||||
|
||||
if (state == EXECUTE) {
|
||||
CTX_store_set(C, opwait->context);
|
||||
WM_operator_name_call_ptr(C,
|
||||
opwait->optype_params.optype,
|
||||
opwait->optype_params.opcontext,
|
||||
opwait->optype_params.opptr);
|
||||
CTX_store_set(C, NULL);
|
||||
}
|
||||
|
||||
WM_event_remove_ui_handler(&win->modalhandlers,
|
||||
ui_handler_wait_for_input,
|
||||
ui_handler_wait_for_input_remove,
|
||||
opwait,
|
||||
false);
|
||||
|
||||
ui_handler_wait_for_input_remove(C, opwait);
|
||||
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
|
||||
return WM_UI_HANDLER_CONTINUE;
|
||||
}
|
||||
|
||||
void WM_operator_name_call_ptr_with_depends_on_cursor(
|
||||
bContext *C, wmOperatorType *ot, short opcontext, PointerRNA *properties, const char *drawstr)
|
||||
{
|
||||
int flag = ot->flag;
|
||||
|
||||
LISTBASE_FOREACH (wmOperatorTypeMacro *, macro, &ot->macro) {
|
||||
wmOperatorType *otm = WM_operatortype_find(macro->idname, 0);
|
||||
if (otm != NULL) {
|
||||
flag |= otm->flag;
|
||||
}
|
||||
}
|
||||
|
||||
if ((flag & OPTYPE_DEPENDS_ON_CURSOR) == 0) {
|
||||
WM_operator_name_call_ptr(C, ot, opcontext, properties);
|
||||
return;
|
||||
}
|
||||
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
|
||||
{
|
||||
char header_text[UI_MAX_DRAW_STR];
|
||||
SNPRINTF(header_text,
|
||||
"%s %s",
|
||||
IFACE_("Input pending "),
|
||||
(drawstr && drawstr[0]) ? drawstr : CTX_IFACE_(ot->translation_context, ot->name));
|
||||
if (area != NULL) {
|
||||
ED_area_status_text(area, header_text);
|
||||
}
|
||||
else {
|
||||
ED_workspace_status_text(C, header_text);
|
||||
}
|
||||
}
|
||||
|
||||
WM_cursor_modal_set(win, WM_CURSOR_PICK_AREA);
|
||||
|
||||
uiOperatorWaitForInput *opwait = MEM_callocN(sizeof(*opwait), __func__);
|
||||
opwait->optype_params.optype = ot;
|
||||
opwait->optype_params.opcontext = opcontext;
|
||||
opwait->optype_params.opptr = properties;
|
||||
|
||||
opwait->area = area;
|
||||
|
||||
if (properties) {
|
||||
opwait->optype_params.opptr = MEM_mallocN(sizeof(*opwait->optype_params.opptr), __func__);
|
||||
*opwait->optype_params.opptr = *properties;
|
||||
if (properties->data != NULL) {
|
||||
opwait->optype_params.opptr->data = IDP_CopyProperty(properties->data);
|
||||
}
|
||||
}
|
||||
|
||||
bContextStore *store = CTX_store_get(C);
|
||||
if (store) {
|
||||
opwait->context = CTX_store_copy(store);
|
||||
}
|
||||
|
||||
WM_event_add_ui_handler(C,
|
||||
&win->modalhandlers,
|
||||
ui_handler_wait_for_input,
|
||||
ui_handler_wait_for_input_remove,
|
||||
opwait,
|
||||
WM_HANDLER_BLOCKING);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Handler Types
|
||||
*
|
||||
|
@ -4692,47 +4858,27 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void
|
|||
case EVT_LEFTSHIFTKEY:
|
||||
case EVT_RIGHTSHIFTKEY:
|
||||
if (event.val == KM_PRESS) {
|
||||
if (event_state->ctrl || event_state->alt || event_state->oskey) {
|
||||
keymodifier = (KM_MOD_FIRST | KM_MOD_SECOND);
|
||||
}
|
||||
else {
|
||||
keymodifier = KM_MOD_FIRST;
|
||||
}
|
||||
keymodifier = KM_MOD_HELD;
|
||||
}
|
||||
event.shift = event_state->shift = keymodifier;
|
||||
break;
|
||||
case EVT_LEFTCTRLKEY:
|
||||
case EVT_RIGHTCTRLKEY:
|
||||
if (event.val == KM_PRESS) {
|
||||
if (event_state->shift || event_state->alt || event_state->oskey) {
|
||||
keymodifier = (KM_MOD_FIRST | KM_MOD_SECOND);
|
||||
}
|
||||
else {
|
||||
keymodifier = KM_MOD_FIRST;
|
||||
}
|
||||
keymodifier = KM_MOD_HELD;
|
||||
}
|
||||
event.ctrl = event_state->ctrl = keymodifier;
|
||||
break;
|
||||
case EVT_LEFTALTKEY:
|
||||
case EVT_RIGHTALTKEY:
|
||||
if (event.val == KM_PRESS) {
|
||||
if (event_state->ctrl || event_state->shift || event_state->oskey) {
|
||||
keymodifier = (KM_MOD_FIRST | KM_MOD_SECOND);
|
||||
}
|
||||
else {
|
||||
keymodifier = KM_MOD_FIRST;
|
||||
}
|
||||
keymodifier = KM_MOD_HELD;
|
||||
}
|
||||
event.alt = event_state->alt = keymodifier;
|
||||
break;
|
||||
case EVT_OSKEY:
|
||||
if (event.val == KM_PRESS) {
|
||||
if (event_state->ctrl || event_state->alt || event_state->shift) {
|
||||
keymodifier = (KM_MOD_FIRST | KM_MOD_SECOND);
|
||||
}
|
||||
else {
|
||||
keymodifier = KM_MOD_FIRST;
|
||||
}
|
||||
keymodifier = KM_MOD_HELD;
|
||||
}
|
||||
event.oskey = event_state->oskey = keymodifier;
|
||||
break;
|
||||
|
|
|
@ -1527,10 +1527,6 @@ static ImBuf *blend_file_thumb_from_screenshot(bContext *C, BlendThumbnail **thu
|
|||
return BKE_main_thumbnail_to_imbuf(NULL, *thumb_pt);
|
||||
}
|
||||
|
||||
/* Redraw to remove menus that might be open. */
|
||||
WM_redraw_windows(C);
|
||||
WM_cursor_wait(true);
|
||||
|
||||
/* The window to capture should be a main window (without parent). */
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
while (win && win->parent) {
|
||||
|
@ -1563,7 +1559,6 @@ static ImBuf *blend_file_thumb_from_screenshot(bContext *C, BlendThumbnail **thu
|
|||
IMB_freeImBuf(thumb_ibuf);
|
||||
*thumb_pt = thumb;
|
||||
}
|
||||
WM_cursor_wait(false);
|
||||
|
||||
/* Must be freed by caller. */
|
||||
return ibuf;
|
||||
|
@ -1607,10 +1602,9 @@ static ImBuf *blend_file_thumb_from_camera(const bContext *C,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if ((scene->camera == NULL) && (screen != NULL)) {
|
||||
if (screen != NULL) {
|
||||
area = BKE_screen_find_big_area(screen, SPACE_VIEW3D, 0);
|
||||
region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW);
|
||||
if (region) {
|
||||
if (area) {
|
||||
v3d = area->spacedata.first;
|
||||
}
|
||||
}
|
||||
|
@ -1629,13 +1623,14 @@ static ImBuf *blend_file_thumb_from_camera(const bContext *C,
|
|||
if (scene->camera) {
|
||||
ibuf = ED_view3d_draw_offscreen_imbuf_simple(depsgraph,
|
||||
scene,
|
||||
NULL,
|
||||
OB_SOLID,
|
||||
(v3d) ? &v3d->shading : NULL,
|
||||
(v3d) ? v3d->shading.type : OB_SOLID,
|
||||
scene->camera,
|
||||
PREVIEW_RENDER_LARGE_HEIGHT * 2,
|
||||
PREVIEW_RENDER_LARGE_HEIGHT * 2,
|
||||
IB_rect,
|
||||
V3D_OFSDRAW_NONE,
|
||||
(v3d) ? V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS :
|
||||
V3D_OFSDRAW_NONE,
|
||||
R_ALPHAPREMUL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -1758,17 +1753,41 @@ static bool wm_file_write(bContext *C,
|
|||
/* Enforce full override check/generation on file save. */
|
||||
BKE_lib_override_library_main_operations_create(bmain, true);
|
||||
|
||||
if (!G.background) {
|
||||
/* Redraw to remove menus that might be open. */
|
||||
WM_redraw_windows(C);
|
||||
}
|
||||
|
||||
/* don't forget not to return without! */
|
||||
WM_cursor_wait(true);
|
||||
|
||||
/* blend file thumbnail */
|
||||
/* Save before exit_editmode, otherwise derivedmeshes for shared data corrupt T27765. */
|
||||
/* Main now can store a '.blend' thumbnail, useful for background mode
|
||||
* or thumbnail customization. */
|
||||
main_thumb = thumb = bmain->blen_thumb;
|
||||
if (BLI_thread_is_main()) {
|
||||
if (U.file_preview_type == USER_FILE_PREVIEW_SCREENSHOT) {
|
||||
ibuf_thumb = blend_file_thumb_from_screenshot(C, &thumb);
|
||||
if (BLI_thread_is_main() && U.file_preview_type != USER_FILE_PREVIEW_NONE) {
|
||||
|
||||
int file_preview_type = U.file_preview_type;
|
||||
|
||||
if (file_preview_type == USER_FILE_PREVIEW_AUTO) {
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
bool do_render = (scene != NULL && scene->camera != NULL &&
|
||||
(BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_VIEW3D, 0) != NULL));
|
||||
file_preview_type = do_render ? USER_FILE_PREVIEW_CAMERA : USER_FILE_PREVIEW_SCREENSHOT;
|
||||
}
|
||||
else if (U.file_preview_type == USER_FILE_PREVIEW_CAMERA) {
|
||||
ibuf_thumb = blend_file_thumb_from_camera(C, CTX_data_scene(C), CTX_wm_screen(C), &thumb);
|
||||
|
||||
switch (file_preview_type) {
|
||||
case USER_FILE_PREVIEW_SCREENSHOT: {
|
||||
ibuf_thumb = blend_file_thumb_from_screenshot(C, &thumb);
|
||||
break;
|
||||
}
|
||||
case USER_FILE_PREVIEW_CAMERA: {
|
||||
ibuf_thumb = blend_file_thumb_from_camera(C, CTX_data_scene(C), CTX_wm_screen(C), &thumb);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1778,9 +1797,6 @@ static bool wm_file_write(bContext *C,
|
|||
BKE_packedfile_pack_all(bmain, reports, false);
|
||||
}
|
||||
|
||||
/* don't forget not to return without! */
|
||||
WM_cursor_wait(true);
|
||||
|
||||
ED_editors_flush_edits(bmain);
|
||||
|
||||
/* First time saving. */
|
||||
|
|
|
@ -709,7 +709,7 @@ static void wm_append_do(WMLinkAppendData *lapp_data,
|
|||
break;
|
||||
case WM_APPEND_ACT_REUSE_LOCAL:
|
||||
/* We only need to set `newid` to ID found in previous loop, for proper remapping. */
|
||||
ID_NEW_SET(id->newid, item->customdata);
|
||||
ID_NEW_SET(id, item->customdata);
|
||||
/* This is not a 'new' local appended id, do not set `local_appended_new_id` here. */
|
||||
break;
|
||||
case WM_APPEND_ACT_UNSET:
|
||||
|
|
|
@ -818,6 +818,8 @@ void WM_OT_lasso_gesture(wmOperatorType *ot)
|
|||
|
||||
ot->poll = WM_operator_winactive;
|
||||
|
||||
ot->flag = OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
prop = RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_struct_runtime(ot->srna, prop, &RNA_OperatorMousePath);
|
||||
}
|
||||
|
|
|
@ -484,13 +484,20 @@ static void keymap_event_set(
|
|||
kmi->shift = kmi->ctrl = kmi->alt = kmi->oskey = KM_ANY;
|
||||
}
|
||||
else {
|
||||
kmi->shift = (modifier & KM_SHIFT) ? KM_MOD_FIRST :
|
||||
((modifier & KM_SHIFT2) ? KM_MOD_SECOND : false);
|
||||
kmi->ctrl = (modifier & KM_CTRL) ? KM_MOD_FIRST :
|
||||
((modifier & KM_CTRL2) ? KM_MOD_SECOND : false);
|
||||
kmi->alt = (modifier & KM_ALT) ? KM_MOD_FIRST : ((modifier & KM_ALT2) ? KM_MOD_SECOND : false);
|
||||
kmi->oskey = (modifier & KM_OSKEY) ? KM_MOD_FIRST :
|
||||
((modifier & KM_OSKEY2) ? KM_MOD_SECOND : false);
|
||||
/* Only one of the flags should be set. */
|
||||
BLI_assert(((modifier & (KM_SHIFT | KM_SHIFT_ANY)) != (KM_SHIFT | KM_SHIFT_ANY)) &&
|
||||
((modifier & (KM_CTRL | KM_CTRL_ANY)) != (KM_CTRL | KM_CTRL_ANY)) &&
|
||||
((modifier & (KM_ALT | KM_ALT_ANY)) != (KM_ALT | KM_ALT_ANY)) &&
|
||||
((modifier & (KM_OSKEY | KM_OSKEY_ANY)) != (KM_OSKEY | KM_OSKEY_ANY)));
|
||||
|
||||
kmi->shift = ((modifier & KM_SHIFT) ? KM_MOD_HELD :
|
||||
((modifier & KM_SHIFT_ANY) ? KM_ANY : KM_NOTHING));
|
||||
kmi->ctrl = ((modifier & KM_CTRL) ? KM_MOD_HELD :
|
||||
((modifier & KM_CTRL_ANY) ? KM_ANY : KM_NOTHING));
|
||||
kmi->alt = ((modifier & KM_ALT) ? KM_MOD_HELD :
|
||||
((modifier & KM_ALT_ANY) ? KM_ANY : KM_NOTHING));
|
||||
kmi->oskey = ((modifier & KM_OSKEY) ? KM_MOD_HELD :
|
||||
((modifier & KM_OSKEY_ANY) ? KM_ANY : KM_NOTHING));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1164,7 +1171,6 @@ int WM_keymap_item_raw_to_string(const short shift,
|
|||
|
||||
buf[0] = '\0';
|
||||
|
||||
/* TODO: support order (KM_SHIFT vs. KM_SHIFT2) ? */
|
||||
if (shift == KM_ANY && ctrl == KM_ANY && alt == KM_ANY && oskey == KM_ANY) {
|
||||
/* Don't show anything for any mapping. */
|
||||
}
|
||||
|
|
|
@ -1197,7 +1197,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
|
|||
#ifdef USE_WIN_ACTIVATE
|
||||
else {
|
||||
if (keymodifier & KM_SHIFT) {
|
||||
win->eventstate->shift = KM_MOD_FIRST;
|
||||
win->eventstate->shift = KM_MOD_HELD;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1210,7 +1210,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
|
|||
#ifdef USE_WIN_ACTIVATE
|
||||
else {
|
||||
if (keymodifier & KM_CTRL) {
|
||||
win->eventstate->ctrl = KM_MOD_FIRST;
|
||||
win->eventstate->ctrl = KM_MOD_HELD;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1223,7 +1223,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
|
|||
#ifdef USE_WIN_ACTIVATE
|
||||
else {
|
||||
if (keymodifier & KM_ALT) {
|
||||
win->eventstate->alt = KM_MOD_FIRST;
|
||||
win->eventstate->alt = KM_MOD_HELD;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1236,7 +1236,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
|
|||
#ifdef USE_WIN_ACTIVATE
|
||||
else {
|
||||
if (keymodifier & KM_OSKEY) {
|
||||
win->eventstate->oskey = KM_MOD_FIRST;
|
||||
win->eventstate->oskey = KM_MOD_HELD;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -74,6 +74,8 @@ typedef enum WMCursorType {
|
|||
WM_CURSOR_NONE,
|
||||
WM_CURSOR_MUTE,
|
||||
|
||||
WM_CURSOR_PICK_AREA,
|
||||
|
||||
/* --- ALWAYS LAST ----- */
|
||||
WM_CURSOR_NUM,
|
||||
} WMCursorType;
|
||||
|
|
Loading…
Reference in New Issue