Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_material.h1
-rw-r--r--source/blender/blenkernel/BKE_mesh.h11
-rw-r--r--source/blender/blenkernel/BKE_pointcloud.h5
-rw-r--r--source/blender/blenkernel/intern/material.c21
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.c97
-rw-r--r--source/blender/blenkernel/intern/object.c3
-rw-r--r--source/blender/blenkernel/intern/pointcloud.c29
-rw-r--r--source/blender/editors/object/CMakeLists.txt5
-rw-r--r--source/blender/editors/object/object_add.c59
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;
}