diff options
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_material.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_mesh.h | 11 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_pointcloud.h | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/material.c | 21 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_convert.c | 97 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pointcloud.c | 29 | ||||
-rw-r--r-- | source/blender/editors/object/CMakeLists.txt | 5 | ||||
-rw-r--r-- | source/blender/editors/object/object_add.c | 59 |
9 files changed, 220 insertions, 11 deletions
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index a30d7d55985..a6d8d2d2d8b 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -99,6 +99,7 @@ void BKE_texpaint_slots_refresh_object(struct Scene *scene, struct Object *ob); struct bNode *BKE_texpaint_slot_material_find_node(struct Material *ma, short texpaint_slot); /* rna api */ +void BKE_id_materials_copy(struct Main *bmain, struct ID *id_src, struct ID *id_dst); void BKE_id_material_resize(struct Main *bmain, struct ID *id, short totcol, bool do_id_user); void BKE_id_material_append(struct Main *bmain, struct ID *id, struct Material *ma); struct Material *BKE_id_material_pop(struct Main *bmain, diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 6e8c67dde5f..39b15bdd48d 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -54,6 +54,7 @@ struct MemArena; struct Mesh; struct ModifierData; struct Object; +struct PointCloud; struct Scene; #ifdef __cplusplus @@ -172,6 +173,16 @@ void BKE_mesh_to_curve(struct Main *bmain, struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob); +void BKE_pointcloud_from_mesh(struct Mesh *me, struct PointCloud *pointcloud); +void BKE_mesh_to_pointcloud(struct Main *bmain, + struct Depsgraph *depsgraph, + struct Scene *scene, + struct Object *ob); +void BKE_mesh_from_pointcloud(struct PointCloud *pointcloud, struct Mesh *me); +void BKE_pointcloud_to_mesh(struct Main *bmain, + struct Depsgraph *depsgraph, + struct Scene *scene, + struct Object *ob); void BKE_mesh_material_index_remove(struct Mesh *me, short index); bool BKE_mesh_material_index_used(struct Mesh *me, short index); void BKE_mesh_material_index_clear(struct Mesh *me); diff --git a/source/blender/blenkernel/BKE_pointcloud.h b/source/blender/blenkernel/BKE_pointcloud.h index 295744af5b4..f850e716ea6 100644 --- a/source/blender/blenkernel/BKE_pointcloud.h +++ b/source/blender/blenkernel/BKE_pointcloud.h @@ -32,7 +32,12 @@ struct Object; struct PointCloud; struct Scene; +/* PointCloud datablock */ +extern const char *POINTCLOUD_ATTR_POSITION; +extern const char *POINTCLOUD_ATTR_RADIUS; + void *BKE_pointcloud_add(struct Main *bmain, const char *name); +void *BKE_pointcloud_add_default(struct Main *bmain, const char *name); struct PointCloud *BKE_pointcloud_copy(struct Main *bmain, const struct PointCloud *pointcloud); struct BoundBox *BKE_pointcloud_boundbox_get(struct Object *ob); diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 885cc1baefc..d8c0b5d6dce 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -535,6 +535,27 @@ static void material_data_index_clear_id(ID *id) } } +void BKE_id_materials_copy(Main *bmain, ID *id_src, ID *id_dst) +{ + Material ***matar_src = BKE_id_material_array_p(id_src); + const short *materials_len_p_src = BKE_id_material_len_p(id_src); + + Material ***matar_dst = BKE_id_material_array_p(id_dst); + short *materials_len_p_dst = BKE_id_material_len_p(id_dst); + + *materials_len_p_dst = *materials_len_p_src; + if (*materials_len_p_src != 0) { + (*matar_dst) = MEM_dupallocN(*matar_src); + + for (int a = 0; a < *materials_len_p_src; a++) { + id_us_plus((ID *)(*matar_dst)[a]); + } + + DEG_id_tag_update(id_dst, ID_RECALC_COPY_ON_WRITE); + DEG_relations_tag_update(bmain); + } +} + void BKE_id_material_resize(Main *bmain, ID *id, short totcol, bool do_id_user) { Material ***matar = BKE_id_material_array_p(id); diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c index 60a9ef2df55..557948ef3a4 100644 --- a/source/blender/blenkernel/intern/mesh_convert.c +++ b/source/blender/blenkernel/intern/mesh_convert.c @@ -28,6 +28,7 @@ #include "DNA_mesh_types.h" #include "DNA_meta_types.h" #include "DNA_object_types.h" +#include "DNA_pointcloud_types.h" #include "DNA_scene_types.h" #include "BLI_edgehash.h" @@ -53,6 +54,8 @@ #include "BKE_curve.h" /* -- */ #include "BKE_object.h" +/* -- */ +#include "BKE_pointcloud.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" @@ -903,6 +906,100 @@ 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); + + 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); + BKE_pointcloud_update_customdata_pointers(pointcloud); + CustomData_update_typemap(&pointcloud->pdata); + + MVert *mvert; + mvert = me->mvert; + for (int i = 0; i < me->totvert; i++, mvert++) { + copy_v3_v3(pointcloud->co[i], mvert->co); + } +} + +void BKE_mesh_to_pointcloud(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(scene), Object *ob) +{ + BLI_assert(ob->type == OB_MESH); + + 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); + + PointCloud *pointcloud = BKE_pointcloud_add(bmain, ob->id.name + 2); + + BKE_pointcloud_from_mesh(me_eval, pointcloud); + + BKE_id_materials_copy(bmain, (ID *)ob->data, (ID *)pointcloud); + + id_us_min(&((Mesh *)ob->data)->id); + ob->data = pointcloud; + ob->type = OB_POINTCLOUD; + + BKE_object_free_derived_caches(ob); +} + +void BKE_mesh_from_pointcloud(PointCloud *pointcloud, Mesh *me) +{ + BLI_assert(pointcloud != NULL); + + 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); + + /* Convert the Position attribute to a mesh vertex. */ + me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, 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; + + MVert *mvert; + mvert = me->mvert; + for (int i = 0; i < me->totvert; i++, mvert++) { + copy_v3_v3(mvert->co, positions[i]); + } + + /* Delete Position attribute since it is now in vertex coordinates. */ + CustomData_free_layer(&me->vdata, CD_PROP_FLOAT3, me->totvert, layer_idx); +} + +void BKE_pointcloud_to_mesh(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(scene), Object *ob) +{ + BLI_assert(ob->type == OB_POINTCLOUD); + + Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); + PointCloud *pointcloud_eval = (PointCloud *)ob_eval->runtime.data_eval; + + Mesh *me = BKE_mesh_add(bmain, ob->id.name + 2); + + BKE_mesh_from_pointcloud(pointcloud_eval, me); + + BKE_id_materials_copy(bmain, (ID *)ob->data, (ID *)me); + + id_us_min(&((PointCloud *)ob->data)->id); + ob->data = me; + ob->type = OB_MESH; + + BKE_object_free_derived_caches(ob); +} + /* Create a temporary object to be used for nurbs-to-mesh conversion. * * This is more complex that it should be because BKE_mesh_from_nurbs_displist() will do more than diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 07a20c417fe..23faaff7734 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -48,6 +48,7 @@ #include "DNA_meta_types.h" #include "DNA_movieclip_types.h" #include "DNA_object_types.h" +#include "DNA_pointcloud_types.h" #include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" @@ -1285,7 +1286,7 @@ void *BKE_object_obdata_add_from_type(Main *bmain, int type, const char *name) case OB_HAIR: return BKE_hair_add(bmain, name); case OB_POINTCLOUD: - return BKE_pointcloud_add(bmain, name); + return BKE_pointcloud_add_default(bmain, name); case OB_VOLUME: return BKE_volume_add(bmain, name); case OB_EMPTY: diff --git a/source/blender/blenkernel/intern/pointcloud.c b/source/blender/blenkernel/intern/pointcloud.c index 6ec305a971c..02f318445ac 100644 --- a/source/blender/blenkernel/intern/pointcloud.c +++ b/source/blender/blenkernel/intern/pointcloud.c @@ -53,8 +53,8 @@ static void pointcloud_random(PointCloud *pointcloud); -static const char *POINTCLOUD_ATTR_POSITION = "Position"; -static const char *POINTCLOUD_ATTR_RADIUS = "Radius"; +const char *POINTCLOUD_ATTR_POSITION = "Position"; +const char *POINTCLOUD_ATTR_RADIUS = "Radius"; static void pointcloud_init_data(ID *id) { @@ -70,15 +70,7 @@ static void pointcloud_init_data(ID *id) NULL, pointcloud->totpoint, POINTCLOUD_ATTR_POSITION); - CustomData_add_layer_named(&pointcloud->pdata, - CD_PROP_FLOAT, - CD_CALLOC, - NULL, - pointcloud->totpoint, - POINTCLOUD_ATTR_RADIUS); BKE_pointcloud_update_customdata_pointers(pointcloud); - - pointcloud_random(pointcloud); } static void pointcloud_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag) @@ -221,6 +213,23 @@ void *BKE_pointcloud_add(Main *bmain, const char *name) return pointcloud; } +void *BKE_pointcloud_add_default(Main *bmain, const char *name) +{ + PointCloud *pointcloud = BKE_libblock_alloc(bmain, ID_PT, name, 0); + + pointcloud_init_data(&pointcloud->id); + + CustomData_add_layer_named(&pointcloud->pdata, + CD_PROP_FLOAT, + CD_CALLOC, + NULL, + pointcloud->totpoint, + POINTCLOUD_ATTR_RADIUS); + pointcloud_random(pointcloud); + + return pointcloud; +} + PointCloud *BKE_pointcloud_copy(Main *bmain, const PointCloud *pointcloud) { PointCloud *pointcloud_copy; diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt index be6c0658b1f..a1f8061c9f7 100644 --- a/source/blender/editors/object/CMakeLists.txt +++ b/source/blender/editors/object/CMakeLists.txt @@ -86,4 +86,9 @@ if(WITH_INTERNATIONAL) add_definitions(-DWITH_INTERNATIONAL) endif() +if(WITH_EXPERIMENTAL_FEATURES) + add_definitions(-DWITH_PARTICLE_NODES) + add_definitions(-DWITH_HAIR_NODES) +endif() + blender_add_lib(bf_editor_object "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index fa1d147dc5e..fe68195409f 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -41,6 +41,7 @@ #include "DNA_object_fluidsim_types.h" #include "DNA_object_force_types.h" #include "DNA_object_types.h" +#include "DNA_pointcloud_types.h" #include "DNA_scene_types.h" #include "DNA_vfont_types.h" @@ -2328,8 +2329,15 @@ void OBJECT_OT_duplicates_make_real(wmOperatorType *ot) static const EnumPropertyItem convert_target_items[] = { {OB_CURVE, "CURVE", ICON_OUTLINER_OB_CURVE, "Curve from Mesh/Text", ""}, +#ifdef WITH_PARTICLE_NODES + {OB_MESH, "MESH", ICON_OUTLINER_OB_MESH, "Mesh from Curve/Meta/Surf/Text/Pointcloud", ""}, +#else {OB_MESH, "MESH", ICON_OUTLINER_OB_MESH, "Mesh from Curve/Meta/Surf/Text", ""}, +#endif {OB_GPENCIL, "GPENCIL", ICON_OUTLINER_OB_GREASEPENCIL, "Grease Pencil from Curve/Mesh", ""}, +#ifdef WITH_PARTICLE_NODES + {OB_POINTCLOUD, "POINTCLOUD", ICON_OUTLINER_OB_POINTCLOUD, "Pointcloud from Mesh", ""}, +#endif {0, NULL, 0, NULL, NULL}, }; @@ -2467,6 +2475,7 @@ static int object_convert_exec(bContext *C, wmOperator *op) MetaBall *mb; Mesh *me; Object *ob_gpencil = NULL; + PointCloud *pointcloud; const short target = RNA_enum_get(op->ptr, "target"); bool keep_original = RNA_boolean_get(op->ptr, "keep_original"); @@ -2636,6 +2645,31 @@ static int object_convert_exec(bContext *C, wmOperator *op) } ob_gpencil->actcol = actcol; } + else if (ob->type == OB_MESH && target == OB_POINTCLOUD) { + ob->flag |= OB_DONE; + + if (keep_original) { + basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, NULL); + newob = basen->object; + + /* decrement original mesh's usage count */ + me = newob->data; + id_us_min(&me->id); + + /* make a new copy of the mesh */ + newob->data = BKE_mesh_copy(bmain, me); + } + else { + newob = ob; + } + + BKE_mesh_to_pointcloud(bmain, depsgraph, scene, newob); + + if (newob->type == OB_POINTCLOUD) { + BKE_object_free_modifiers(newob, 0); /* after derivedmesh calls! */ + ED_rigidbody_object_remove(bmain, scene, newob); + } + } else if (ob->type == OB_MESH) { ob->flag |= OB_DONE; @@ -2821,6 +2855,31 @@ static int object_convert_exec(bContext *C, wmOperator *op) mballConverted = 1; } } + else if (ob->type == OB_POINTCLOUD && target == OB_MESH) { + ob->flag |= OB_DONE; + + if (keep_original) { + basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, NULL); + newob = basen->object; + + /* decrement original pointclouds's usage count */ + pointcloud = newob->data; + id_us_min(&pointcloud->id); + + /* make a new copy of the pointcloud */ + newob->data = BKE_pointcloud_copy(bmain, pointcloud); + } + else { + newob = ob; + } + + BKE_pointcloud_to_mesh(bmain, depsgraph, scene, newob); + + if (newob->type == OB_MESH) { + BKE_object_free_modifiers(newob, 0); /* after derivedmesh calls! */ + ED_rigidbody_object_remove(bmain, scene, newob); + } + } else { continue; } |