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:
Diffstat (limited to 'source/blender/blenkernel/intern/mesh_convert.c')
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.c114
1 files changed, 86 insertions, 28 deletions
diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c
index a5c97cd1182..6d0245cbc88 100644
--- a/source/blender/blenkernel/intern/mesh_convert.c
+++ b/source/blender/blenkernel/intern/mesh_convert.c
@@ -38,6 +38,7 @@
#include "BKE_main.h"
#include "BKE_DerivedMesh.h"
#include "BKE_key.h"
+#include "BKE_library_query.h"
#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
@@ -612,7 +613,13 @@ void BKE_mesh_from_nurbs_displist(Main *bmain,
}
/* make mesh */
- me = BKE_mesh_add(bmain, obdata_name);
+ if (bmain != NULL) {
+ me = BKE_mesh_add(bmain, obdata_name);
+ }
+ else {
+ me = BKE_id_new_nomain(ID_ME, obdata_name);
+ }
+
me->totvert = totvert;
me->totedge = totedge;
me->totloop = totloop;
@@ -632,7 +639,13 @@ void BKE_mesh_from_nurbs_displist(Main *bmain,
BKE_mesh_calc_normals(me);
}
else {
- me = BKE_mesh_add(bmain, obdata_name);
+ if (bmain != NULL) {
+ me = BKE_mesh_add(bmain, obdata_name);
+ }
+ else {
+ me = BKE_id_new_nomain(ID_ME, obdata_name);
+ }
+
ob->runtime.mesh_eval = NULL;
BKE_mesh_nomain_to_mesh(me_eval, me, ob, &CD_MASK_MESH, true);
}
@@ -662,16 +675,18 @@ void BKE_mesh_from_nurbs_displist(Main *bmain,
ob->type = OB_MESH;
/* other users */
- ob1 = bmain->objects.first;
- while (ob1) {
- if (ob1->data == cu) {
- ob1->type = OB_MESH;
-
- id_us_min((ID *)ob1->data);
- ob1->data = ob->data;
- id_us_plus((ID *)ob1->data);
+ if (bmain != NULL) {
+ ob1 = bmain->objects.first;
+ while (ob1) {
+ if (ob1->data == cu) {
+ ob1->type = OB_MESH;
+
+ id_us_min((ID *)ob1->data);
+ ob1->data = ob->data;
+ id_us_plus((ID *)ob1->data);
+ }
+ ob1 = ob1->id.next;
}
- ob1 = ob1->id.next;
}
if (temporary) {
@@ -995,7 +1010,7 @@ static void curve_to_mesh_eval_ensure(Object *object)
BKE_object_free_curve_cache(&taper_object);
}
-static Mesh *mesh_new_from_curve_type_object(Main *bmain, Object *object)
+static Mesh *mesh_new_from_curve_type_object(Object *object)
{
Curve *curve = object->data;
const bool uv_from_orco = (curve->flag & CU_UV_ORCO) != 0;
@@ -1014,7 +1029,7 @@ static Mesh *mesh_new_from_curve_type_object(Main *bmain, Object *object)
temp_curve->editnurb = NULL;
/* Convert to mesh. */
- BKE_mesh_from_nurbs_displist(bmain,
+ BKE_mesh_from_nurbs_displist(NULL,
temp_object,
&temp_object->runtime.curve_cache->disp,
uv_from_orco,
@@ -1037,7 +1052,7 @@ static Mesh *mesh_new_from_curve_type_object(Main *bmain, Object *object)
return mesh_result;
}
-static Mesh *mesh_new_from_mball_object(Main *bmain, Object *object)
+static Mesh *mesh_new_from_mball_object(Object *object)
{
MetaBall *mball = (MetaBall *)object->data;
@@ -1048,10 +1063,10 @@ static Mesh *mesh_new_from_mball_object(Main *bmain, Object *object)
* We create empty mesh so scripters don't run into None objects. */
if (!DEG_is_evaluated_object(object) || object->runtime.curve_cache == NULL ||
BLI_listbase_is_empty(&object->runtime.curve_cache->disp)) {
- return BKE_mesh_add(bmain, mball->id.name + 2);
+ return BKE_id_new_nomain(ID_ME, ((ID *)object->data)->name + 2);
}
- Mesh *mesh_result = BKE_mesh_add(bmain, ((ID *)object->data)->name + 2);
+ Mesh *mesh_result = BKE_id_new_nomain(ID_ME, ((ID *)object->data)->name + 2);
BKE_mesh_from_metaball(&object->runtime.curve_cache->disp, mesh_result);
/* Copy materials. */
@@ -1066,29 +1081,32 @@ static Mesh *mesh_new_from_mball_object(Main *bmain, Object *object)
return mesh_result;
}
-static Mesh *mesh_new_from_mesh_object(Main *bmain, Object *object)
+static Mesh *mesh_new_from_mesh_object(Object *object)
{
Mesh *mesh_input = object->data;
Mesh *mesh_result = NULL;
- BKE_id_copy_ex(bmain, &mesh_input->id, (ID **)&mesh_result, 0);
+ BKE_id_copy_ex(NULL,
+ &mesh_input->id,
+ (ID **)&mesh_result,
+ LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT);
/* NOTE: Materials should already be copied. */
return mesh_result;
}
-Mesh *BKE_mesh_new_from_object(Main *bmain, Object *object)
+Mesh *BKE_mesh_new_from_object(Object *object)
{
Mesh *new_mesh = NULL;
switch (object->type) {
case OB_FONT:
case OB_CURVE:
case OB_SURF:
- new_mesh = mesh_new_from_curve_type_object(bmain, object);
+ new_mesh = mesh_new_from_curve_type_object(object);
break;
case OB_MBALL:
- new_mesh = mesh_new_from_mball_object(bmain, object);
+ new_mesh = mesh_new_from_mball_object(object);
break;
case OB_MESH:
- new_mesh = mesh_new_from_mesh_object(bmain, object);
+ new_mesh = mesh_new_from_mesh_object(object);
break;
default:
/* Object does not have geometry data. */
@@ -1098,15 +1116,55 @@ Mesh *BKE_mesh_new_from_object(Main *bmain, Object *object)
/* Happens in special cases like request of mesh for non-mother meta ball. */
return NULL;
}
- /* The result must have 0 users, since it's just a mesh which is free-dangling in the main
- * database. All the copy and allocation functions to manipulate new Mesh datablock are ensuring
- * an user.
- * Here we control that user management went the way it's expected, and cancel out the user. */
- BLI_assert(new_mesh->id.us == 1);
- id_us_min(&new_mesh->id);
+ /* The result must have 0 users, since it's just a mesh which is free-dangling data-block.
+ * All the conversion functions are supposed to ensure mesh is not counted. */
+ BLI_assert(new_mesh->id.us == 0);
return new_mesh;
}
+static int foreach_libblock_make_original_and_usercount_callback(void *user_data_v,
+ ID *id_self,
+ ID **id_p,
+ int cb_flag)
+{
+ UNUSED_VARS(user_data_v, id_self, cb_flag);
+ if (*id_p == NULL) {
+ return IDWALK_RET_NOP;
+ }
+ *id_p = DEG_get_original_id(*id_p);
+ id_us_plus(*id_p);
+ return IDWALK_RET_NOP;
+}
+
+Mesh *BKE_mesh_new_from_object_to_bmain(Main *bmain, Object *object)
+{
+ Mesh *mesh = BKE_mesh_new_from_object(object);
+
+ /* Make sure mesh only points original datablocks, also increase users of materials and other
+ * possibly referenced data-blocks.
+ *
+ * Going to original data-blocks is required to have bmain in a consistent state, where
+ * everything is only allowed to reference original data-blocks.
+ *
+ * user-count is required is 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->id, foreach_libblock_make_original_and_usercount_callback, NULL, 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 datablock
+ * to the bmain. So we allocate new empty mesh in the bmain (which guarantess all the naming and
+ * orders and flags) and move the temporary mesh in place there. */
+ Mesh *mesh_in_bmain = BKE_mesh_add(bmain, mesh->id.name + 2);
+ BKE_mesh_nomain_to_mesh(mesh, mesh_in_bmain, NULL, &CD_MASK_MESH, true);
+
+ /* 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);
+ id_us_min(&mesh_in_bmain->id);
+
+ return mesh_in_bmain;
+}
+
static void add_shapekey_layers(Mesh *mesh_dest, Mesh *mesh_src)
{
KeyBlock *kb;