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_displist.h5
-rw-r--r--source/blender/blenkernel/intern/displist.cc17
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.cc261
3 files changed, 80 insertions, 203 deletions
diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h
index db5663fcc94..8fb596a8096 100644
--- a/source/blender/blenkernel/BKE_displist.h
+++ b/source/blender/blenkernel/BKE_displist.h
@@ -87,11 +87,6 @@ void BKE_displist_make_curveTypes(struct Depsgraph *depsgraph,
const struct Scene *scene,
struct Object *ob,
const bool for_render);
-void BKE_displist_make_curveTypes_forRender(struct Depsgraph *depsgraph,
- const struct Scene *scene,
- struct Object *ob,
- struct ListBase *dispbase,
- struct Mesh **r_final);
void BKE_displist_make_mball(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob);
void BKE_curve_calc_modifiers_pre(struct Depsgraph *depsgraph,
diff --git a/source/blender/blenkernel/intern/displist.cc b/source/blender/blenkernel/intern/displist.cc
index e756daa1156..79e913d266f 100644
--- a/source/blender/blenkernel/intern/displist.cc
+++ b/source/blender/blenkernel/intern/displist.cc
@@ -1540,23 +1540,6 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph,
boundbox_displist_object(ob);
}
-void BKE_displist_make_curveTypes_forRender(
- Depsgraph *depsgraph, const Scene *scene, Object *ob, ListBase *r_dispbase, Mesh **r_final)
-{
- if (ob->runtime.curve_cache == nullptr) {
- ob->runtime.curve_cache = (CurveCache *)MEM_callocN(sizeof(CurveCache), __func__);
- }
-
- if (ob->type == OB_SURF) {
- evaluate_surface_object(depsgraph, scene, ob, true, r_dispbase, r_final);
- }
- else {
- GeometrySet geometry_set = evaluate_curve_type_object(depsgraph, scene, ob, true, r_dispbase);
- MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
- *r_final = mesh_component.release();
- }
-}
-
void BKE_displist_minmax(const ListBase *dispbase, float min[3], float max[3])
{
bool doit = false;
diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc
index 72ccfffbc3c..51acbeb8f5b 100644
--- a/source/blender/blenkernel/intern/mesh_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_convert.cc
@@ -41,6 +41,7 @@
#include "BKE_deform.h"
#include "BKE_displist.h"
#include "BKE_editmesh.h"
+#include "BKE_geometry_set.hh"
#include "BKE_key.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
@@ -51,6 +52,7 @@
#include "BKE_mesh_runtime.h"
#include "BKE_mesh_wrapper.h"
#include "BKE_modifier.h"
+#include "BKE_spline.hh"
/* these 2 are only used by conversion functions */
#include "BKE_curve.h"
/* -- */
@@ -58,6 +60,8 @@
/* -- */
#include "BKE_pointcloud.h"
+#include "BKE_curve_to_mesh.hh"
+
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
@@ -573,90 +577,6 @@ Mesh *BKE_mesh_new_nomain_from_curve(const Object *ob)
return BKE_mesh_new_nomain_from_curve_displist(ob, &disp);
}
-static void mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const char *obdata_name)
-{
- if (ob->runtime.data_eval && GS(((ID *)ob->runtime.data_eval)->name) != ID_ME) {
- return;
- }
-
- Mesh *me_eval = (Mesh *)ob->runtime.data_eval;
- Mesh *me;
- MVert *allvert = nullptr;
- MEdge *alledge = nullptr;
- MLoop *allloop = nullptr;
- MLoopUV *alluv = nullptr;
- MPoly *allpoly = nullptr;
- int totvert, totedge, totloop, totpoly;
-
- Curve *cu = (Curve *)ob->data;
-
- if (me_eval == nullptr) {
- if (mesh_nurbs_displist_to_mdata(cu,
- dispbase,
- &allvert,
- &totvert,
- &alledge,
- &totedge,
- &allloop,
- &allpoly,
- &alluv,
- &totloop,
- &totpoly) != 0) {
- /* Error initializing */
- return;
- }
-
- /* make mesh */
- me = (Mesh *)BKE_id_new_nomain(ID_ME, obdata_name);
-
- me->totvert = totvert;
- me->totedge = totedge;
- me->totloop = totloop;
- me->totpoly = 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 = (MLoopUV *)CustomData_add_layer_named(
- &me->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, me->totloop, uvname);
- }
-
- BKE_mesh_calc_normals(me);
- }
- else {
- me = (Mesh *)BKE_id_new_nomain(ID_ME, obdata_name);
-
- ob->runtime.data_eval = nullptr;
- BKE_mesh_nomain_to_mesh(me_eval, me, ob, &CD_MASK_MESH, true);
- }
-
- me->totcol = cu->totcol;
- me->mat = cu->mat;
-
- mesh_copy_texture_space_from_curve_type(cu, me);
-
- cu->mat = nullptr;
- cu->totcol = 0;
-
- /* Do not decrement ob->data usercount here,
- * it's done at end of func with BKE_id_free_us() call. */
- ob->data = me;
- ob->type = OB_MESH;
-
- /* 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(nullptr, cu);
-}
-
struct EdgeLink {
struct EdgeLink *next, *prev;
void *edge;
@@ -948,47 +868,25 @@ void BKE_pointcloud_to_mesh(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(sce
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 #mesh_from_nurbs_displist will do more than
- * simply conversion and will attempt to take over ownership of evaluated result and will also
- * modify the input object. */
-static Object *object_for_curve_to_mesh_create(Object *object)
+/* Create a temporary object to be used for nurbs-to-mesh conversion. */
+static Object *object_for_curve_to_mesh_create(const Object *object)
{
- Curve *curve = (Curve *)object->data;
+ const Curve *curve = (const Curve *)object->data;
- /* Create object itself. */
+ /* reate a temporary object which can be evaluated and modified by generic
+ * curve evaluation (hence the LIB_ID_COPY_SET_COPIED_ON_WRITE flag). */
Object *temp_object = (Object *)BKE_id_copy_ex(
- nullptr, &object->id, nullptr, LIB_ID_COPY_LOCALIZE);
+ nullptr, &object->id, nullptr, LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_SET_COPIED_ON_WRITE);
/* Remove all modifiers, since we don't want them to be applied. */
BKE_object_free_modifiers(temp_object, LIB_ID_CREATE_NO_USER_REFCOUNT);
- /* Copy relevant evaluated fields of curve cache.
- *
- * 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 == nullptr) {
- temp_object->runtime.curve_cache = (CurveCache *)MEM_callocN(sizeof(CurveCache),
- "CurveCache for curve types");
- }
-
- 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 != nullptr) {
- BKE_id_copy_ex(
- 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(
- nullptr, (const ID *)object->data, (ID **)&temp_object->data, LIB_ID_COPY_LOCALIZE);
+ /* Need to create copy of curve itself as well, since it will be changed by the curve evaluation
+ * process. NOTE: Copies the data, but not the shapekeys. */
+ temp_object->data = BKE_id_copy_ex(nullptr,
+ (const ID *)object->data,
+ nullptr,
+ LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_SET_COPIED_ON_WRITE);
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
@@ -1006,23 +904,10 @@ static Object *object_for_curve_to_mesh_create(Object *object)
/**
* Populate `object->runtime.curve_cache` which is then used to create the mesh.
*/
-static void curve_to_mesh_eval_ensure(Object *object)
+static void curve_to_mesh_eval_ensure(Object &object)
{
- Curve *curve = (Curve *)object->data;
- Curve remapped_curve = *curve;
- Object remapped_object = *object;
- BKE_object_runtime_reset(&remapped_object);
-
- remapped_object.data = &remapped_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`. */
- remapped_object.runtime.curve_cache = object->runtime.curve_cache;
-
+ BLI_assert(GS(static_cast<ID *>(object.data)->name) == ID_CU);
+ Curve &curve = *static_cast<Curve *>(object.data);
/* Clear all modifiers for the bevel object.
*
* This is because they can not be reliably evaluated for an original object (at least because
@@ -1031,83 +916,97 @@ 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 = {{nullptr}};
- if (remapped_curve.bevobj != nullptr) {
- bevel_object = *remapped_curve.bevobj;
+ if (curve.bevobj != nullptr) {
+ bevel_object = *curve.bevobj;
BLI_listbase_clear(&bevel_object.modifiers);
BKE_object_runtime_reset(&bevel_object);
- remapped_curve.bevobj = &bevel_object;
+ curve.bevobj = &bevel_object;
}
/* Same thing for taper. */
Object taper_object = {{nullptr}};
- if (remapped_curve.taperobj != nullptr) {
- taper_object = *remapped_curve.taperobj;
+ if (curve.taperobj != nullptr) {
+ taper_object = *curve.taperobj;
BLI_listbase_clear(&taper_object.modifiers);
BKE_object_runtime_reset(&taper_object);
- remapped_curve.taperobj = &taper_object;
+ curve.taperobj = &taper_object;
}
/* 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.
+ * bit of internal functions (#BKE_mesh_nomain_to_mesh) and also Mesh From Curve operator.
* Brecht says hold off with that. */
- Mesh *mesh_eval = nullptr;
- BKE_displist_make_curveTypes_forRender(
- nullptr, nullptr, &remapped_object, &remapped_object.runtime.curve_cache->disp, &mesh_eval);
+ BKE_displist_make_curveTypes(nullptr, nullptr, &object, true);
- /* 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 != 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 = nullptr;
-
- BKE_object_runtime_free_data(&remapped_object);
- BKE_object_runtime_free_data(&taper_object);
+ BKE_object_runtime_free_data(&bevel_object);
BKE_object_runtime_free_data(&taper_object);
}
-static Mesh *mesh_new_from_curve_type_object(Object *object)
+/* Necessary because #BKE_object_get_evaluated_mesh doesn't look in the geometry set yet. */
+static const Mesh *get_evaluated_mesh_from_object(const Object *object)
{
- Curve *curve = (Curve *)object->data;
- Object *temp_object = object_for_curve_to_mesh_create(object);
- Curve *temp_curve = (Curve *)temp_object->data;
+ const Mesh *mesh = BKE_object_get_evaluated_mesh(object);
+ if (mesh) {
+ return mesh;
+ }
+ GeometrySet *geometry_set_eval = object->runtime.geometry_set_eval;
+ if (geometry_set_eval) {
+ return geometry_set_eval->get_mesh_for_read();
+ }
+ return nullptr;
+}
- /* When input object is an original one, we don't have evaluated curve cache yet, so need to
- * create it in the temporary object. */
- if (!DEG_is_evaluated_object(object)) {
- curve_to_mesh_eval_ensure(temp_object);
+static const CurveEval *get_evaluated_curve_from_object(const Object *object)
+{
+ GeometrySet *geometry_set_eval = object->runtime.geometry_set_eval;
+ if (geometry_set_eval) {
+ return geometry_set_eval->get_curve_for_read();
}
+ return nullptr;
+}
- /* Reset pointers before conversion. */
- temp_curve->editfont = nullptr;
- temp_curve->editnurb = nullptr;
+static Mesh *mesh_new_from_evaluated_curve_type_object(const Object *evaluated_object)
+{
+ const Mesh *mesh = get_evaluated_mesh_from_object(evaluated_object);
+ if (mesh) {
+ return BKE_mesh_copy_for_eval(mesh, false);
+ }
+ const CurveEval *curve = get_evaluated_curve_from_object(evaluated_object);
+ if (curve) {
+ return blender::bke::curve_to_wire_mesh(*curve);
+ }
+ return nullptr;
+}
- /* Convert to mesh. */
- mesh_from_nurbs_displist(
- temp_object, &temp_object->runtime.curve_cache->disp, curve->id.name + 2);
+static Mesh *mesh_new_from_curve_type_object(const Object *object)
+{
+ /* If the object is evaluated, it should either have an evaluated mesh or curve data already.
+ * The mesh can be duplicated, or the curve converted to wire mesh edges. */
+ if (DEG_is_evaluated_object(object)) {
+ return mesh_new_from_evaluated_curve_type_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(nullptr, temp_object->data);
- BKE_id_free(nullptr, temp_object);
- return nullptr;
+ /* Otherwise, create a temporary "fake" evaluated object and try again. This might have
+ * different results, since in order to avoid having adverse affects to other original objects,
+ * modifiers are cleared. An alternative would be to create a temporary depsgraph only for this
+ * object and its dependencies. */
+ Object *temp_object = object_for_curve_to_mesh_create(object);
+ ID *temp_data = static_cast<ID *>(temp_object->data);
+ curve_to_mesh_eval_ensure(*temp_object);
+
+ /* If evaluating the curve replaced object data with different data, free the original data. */
+ if (temp_data != temp_object->data) {
+ BKE_id_free(nullptr, temp_data);
}
- Mesh *mesh_result = (Mesh *)temp_object->data;
+ Mesh *mesh = mesh_new_from_evaluated_curve_type_object(temp_object);
+ BKE_id_free(nullptr, temp_object->data);
BKE_id_free(nullptr, temp_object);
- /* NOTE: Materials are copied in #mesh_from_nurbs_displist(). */
-
- return mesh_result;
+ return mesh;
}
static Mesh *mesh_new_from_mball_object(Object *object)