1
1

Compare commits

...

66 Commits

Author SHA1 Message Date
b9343028e4 Cleanup: Remove unecessary change order of switch cases
Also don't check for mesh_eval for text objects
2021-07-21 17:11:37 -04:00
2ee86901fd Cleanup: Comment formatting, wording 2021-07-21 17:07:43 -04:00
8e907841c4 Remove redundant text object mesh/displist drawing code 2021-07-21 16:25:21 -04:00
60e68e8b28 Skip mesh conversion for "fast text editing" 2021-07-21 16:24:55 -04:00
a26494e196 Merge branch 'master' into curve-nodes-modifier 2021-07-21 09:04:20 -04:00
b95d647fb1 Merge branch 'master' into curve-nodes-modifier 2021-07-20 16:47:51 -04:00
ff75ce1016 Also copy curve non-auto texture space settings to generated curve 2021-07-19 21:42:35 -04:00
9ccf5c3d4c Merge branch 'master' into curve-nodes-modifier 2021-07-19 21:24:44 -04:00
9c6b2331a1 Merge branch 'master' into curve-nodes-modifier 2021-07-19 12:10:19 -04:00
5cdf5416d9 Merge branch 'master' into curve-nodes-modifier 2021-07-18 22:05:02 -04:00
18a43b5dd5 Cleanup: Comment and redundant logic 2021-07-15 23:04:34 -04:00
dbdb60a2b2 Merge branch 'master' into curve-nodes-modifier 2021-07-15 22:29:59 -04:00
e5032cf821 Hide the geometry nodes modifier for surface and lattice objects 2021-07-13 18:04:39 -04:00
16cf3a0014 Fix 2D curves always convert to mesh, regardless of fill mode 2021-07-13 17:45:58 -04:00
c4562691da Fix selection doesn't use evalauted mesh 2021-07-13 17:45:10 -04:00
65d5595b4a Merge branch 'master' into curve-nodes-modifier 2021-07-13 16:59:29 -04:00
f9ce74425c Cleanup: Fix typos, add deprecated comment to flag 2021-07-12 22:22:11 -04:00
d6b296a5bf Merge branch 'master' into curve-nodes-modifier 2021-07-12 22:10:41 -04:00
32d5cd8b52 Fix text object edit mode overlays 2021-07-06 17:35:10 -05:00
ce5c6e4d0d Change more switch statements to reflect the fact that curves only render as wires 2021-07-06 17:15:43 -05:00
b21c16b627 Fix surface objects again 2021-07-06 16:35:11 -05:00
ca87f08814 Cleanup: Remove unused DispList wire edge drawing code 2021-07-06 16:30:11 -05:00
af64b0ad5f Cleanup: Simplify curve eval cache 2021-07-06 16:22:09 -05:00
cc13189d96 Cleanup: Add comment 2021-07-06 16:14:29 -05:00
bb6b926b04 Add smarter mesh conversion logic 2021-07-06 16:09:49 -05:00
1cdfb9ad5a Cleanup: Remove unecessary change 2021-07-06 13:29:39 -05:00
9363099526 Merge branch 'master' into curve-nodes-modifier 2021-07-06 13:21:51 -05:00
98f8534789 Cleanup: White space 2021-07-06 09:46:11 -05:00
9773b0fb0b Fix surface objects 2021-07-06 09:46:02 -05:00
6e2e772667 Merge branch 'master' into curve-nodes-modifier 2021-07-05 22:48:55 -05:00
1ad81a6706 Make curve data visible on non-curve object types 2021-07-02 00:15:23 -05:00
4c0c91cb60 Further development and improvements 2021-07-02 00:03:24 -05:00
e253b6bef3 Merge branch 'master' into curve-nodes-modifier 2021-07-01 23:04:42 -05:00
49304aa303 Various Improvements 2021-07-01 15:50:32 -05:00
f7b2d30d8f Merge branch 'master' into curve-nodes-modifier 2021-07-01 10:58:23 -05:00
78c086f686 Merge branch 'master' into curve-nodes-modifier 2021-06-30 18:32:36 -05:00
66e00013c9 Merge branch 'master' into curve-nodes-modifier 2021-06-30 16:52:33 -05:00
86fc715349 Merge branch 'master' into curve-nodes-modifier 2021-06-30 11:34:51 -05:00
3036b724f7 Merge branch 'master' into curve-nodes-modifier 2021-06-28 22:45:26 -05:00
e77f3d92ee Merge branch 'master' into curve-nodes-modifier 2021-06-28 22:23:57 -05:00
e0b3d64186 Merge branch 'master' into curve-nodes-modifier 2021-06-28 21:48:31 -05:00
0dc68aeff8 Merge branch 'master' into curve-nodes-modifier 2021-06-28 21:35:24 -05:00
4a89a39166 Merge branch 'master' into curve-nodes-modifier 2021-06-28 21:00:16 -05:00
7ae47bc368 More cleanup, displist still shows up when it shouldn't (no mesh in data_eval) 2021-06-28 20:27:07 -05:00
e51c10d71e Cleanup: Rename variables 2021-06-28 17:53:42 -05:00
229d30587b Merge branch 'master' into curve-nodes-modifier 2021-06-28 17:50:10 -05:00
59be5bf228 Remove "Curve deform fill" setting, avoid duplicating spline list 2021-06-28 16:49:48 -05:00
65c326cbe9 Cleanup: Remove unecessary change 2021-06-28 15:23:42 -05:00
e14ce0fefe Cleanup: Remove unecessary include 2021-06-28 14:34:57 -05:00
3476da4d60 Cleanup: Clang format 2021-06-28 14:32:21 -05:00
8203470174 Merge branch 'master' into curve-nodes-modifier 2021-06-28 14:31:40 -05:00
afbb61dc35 Merge branch 'master' into curve-nodes-modifier 2021-06-28 13:48:35 -05:00
61bd814f2b Merge branch 'master' into curve-nodes-modifier 2021-06-28 13:26:34 -05:00
aa7c42d5f9 Working curve modifier evaluation, nodes modifier uses pre-tessellated deform 2021-06-28 13:14:04 -05:00
49fc3ddc5d Merge branch 'master' into curve-nodes-modifier 2021-06-28 10:42:29 -05:00
59455f9b66 Further refactoring WIP 2021-06-26 23:50:49 -05:00
54241d1b77 Fix crash with disabled nodes modifier 2021-06-25 13:13:21 -05:00
5c2267bbd4 Merge branch 'master' into curve-nodes-modifier 2021-06-25 12:15:45 -05:00
5ab4ce5856 Cleanup: Remove outdated comment 2021-06-25 10:57:26 -05:00
8e1239eedf Enable new button in geometry node editor for curves 2021-06-25 10:56:02 -05:00
bf68462387 Merge branch 'master' into curve-nodes-modifier 2021-06-25 10:34:39 -05:00
18355a505d Fix error, assert for null mesh result at start 2021-06-18 10:21:17 -05:00
7008d183c4 Merge branch 'master' into curve-nodes-modifier 2021-06-17 19:23:16 -05:00
4a2eac8897 Fix order of assigning geometry set and BKE_object_eval_assign_data 2021-06-16 17:30:33 -05:00
8ceb07bd58 Merge branch 'master' into curve-nodes-modifier 2021-06-16 16:52:56 -05:00
0bc5800754 WIP: Geometry Nodes: Support nodes modifier on curve objects
With this commit, curve objects support the nodes modifier. The goal is
that nodes modifiers will read curve data as the original curve, unless
they are placed after a modifier that must tessalate the curve (convert
it to a mesh). Always converting to a mesh in that case  is basically
just a formalization of the behavior that was already present after
recent fixes for 2.8 versions last year and two years ago. For more
controlled explicit conversions between data types, using geometry
nodes makes so much more sense anyway.

TODO:
 - Add more code comments
 - Fix memory leak(s?)
 - Fix geometry components besides mesh don't display in viewport.

Differential Revision: https://developer.blender.org/D11597
2021-06-14 01:14:48 -05:00
20 changed files with 230 additions and 593 deletions

View File

@@ -42,8 +42,8 @@ def geometry_node_group_empty_new():
def geometry_modifier_poll(context):
ob = context.object
# Test object support for geometry node modifier (No curve, or hair object support yet)
if not ob or ob.type not in {'MESH', 'POINTCLOUD', 'VOLUME'}:
# Test object support for geometry node modifier (No hair object support yet)
if not ob or ob.type not in {'MESH', 'POINTCLOUD', 'VOLUME', 'CURVE'}:
return False
return True

View File

@@ -120,7 +120,6 @@ class DATA_PT_shape_curve(CurveButtonsPanel, Panel):
sub = col.column()
sub.active = (curve.dimensions == '2D' or (curve.bevel_mode != 'OBJECT' and curve.dimensions == '3D'))
sub.prop(curve, "fill_mode")
col.prop(curve, "use_fill_deform")
if is_curve:
col = layout.column()

View File

@@ -99,7 +99,7 @@ void BKE_displist_make_mball_forRender(struct Depsgraph *depsgraph,
struct Object *ob,
struct ListBase *dispbase);
bool BKE_curve_calc_modifiers_pre(struct Depsgraph *depsgraph,
void BKE_curve_calc_modifiers_pre(struct Depsgraph *depsgraph,
const struct Scene *scene,
struct Object *ob,
struct ListBase *source_nurb,

View File

@@ -40,6 +40,7 @@
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_scanfill.h"
#include "BLI_span.hh"
#include "BLI_string.h"
#include "BLI_utildefines.h"
@@ -47,6 +48,7 @@
#include "BKE_curve.h"
#include "BKE_displist.h"
#include "BKE_font.h"
#include "BKE_geometry_set.hh"
#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_lib_id.h"
@@ -55,6 +57,7 @@
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_spline.hh"
#include "BLI_sys_types.h" // for intptr_t support
@@ -745,10 +748,7 @@ static ModifierData *curve_get_tessellate_point(const Scene *scene,
return pretessellatePoint;
}
/**
* \return True if any modifier was applied.
*/
bool BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph,
void BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph,
const Scene *scene,
Object *ob,
ListBase *source_nurb,
@@ -793,7 +793,6 @@ bool BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph,
const ModifierEvalContext mectx = {depsgraph, ob, apply_flag};
ModifierData *pretessellatePoint = curve_get_tessellate_point(scene, ob, for_render, editmode);
bool modified = false;
if (pretessellatePoint) {
VirtualModifierData virtualModifierData;
@@ -813,7 +812,6 @@ bool BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph,
}
mti->deformVerts(md, &mectx, nullptr, deformedVerts, numVerts);
modified = true;
if (md == pretessellatePoint) {
break;
@@ -832,48 +830,59 @@ bool BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph,
if (keyVerts) {
MEM_freeN(keyVerts);
}
return modified;
}
static float (*displist_vert_coords_alloc(ListBase *dispbase, int *r_vert_len))[3]
/**
* \return True if the deformed curve control point data should be implicitly
* converted directly to a mesh, or false if it can be left as curve data via #CurveEval.
*/
static bool do_curve_implicit_mesh_conversion(const Curve *curve,
ModifierData *first_modifier,
const Scene *scene,
const ModifierMode required_mode)
{
*r_vert_len = 0;
LISTBASE_FOREACH (DispList *, dl, dispbase) {
*r_vert_len += (dl->type == DL_INDEX3) ? dl->nr : dl->parts * dl->nr;
/* Skip implicit filling and conversion to mesh when using "fast text editing". */
if (curve->flag & CU_FAST) {
return false;
}
float(*allverts)[3] = (float(*)[3])MEM_mallocN(sizeof(float[3]) * (*r_vert_len), __func__);
float *fp = (float *)allverts;
LISTBASE_FOREACH (DispList *, dl, dispbase) {
const int ofs = 3 * ((dl->type == DL_INDEX3) ? dl->nr : dl->parts * dl->nr);
memcpy(fp, dl->verts, sizeof(float) * ofs);
fp += ofs;
/* Do implicit conversion to mesh with the object bevel mode. */
if (curve->bevel_mode == CU_BEV_MODE_OBJECT && curve->bevobj != nullptr) {
return true;
}
return allverts;
/* 2D curves are sometimes implicitly filled and converted to a mesh. */
if (CU_DO_2DFILL(curve)) {
return true;
}
/* Curve objects with implicit "tube" meshes should convert implicitly to a mesh. */
if (curve->ext1 != 0.0f || curve->ext2 != 0.0f) {
return true;
}
/* If a non-geometry-nodes modifier is enabled before a nodes modifier,
* force conversion to mesh, since only the nodes modifier supports curve data. */
ModifierData *md = first_modifier;
for (; md; md = md->next) {
if (BKE_modifier_is_enabled(scene, md, required_mode)) {
if (md->type == eModifierType_Nodes) {
break;
}
return true;
}
}
return false;
}
static void displist_vert_coords_apply(ListBase *dispbase, const float (*allverts)[3])
{
const float *fp = (float *)allverts;
LISTBASE_FOREACH (DispList *, dl, dispbase) {
int ofs = 3 * ((dl->type == DL_INDEX3) ? dl->nr : dl->parts * dl->nr);
memcpy(dl->verts, fp, sizeof(float) * ofs);
fp += ofs;
}
}
static void curve_calc_modifiers_post(Depsgraph *depsgraph,
const Scene *scene,
Object *ob,
ListBase *dispbase,
const bool for_render,
const bool force_mesh_conversion,
Mesh **r_final)
static GeometrySet curve_calc_modifiers_post(Depsgraph *depsgraph,
const Scene *scene,
Object *ob,
const ListBase *dispbase,
const bool for_render)
{
const Curve *cu = (const Curve *)ob->data;
const bool editmode = (!for_render && (cu->editnurb || cu->editfont));
const bool use_cache = !for_render;
@@ -897,167 +906,69 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph,
BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData) :
pretessellatePoint->next;
if (r_final && *r_final) {
BKE_id_free(nullptr, *r_final);
GeometrySet geometry_set;
if (ob->type == OB_SURF || do_curve_implicit_mesh_conversion(cu, md, scene, required_mode)) {
Mesh *mesh = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase);
/* Copy materials, since BKE_mesh_new_nomain_from_curve_displist() doesn't. */
mesh->mat = (Material **)MEM_dupallocN(cu->mat);
mesh->totcol = cu->totcol;
geometry_set.replace_mesh(mesh);
}
else {
std::unique_ptr<CurveEval> curve_eval = curve_eval_from_dna_curve(
*cu, ob->runtime.curve_cache->deformed_nurbs);
geometry_set.replace_curve(curve_eval.release());
}
Mesh *modified = nullptr;
float(*vertCos)[3] = nullptr;
for (; md; md = md->next) {
const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type);
if (!BKE_modifier_is_enabled(scene, md, required_mode)) {
continue;
}
/* If we need normals, no choice, have to convert to mesh now. */
const bool need_normal = mti->dependsOnNormals != nullptr && mti->dependsOnNormals(md);
/* XXX 2.8 : now that batch cache is stored inside the ob->data
* we need to create a Mesh for each curve that uses modifiers. */
if (modified == nullptr /* && need_normal */) {
if (vertCos != nullptr) {
displist_vert_coords_apply(dispbase, vertCos);
}
if (ELEM(ob->type, OB_CURVE, OB_FONT) && (cu->flag & CU_DEFORM_FILL)) {
curve_to_filledpoly(cu, dispbase);
}
modified = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase);
if (md->type == eModifierType_Nodes) {
mti->modifyGeometrySet(md, &mectx_apply, &geometry_set);
continue;
}
if (mti->type == eModifierTypeType_OnlyDeform ||
(mti->type == eModifierTypeType_DeformOrConstruct && !modified)) {
if (modified) {
int totvert = 0;
if (!vertCos) {
vertCos = BKE_mesh_vert_coords_alloc(modified, &totvert);
}
if (need_normal) {
BKE_mesh_ensure_normals(modified);
}
mti->deformVerts(md, &mectx_deform, modified, vertCos, totvert);
}
else {
int totvert = 0;
if (!vertCos) {
vertCos = displist_vert_coords_alloc(dispbase, &totvert);
}
mti->deformVerts(md, &mectx_deform, nullptr, vertCos, totvert);
if (!geometry_set.has_mesh()) {
geometry_set.replace_mesh(BKE_mesh_new_nomain(0, 0, 0, 0, 0));
}
Mesh *mesh = geometry_set.get_mesh_for_write();
if (mti->type == eModifierTypeType_OnlyDeform) {
int totvert;
float(*vertex_coords)[3] = BKE_mesh_vert_coords_alloc(mesh, &totvert);
if (mti->dependsOnNormals != nullptr && mti->dependsOnNormals(md)) {
BKE_mesh_ensure_normals(mesh);
}
mti->deformVerts(md, &mectx_deform, mesh, vertex_coords, totvert);
BKE_mesh_vert_coords_apply(mesh, vertex_coords);
MEM_freeN(vertex_coords);
}
else {
if (!r_final) {
/* makeDisplistCurveTypes could be used for beveling, where mesh
* is totally unnecessary, so we could stop modifiers applying
* when we found constructive modifier but mesh is unwanted. */
break;
if (mti->dependsOnNormals != nullptr && mti->dependsOnNormals(md)) {
BKE_mesh_ensure_normals(mesh);
}
if (modified) {
if (vertCos) {
Mesh *temp_mesh = (Mesh *)BKE_id_copy_ex(
nullptr, &modified->id, nullptr, LIB_ID_COPY_LOCALIZE);
BKE_id_free(nullptr, modified);
modified = temp_mesh;
BKE_mesh_vert_coords_apply(modified, vertCos);
}
}
else {
if (vertCos) {
displist_vert_coords_apply(dispbase, vertCos);
}
if (ELEM(ob->type, OB_CURVE, OB_FONT) && (cu->flag & CU_DEFORM_FILL)) {
curve_to_filledpoly(cu, dispbase);
}
modified = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase);
}
if (vertCos) {
/* Vertex coordinates were applied to necessary data, could free it */
MEM_freeN(vertCos);
vertCos = nullptr;
}
if (need_normal) {
BKE_mesh_ensure_normals(modified);
}
Mesh *mesh_applied = mti->modifyMesh(md, &mectx_apply, modified);
if (mesh_applied) {
if (modified && modified != mesh_applied) {
BKE_id_free(nullptr, modified);
}
modified = mesh_applied;
Mesh *output_mesh = mti->modifyMesh(md, &mectx_apply, mesh);
if (mesh != output_mesh) {
geometry_set.replace_mesh(output_mesh);
}
}
}
if (vertCos) {
if (modified) {
Mesh *temp_mesh = (Mesh *)BKE_id_copy_ex(
nullptr, &modified->id, nullptr, LIB_ID_COPY_LOCALIZE);
BKE_id_free(nullptr, modified);
modified = temp_mesh;
if (geometry_set.has_mesh()) {
Mesh *final_mesh = geometry_set.get_mesh_for_write();
BKE_mesh_vert_coords_apply(modified, vertCos);
BKE_mesh_calc_normals_mapping_simple(modified);
/* XXX2.8(Sybren): make sure the face normals are recalculated as well */
BKE_mesh_ensure_normals(final_mesh);
MEM_freeN(vertCos);
}
else {
displist_vert_coords_apply(dispbase, vertCos);
MEM_freeN(vertCos);
vertCos = nullptr;
}
BLI_strncpy(final_mesh->id.name, cu->id.name, sizeof(final_mesh->id.name));
*((short *)final_mesh->id.name) = ID_ME;
}
if (r_final) {
if (force_mesh_conversion && !modified) {
/* XXX 2.8 : This is a workaround for by some deeper technical debts:
* - DRW Batch cache is stored inside the ob->data.
* - Curve data is not COWed for instances that use different modifiers.
* This can causes the modifiers to be applied on all user of the same data-block
* (see T71055)
*
* The easy workaround is to force to generate a Mesh that will be used for display data
* since a Mesh output is already used for generative modifiers.
* However it does not fix problems with actual edit data still being shared.
*
* The right solution would be to COW the Curve data block at the input of the modifier
* stack just like what the mesh modifier does.
*/
modified = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase);
}
if (modified) {
/* XXX2.8(Sybren): make sure the face normals are recalculated as well */
BKE_mesh_ensure_normals(modified);
/* Special tweaks, needed since neither BKE_mesh_new_nomain_from_template() nor
* BKE_mesh_new_nomain_from_curve_displist() properly duplicate mat info... */
BLI_strncpy(modified->id.name, cu->id.name, sizeof(modified->id.name));
*((short *)modified->id.name) = ID_ME;
MEM_SAFE_FREE(modified->mat);
/* Set flag which makes it easier to see what's going on in a debugger. */
modified->id.tag |= LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT;
modified->mat = (Material **)MEM_dupallocN(cu->mat);
modified->totcol = cu->totcol;
(*r_final) = modified;
}
else {
(*r_final) = nullptr;
}
}
else if (modified != nullptr) {
/* Pretty stupid to generate that whole mesh if it's unused, yet we have to free it. */
BKE_id_free(nullptr, modified);
}
return geometry_set;
}
static void displist_surf_indices(DispList *dl)
@@ -1110,8 +1021,7 @@ static void evaluate_surface_object(Depsgraph *depsgraph,
BKE_nurbList_duplicate(deformed_nurbs, &cu->nurb);
}
bool force_mesh_conversion = BKE_curve_calc_modifiers_pre(
depsgraph, scene, ob, deformed_nurbs, deformed_nurbs, for_render);
BKE_curve_calc_modifiers_pre(depsgraph, scene, ob, deformed_nurbs, deformed_nurbs, for_render);
LISTBASE_FOREACH (const Nurb *, nu, deformed_nurbs) {
if (!(for_render || nu->hide == 0) || !BKE_nurb_check_valid_uv(nu)) {
@@ -1174,8 +1084,14 @@ static void evaluate_surface_object(Depsgraph *depsgraph,
}
}
curve_calc_modifiers_post(
depsgraph, scene, ob, r_dispbase, for_render, force_mesh_conversion, r_final);
curve_to_filledpoly(cu, r_dispbase);
GeometrySet geometry_set = curve_calc_modifiers_post(
depsgraph, scene, ob, r_dispbase, for_render);
if (!geometry_set.has_mesh()) {
geometry_set.replace_mesh(BKE_mesh_new_nomain(0, 0, 0, 0, 0));
}
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
*r_final = mesh_component.release();
}
static void rotateBevelPiece(const Curve *cu,
@@ -1400,7 +1316,7 @@ static void evaluate_curve_type_object(Depsgraph *depsgraph,
Object *ob,
const bool for_render,
ListBase *r_dispbase,
Mesh **r_final)
GeometrySet *r_geometry_set)
{
BLI_assert(ELEM(ob->type, OB_CURVE, OB_FONT));
const Curve *cu = (const Curve *)ob->data;
@@ -1414,8 +1330,7 @@ static void evaluate_curve_type_object(Depsgraph *depsgraph,
BKE_nurbList_duplicate(deformed_nurbs, BKE_curve_nurbs_get_for_read(cu));
}
bool force_mesh_conversion = BKE_curve_calc_modifiers_pre(
depsgraph, scene, ob, deformed_nurbs, deformed_nurbs, for_render);
BKE_curve_calc_modifiers_pre(depsgraph, scene, ob, deformed_nurbs, deformed_nurbs, for_render);
BKE_curve_bevelList_make(ob, deformed_nurbs, for_render);
@@ -1604,16 +1519,8 @@ static void evaluate_curve_type_object(Depsgraph *depsgraph,
BKE_displist_free(&dlbev);
if (!(cu->flag & CU_DEFORM_FILL)) {
curve_to_filledpoly(cu, r_dispbase);
}
curve_calc_modifiers_post(
depsgraph, scene, ob, r_dispbase, for_render, force_mesh_conversion, r_final);
if (cu->flag & CU_DEFORM_FILL && !ob->runtime.data_eval) {
curve_to_filledpoly(cu, r_dispbase);
}
curve_to_filledpoly(cu, r_dispbase);
*r_geometry_set = curve_calc_modifiers_post(depsgraph, scene, ob, r_dispbase, for_render);
}
void BKE_displist_make_curveTypes(Depsgraph *depsgraph,
@@ -1631,16 +1538,33 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph,
ListBase *dispbase = &(ob->runtime.curve_cache->disp);
Mesh *mesh_eval = nullptr;
if (ob->type == OB_SURF) {
Mesh *mesh_eval;
evaluate_surface_object(depsgraph, scene, ob, for_render, dispbase, &mesh_eval);
BKE_object_eval_assign_data(ob, &mesh_eval->id, true);
}
else {
evaluate_curve_type_object(depsgraph, scene, ob, for_render, dispbase, &mesh_eval);
}
GeometrySet geometry_set;
evaluate_curve_type_object(depsgraph, scene, ob, for_render, dispbase, &geometry_set);
if (mesh_eval != nullptr) {
BKE_object_eval_assign_data(ob, &mesh_eval->id, true);
/* Assign the object's "data_eval" so that selection and other existing code knows how to
* access this. This isn't ideal since it gives special handling to the mesh, which should
* change eventually. */
if (geometry_set.has_mesh()) {
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
Mesh *mesh_eval = mesh_component.release();
BKE_object_eval_assign_data(ob, &mesh_eval->id, true);
mesh_component.replace(mesh_eval, GeometryOwnershipType::ReadOnly);
}
/* If the curve is in edit mode, make sure the output geometry set containts a
* curve component, which is used indirectly to render the edit mode overlays. */
const Curve *curve_orig = (const Curve *)ob->data;
if (BKE_curve_editNurbs_get_for_read(curve_orig) || curve_orig->editfont) {
geometry_set.get_component_for_write<CurveComponent>();
}
ob->runtime.geometry_set_eval = new GeometrySet(std::move(geometry_set));
}
boundbox_displist_object(ob);
@@ -1657,7 +1581,10 @@ void BKE_displist_make_curveTypes_forRender(
evaluate_surface_object(depsgraph, scene, ob, true, r_dispbase, r_final);
}
else {
evaluate_curve_type_object(depsgraph, scene, ob, true, r_dispbase, r_final);
GeometrySet geometry_set;
evaluate_curve_type_object(depsgraph, scene, ob, true, r_dispbase, &geometry_set);
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
*r_final = mesh_component.release();
}
}

View File

@@ -146,7 +146,6 @@ const Curve *CurveComponent::get_curve_for_render() const
}
curve_for_render_ = (Curve *)BKE_id_new_nomain(ID_CU, nullptr);
curve_for_render_->curve_eval = curve_;
return curve_for_render_;
}

View File

@@ -51,16 +51,6 @@ static void add_final_mesh_as_geometry_component(const Object &object, GeometryS
}
}
static void add_curve_data_as_geometry_component(const Object &object, GeometrySet &geometry_set)
{
BLI_assert(object.type == OB_CURVE);
if (object.data != nullptr) {
std::unique_ptr<CurveEval> curve = curve_eval_from_dna_curve(*(const Curve *)object.data);
CurveComponent &curve_component = geometry_set.get_component_for_write<CurveComponent>();
curve_component.replace(curve.release(), GeometryOwnershipType::Owned);
}
}
/**
* \note This doesn't extract instances from the "dupli" system for non-geometry-nodes instances.
*/
@@ -84,9 +74,6 @@ static GeometrySet object_get_geometry_set_for_read(const Object &object)
if (object.type == OB_MESH) {
add_final_mesh_as_geometry_component(object, geometry_set);
}
else if (object.type == OB_CURVE) {
add_curve_data_as_geometry_component(object, geometry_set);
}
/* TODO: Cover the case of point-clouds without modifiers-- they may not be covered by the
* #geometry_set_eval case above. */

View File

@@ -482,8 +482,24 @@ static int mesh_nurbs_displist_to_mdata(const Curve *cu,
return 0;
}
/**
* Copy evaluated texture space from curve to mesh.
*
* \note We disable auto texture space feature since that will cause texture space to evaluate
* differently for curve and mesh, since curves use control points and handles to calculate the
* bounding box, and mesh uses the tessellated curve.
*/
static void mesh_copy_texture_space_from_curve_type(const Curve *cu, Mesh *me)
{
me->texflag = cu->texflag & ~CU_AUTOSPACE;
copy_v3_v3(me->loc, cu->loc);
copy_v3_v3(me->size, cu->size);
BKE_mesh_texspace_calc(me);
}
Mesh *BKE_mesh_new_nomain_from_curve_displist(const Object *ob, const ListBase *dispbase)
{
const Curve *cu = ob->data;
Mesh *mesh;
MVert *allvert;
MEdge *alledge;
@@ -492,7 +508,7 @@ Mesh *BKE_mesh_new_nomain_from_curve_displist(const Object *ob, const ListBase *
MLoopUV *alluv = NULL;
int totvert, totedge, totloop, totpoly;
if (mesh_nurbs_displist_to_mdata(ob->data,
if (mesh_nurbs_displist_to_mdata(cu,
dispbase,
&allvert,
&totvert,
@@ -528,6 +544,8 @@ Mesh *BKE_mesh_new_nomain_from_curve_displist(const Object *ob, const ListBase *
CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, totloop, uvname);
}
mesh_copy_texture_space_from_curve_type(cu, mesh);
MEM_freeN(allvert);
MEM_freeN(alledge);
MEM_freeN(allloop);
@@ -620,17 +638,7 @@ void BKE_mesh_from_nurbs_displist(
me->totcol = cu->totcol;
me->mat = cu->mat;
/* Copy evaluated texture space from curve to mesh.
*
* Note that we disable auto texture space feature since that will cause
* texture space to evaluate differently for curve and mesh, since curve
* uses CV to calculate bounding box, and mesh uses what is coming from
* tessellated curve.
*/
me->texflag = cu->texflag & ~CU_AUTOSPACE;
copy_v3_v3(me->loc, cu->loc);
copy_v3_v3(me->size, cu->size);
BKE_mesh_texspace_calc(me);
mesh_copy_texture_space_from_curve_type(cu, me);
cu->mat = NULL;
cu->totcol = 0;

View File

@@ -1324,6 +1324,11 @@ bool BKE_object_support_modifier_type_check(const Object *ob, int modifier_type)
{
const ModifierTypeInfo *mti = BKE_modifier_get_info(modifier_type);
/* Surface and lattice objects don't support geometry sets. */
if (mti->modifyGeometrySet != NULL && ELEM(ob->type, OB_SURF, OB_LATTICE)) {
return false;
}
/* Only geometry objects should be able to get modifiers T25291. */
if (ob->type == OB_HAIR) {
return (mti->modifyHair != NULL) || (mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly);

View File

@@ -225,16 +225,21 @@ bool deg_iterator_components_step(BLI_Iterator *iter)
const CurveComponent *component = geometry_set->get_component_for_read<CurveComponent>();
if (component != nullptr) {
const Curve *curve = component->get_curve_for_render();
/* Don't use a temporary object for this component when the owner is a curve object. */
if (ELEM(data->geometry_component_owner->type, OB_CURVE, OB_FONT)) {
iter->current = data->geometry_component_owner;
return true;
}
const Curve *curve = component->get_curve_for_render();
if (curve != nullptr) {
Object *temp_object = &data->temp_geometry_component_object;
*temp_object = *data->geometry_component_owner;
temp_object->type = OB_CURVE;
/* Use OB_FONT when the owner is a text object, so that
* the text editing edit mode overlays will draw. */
temp_object->type = data->geometry_component_owner->type == OB_FONT ? OB_FONT : OB_CURVE;
temp_object->data = (void *)curve;
/* Assign data_eval here too, because curve rendering code tries
* to use a mesh if it can find one in this pointer. */
temp_object->runtime.data_eval = (ID *)curve;
temp_object->runtime.select_id = data->geometry_component_owner->runtime.select_id;
iter->current = temp_object;
return true;

View File

@@ -180,19 +180,12 @@ static void edit_text_cache_populate_boxes(OVERLAY_Data *vedata, Object *ob)
void OVERLAY_edit_text_cache_populate(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
Curve *cu = ob->data;
struct GPUBatch *geom;
bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
bool has_surface = (cu->flag & (CU_FRONT | CU_BACK)) || cu->ext1 != 0.0f || cu->ext2 != 0.0f;
if ((cu->flag & CU_FAST) || !has_surface) {
geom = DRW_cache_text_edge_wire_get(ob);
if (geom) {
DRW_shgroup_call(pd->edit_text_wire_grp[do_in_front], geom, ob);
}
}
else {
/* object mode draws */
geom = DRW_cache_text_edge_wire_get(ob);
if (geom) {
DRW_shgroup_call(pd->edit_text_wire_grp[do_in_front], geom, ob);
}
edit_text_cache_populate_select(vedata, ob);

View File

@@ -218,18 +218,10 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
struct GPUBatch *geom = NULL;
switch (ob->type) {
case OB_CURVE:
if (!pd->wireframe_mode && !use_wire && ob->runtime.curve_cache &&
BKE_displist_has_faces(&ob->runtime.curve_cache->disp)) {
break;
}
geom = DRW_cache_curve_edge_wire_get(ob);
break;
case OB_FONT:
if (!pd->wireframe_mode && !use_wire && ob->runtime.curve_cache &&
BKE_displist_has_faces(&ob->runtime.curve_cache->disp)) {
break;
}
geom = DRW_cache_text_loose_edges_get(ob);
geom = DRW_cache_text_edge_wire_get(ob);
break;
case OB_SURF:
geom = DRW_cache_surf_edge_wire_get(ob);

View File

@@ -794,6 +794,10 @@ GPUBatch *DRW_gpencil_dummy_buffer_get(void)
/* -------------------------------------------------------------------- */
/** \name Common Object API
*
* \note Curve and text objects evaluate to the evaluated geometry set's mesh component if
* they have a surface, so curve objects themselves do not have a surface (the mesh component
* is presented to render engines as a separate object).
* \{ */
GPUBatch *DRW_cache_object_all_edges_get(Object *ob)
@@ -814,11 +818,11 @@ GPUBatch *DRW_cache_object_edge_detection_get(Object *ob, bool *r_is_manifold)
case OB_MESH:
return DRW_cache_mesh_edge_detection_get(ob, r_is_manifold);
case OB_CURVE:
return DRW_cache_curve_edge_detection_get(ob, r_is_manifold);
return NULL;
case OB_SURF:
return DRW_cache_surf_edge_detection_get(ob, r_is_manifold);
case OB_FONT:
return DRW_cache_text_edge_detection_get(ob, r_is_manifold);
return NULL;
case OB_MBALL:
return DRW_cache_mball_edge_detection_get(ob, r_is_manifold);
case OB_HAIR:
@@ -838,11 +842,11 @@ GPUBatch *DRW_cache_object_face_wireframe_get(Object *ob)
case OB_MESH:
return DRW_cache_mesh_face_wireframe_get(ob);
case OB_CURVE:
return DRW_cache_curve_face_wireframe_get(ob);
return NULL;
case OB_SURF:
return DRW_cache_surf_face_wireframe_get(ob);
case OB_FONT:
return DRW_cache_text_face_wireframe_get(ob);
return NULL;
case OB_MBALL:
return DRW_cache_mball_face_wireframe_get(ob);
case OB_HAIR:
@@ -865,11 +869,11 @@ GPUBatch *DRW_cache_object_loose_edges_get(struct Object *ob)
case OB_MESH:
return DRW_cache_mesh_loose_edges_get(ob);
case OB_CURVE:
return DRW_cache_curve_loose_edges_get(ob);
return NULL;
case OB_SURF:
return DRW_cache_surf_loose_edges_get(ob);
case OB_FONT:
return DRW_cache_text_loose_edges_get(ob);
return NULL;
case OB_MBALL:
return NULL;
case OB_HAIR:
@@ -889,11 +893,11 @@ GPUBatch *DRW_cache_object_surface_get(Object *ob)
case OB_MESH:
return DRW_cache_mesh_surface_get(ob);
case OB_CURVE:
return DRW_cache_curve_surface_get(ob);
return NULL;
case OB_SURF:
return DRW_cache_surf_surface_get(ob);
case OB_FONT:
return DRW_cache_text_surface_get(ob);
return NULL;
case OB_MBALL:
return DRW_cache_mball_surface_get(ob);
case OB_HAIR:
@@ -939,9 +943,9 @@ int DRW_cache_object_material_count_get(struct Object *ob)
Mesh *me = BKE_object_get_evaluated_mesh(ob);
if (me != NULL && type != OB_POINTCLOUD) {
/* Some object types (e.g. curves) can have a Curve in ob->data, but will be rendered as mesh.
* For point clouds this never happens. Ideally this check would happen at another level and we
* would just have to care about ob->data here. */
/* Some object types can have one data type in ob->data, but will be rendered as mesh.
* For point clouds this never happens. Ideally this check would happen at another level
* and we would just have to care about ob->data here. */
type = OB_MESH;
}
@@ -974,11 +978,11 @@ GPUBatch **DRW_cache_object_surface_material_get(struct Object *ob,
case OB_MESH:
return DRW_cache_mesh_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
case OB_CURVE:
return DRW_cache_curve_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
return NULL;
case OB_SURF:
return DRW_cache_surf_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
case OB_FONT:
return DRW_cache_text_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
return NULL;
case OB_MBALL:
return DRW_cache_mball_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
case OB_HAIR:
@@ -2929,20 +2933,13 @@ GPUBatch *DRW_cache_mesh_surface_mesh_analysis_get(Object *ob)
GPUBatch *DRW_cache_curve_edge_wire_get(Object *ob)
{
BLI_assert(ob->type == OB_CURVE);
struct Curve *cu = ob->data;
struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
}
return DRW_curve_batch_cache_get_wire_edge(cu);
}
GPUBatch *DRW_cache_curve_edge_normal_get(Object *ob)
{
BLI_assert(ob->type == OB_CURVE);
struct Curve *cu = ob->data;
return DRW_curve_batch_cache_get_normal_edge(cu);
}
@@ -2963,75 +2960,6 @@ GPUBatch *DRW_cache_curve_vert_overlay_get(Object *ob)
return DRW_curve_batch_cache_get_edit_verts(cu);
}
GPUBatch *DRW_cache_curve_surface_get(Object *ob)
{
BLI_assert(ob->type == OB_CURVE);
struct Curve *cu = ob->data;
struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_surface(mesh_eval);
}
return DRW_curve_batch_cache_get_triangles_with_normals(cu);
}
GPUBatch *DRW_cache_curve_loose_edges_get(Object *ob)
{
BLI_assert(ob->type == OB_CURVE);
struct Curve *cu = ob->data;
struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
}
/* TODO */
UNUSED_VARS(cu);
return NULL;
}
GPUBatch *DRW_cache_curve_face_wireframe_get(Object *ob)
{
BLI_assert(ob->type == OB_CURVE);
struct Curve *cu = ob->data;
struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_wireframes_face(mesh_eval);
}
return DRW_curve_batch_cache_get_wireframes_face(cu);
}
GPUBatch *DRW_cache_curve_edge_detection_get(Object *ob, bool *r_is_manifold)
{
BLI_assert(ob->type == OB_CURVE);
struct Curve *cu = ob->data;
struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_edge_detection(mesh_eval, r_is_manifold);
}
return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold);
}
/* Return list of batches */
GPUBatch **DRW_cache_curve_surface_shaded_get(Object *ob,
struct GPUMaterial **gpumat_array,
uint gpumat_array_len)
{
BLI_assert(ob->type == OB_CURVE);
struct Curve *cu = ob->data;
struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len);
}
return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len);
}
/** \} */
/* -------------------------------------------------------------------- */
@@ -3075,96 +3003,9 @@ GPUBatch *DRW_cache_text_edge_wire_get(Object *ob)
{
BLI_assert(ob->type == OB_FONT);
struct Curve *cu = ob->data;
struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
const bool has_surface = (cu->flag & (CU_FRONT | CU_BACK)) || cu->ext1 != 0.0f ||
cu->ext2 != 0.0f;
if (!has_surface) {
return NULL;
}
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
}
return DRW_curve_batch_cache_get_wire_edge(cu);
}
GPUBatch *DRW_cache_text_surface_get(Object *ob)
{
BLI_assert(ob->type == OB_FONT);
struct Curve *cu = ob->data;
struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (cu->editfont && (cu->flag & CU_FAST)) {
return NULL;
}
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_surface(mesh_eval);
}
return DRW_curve_batch_cache_get_triangles_with_normals(cu);
}
GPUBatch *DRW_cache_text_edge_detection_get(Object *ob, bool *r_is_manifold)
{
BLI_assert(ob->type == OB_FONT);
struct Curve *cu = ob->data;
struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (cu->editfont && (cu->flag & CU_FAST)) {
return NULL;
}
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_edge_detection(mesh_eval, r_is_manifold);
}
return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold);
}
GPUBatch *DRW_cache_text_loose_edges_get(Object *ob)
{
BLI_assert(ob->type == OB_FONT);
struct Curve *cu = ob->data;
struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (cu->editfont && (cu->flag & CU_FAST)) {
return NULL;
}
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
}
return DRW_curve_batch_cache_get_wire_edge(cu);
}
GPUBatch *DRW_cache_text_face_wireframe_get(Object *ob)
{
BLI_assert(ob->type == OB_FONT);
struct Curve *cu = ob->data;
struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (cu->editfont && (cu->flag & CU_FAST)) {
return NULL;
}
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_wireframes_face(mesh_eval);
}
return DRW_curve_batch_cache_get_wireframes_face(cu);
}
GPUBatch **DRW_cache_text_surface_shaded_get(Object *ob,
struct GPUMaterial **gpumat_array,
uint gpumat_array_len)
{
BLI_assert(ob->type == OB_FONT);
struct Curve *cu = ob->data;
struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
if (cu->editfont && (cu->flag & CU_FAST)) {
return NULL;
}
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len);
}
return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len);
}
/** \} */
/* -------------------------------------------------------------------- */
@@ -3544,6 +3385,8 @@ void drw_batch_cache_validate(Object *ob)
break;
case OB_CURVE:
case OB_FONT:
DRW_curve_batch_cache_validate((Curve *)ob->data);
break;
case OB_SURF:
if (mesh_eval != NULL) {
DRW_mesh_batch_cache_validate(mesh_eval);
@@ -3592,6 +3435,8 @@ void drw_batch_cache_generate_requested(Object *ob)
break;
case OB_CURVE:
case OB_FONT:
DRW_curve_batch_cache_create_requested(ob, scene);
break;
case OB_SURF:
if (mesh_eval) {
DRW_mesh_batch_cache_create_requested(
@@ -3618,8 +3463,6 @@ void DRW_batch_cache_free_old(Object *ob, int ctime)
case OB_MESH:
DRW_mesh_batch_cache_free_old((Mesh *)ob->data, ctime);
break;
case OB_CURVE:
case OB_FONT:
case OB_SURF:
if (mesh_eval) {
DRW_mesh_batch_cache_free_old(mesh_eval, ctime);

View File

@@ -150,28 +150,14 @@ struct GPUBatch *DRW_cache_mesh_surface_mesh_analysis_get(struct Object *ob);
struct GPUBatch *DRW_cache_mesh_face_wireframe_get(struct Object *ob);
/* Curve */
struct GPUBatch *DRW_cache_curve_surface_get(struct Object *ob);
struct GPUBatch **DRW_cache_curve_surface_shaded_get(struct Object *ob,
struct GPUMaterial **gpumat_array,
uint gpumat_array_len);
struct GPUBatch *DRW_cache_curve_loose_edges_get(struct Object *ob);
struct GPUBatch *DRW_cache_curve_edge_wire_get(struct Object *ob);
struct GPUBatch *DRW_cache_curve_face_wireframe_get(struct Object *ob);
struct GPUBatch *DRW_cache_curve_edge_detection_get(struct Object *ob, bool *r_is_manifold);
/* edit-mode */
struct GPUBatch *DRW_cache_curve_edge_normal_get(struct Object *ob);
struct GPUBatch *DRW_cache_curve_edge_overlay_get(struct Object *ob);
struct GPUBatch *DRW_cache_curve_vert_overlay_get(struct Object *ob);
/* Font */
struct GPUBatch *DRW_cache_text_surface_get(struct Object *ob);
struct GPUBatch *DRW_cache_text_edge_detection_get(struct Object *ob, bool *r_is_manifold);
struct GPUBatch *DRW_cache_text_loose_edges_get(struct Object *ob);
struct GPUBatch *DRW_cache_text_edge_wire_get(struct Object *ob);
struct GPUBatch **DRW_cache_text_surface_shaded_get(struct Object *ob,
struct GPUMaterial **gpumat_array,
uint gpumat_array_len);
struct GPUBatch *DRW_cache_text_face_wireframe_get(struct Object *ob);
/* Surface */
struct GPUBatch *DRW_cache_surf_surface_get(struct Object *ob);

View File

@@ -112,43 +112,6 @@ static void curve_render_overlay_verts_edges_len_get(ListBase *lb,
}
}
static void curve_render_wire_verts_edges_len_get(const CurveCache *ob_curve_cache,
int *r_curve_len,
int *r_vert_len,
int *r_edge_len)
{
BLI_assert(r_vert_len || r_edge_len);
int vert_len = 0;
int edge_len = 0;
int curve_len = 0;
LISTBASE_FOREACH (const BevList *, bl, &ob_curve_cache->bev) {
if (bl->nr > 0) {
const bool is_cyclic = bl->poly != -1;
edge_len += (is_cyclic) ? bl->nr : bl->nr - 1;
vert_len += bl->nr;
curve_len += 1;
}
}
LISTBASE_FOREACH (const DispList *, dl, &ob_curve_cache->disp) {
if (ELEM(dl->type, DL_SEGM, DL_POLY)) {
BLI_assert(dl->parts == 1);
const bool is_cyclic = dl->type == DL_POLY;
edge_len += (is_cyclic) ? dl->nr : dl->nr - 1;
vert_len += dl->nr;
curve_len += 1;
}
}
if (r_vert_len) {
*r_vert_len = vert_len;
}
if (r_edge_len) {
*r_edge_len = edge_len;
}
if (r_curve_len) {
*r_curve_len = curve_len;
}
}
static void curve_eval_render_wire_verts_edges_len_get(const CurveEval &curve_eval,
int *r_curve_len,
int *r_vert_len,
@@ -245,9 +208,7 @@ enum {
/*
* ob_curve_cache can be NULL, only needed for CU_DATATYPE_WIRE
*/
static CurveRenderData *curve_render_data_create(Curve *cu,
CurveCache *ob_curve_cache,
const int types)
static CurveRenderData *curve_render_data_create(Curve *cu, Object *object, const int types)
{
CurveRenderData *rdata = (CurveRenderData *)MEM_callocN(sizeof(*rdata), __func__);
rdata->types = types;
@@ -256,9 +217,10 @@ static CurveRenderData *curve_render_data_create(Curve *cu,
rdata->actnu = cu->actnu;
rdata->actvert = cu->actvert;
rdata->ob_curve_cache = ob_curve_cache;
rdata->curve_eval = cu->curve_eval;
rdata->ob_curve_cache = object->runtime.curve_cache;
if (object->runtime.geometry_set_eval != nullptr) {
rdata->curve_eval = object->runtime.geometry_set_eval->get_curve_for_read();
}
if (types & CU_DATATYPE_WIRE) {
if (rdata->curve_eval != nullptr) {
@@ -267,12 +229,6 @@ static CurveRenderData *curve_render_data_create(Curve *cu,
&rdata->wire.vert_len,
&rdata->wire.edge_len);
}
else {
curve_render_wire_verts_edges_len_get(rdata->ob_curve_cache,
&rdata->wire.curve_len,
&rdata->wire.vert_len,
&rdata->wire.edge_len);
}
}
if (cu->editnurb) {
@@ -594,6 +550,10 @@ void DRW_curve_batch_cache_free(Curve *cu)
/* GPUBatch cache usage. */
static void curve_create_curves_pos(CurveRenderData *rdata, GPUVertBuf *vbo_curves_pos)
{
if (rdata->curve_eval == nullptr) {
return;
}
static GPUVertFormat format = {0};
static struct {
uint pos;
@@ -606,46 +566,26 @@ static void curve_create_curves_pos(CurveRenderData *rdata, GPUVertBuf *vbo_curv
GPU_vertbuf_init_with_format(vbo_curves_pos, &format);
GPU_vertbuf_data_alloc(vbo_curves_pos, vert_len);
if (rdata->curve_eval != nullptr) {
const CurveEval &curve_eval = *rdata->curve_eval;
Span<SplinePtr> splines = curve_eval.splines();
Array<int> offsets = curve_eval.evaluated_point_offsets();
BLI_assert(offsets.last() == vert_len);
const CurveEval &curve_eval = *rdata->curve_eval;
Span<SplinePtr> splines = curve_eval.splines();
Array<int> offsets = curve_eval.evaluated_point_offsets();
BLI_assert(offsets.last() == vert_len);
for (const int i_spline : splines.index_range()) {
Span<float3> positions = splines[i_spline]->evaluated_positions();
for (const int i_point : positions.index_range()) {
GPU_vertbuf_attr_set(
vbo_curves_pos, attr_id.pos, offsets[i_spline] + i_point, positions[i_point]);
}
for (const int i_spline : splines.index_range()) {
Span<float3> positions = splines[i_spline]->evaluated_positions();
for (const int i_point : positions.index_range()) {
GPU_vertbuf_attr_set(
vbo_curves_pos, attr_id.pos, offsets[i_spline] + i_point, positions[i_point]);
}
}
else {
BLI_assert(rdata->ob_curve_cache != nullptr);
int v_idx = 0;
LISTBASE_FOREACH (const BevList *, bl, &rdata->ob_curve_cache->bev) {
if (bl->nr <= 0) {
continue;
}
const int i_end = v_idx + bl->nr;
for (const BevPoint *bevp = bl->bevpoints; v_idx < i_end; v_idx++, bevp++) {
GPU_vertbuf_attr_set(vbo_curves_pos, attr_id.pos, v_idx, bevp->vec);
}
}
LISTBASE_FOREACH (const DispList *, dl, &rdata->ob_curve_cache->disp) {
if (ELEM(dl->type, DL_SEGM, DL_POLY)) {
for (int i = 0; i < dl->nr; v_idx++, i++) {
GPU_vertbuf_attr_set(vbo_curves_pos, attr_id.pos, v_idx, &((float(*)[3])dl->verts)[i]);
}
}
}
BLI_assert(v_idx == vert_len);
}
}
static void curve_create_curves_lines(CurveRenderData *rdata, GPUIndexBuf *ibo_curve_lines)
{
if (rdata->curve_eval == nullptr) {
return;
}
const int vert_len = curve_render_data_wire_verts_len_get(rdata);
const int edge_len = curve_render_data_wire_edges_len_get(rdata);
const int curve_len = curve_render_data_wire_curve_len_get(rdata);
@@ -655,54 +595,20 @@ static void curve_create_curves_lines(CurveRenderData *rdata, GPUIndexBuf *ibo_c
GPUIndexBufBuilder elb;
GPU_indexbuf_init_ex(&elb, GPU_PRIM_LINE_STRIP, index_len, vert_len);
if (rdata->curve_eval != nullptr) {
const CurveEval &curve_eval = *rdata->curve_eval;
Span<SplinePtr> splines = curve_eval.splines();
Array<int> offsets = curve_eval.evaluated_point_offsets();
BLI_assert(offsets.last() == vert_len);
const CurveEval &curve_eval = *rdata->curve_eval;
Span<SplinePtr> splines = curve_eval.splines();
Array<int> offsets = curve_eval.evaluated_point_offsets();
BLI_assert(offsets.last() == vert_len);
for (const int i_spline : splines.index_range()) {
const int eval_size = splines[i_spline]->evaluated_points_size();
if (splines[i_spline]->is_cyclic() && splines[i_spline]->evaluated_edges_size() > 1) {
GPU_indexbuf_add_generic_vert(&elb, offsets[i_spline] + eval_size - 1);
}
for (const int i_point : IndexRange(eval_size)) {
GPU_indexbuf_add_generic_vert(&elb, offsets[i_spline] + i_point);
}
GPU_indexbuf_add_primitive_restart(&elb);
for (const int i_spline : splines.index_range()) {
const int eval_size = splines[i_spline]->evaluated_points_size();
if (splines[i_spline]->is_cyclic() && splines[i_spline]->evaluated_edges_size() > 1) {
GPU_indexbuf_add_generic_vert(&elb, offsets[i_spline] + eval_size - 1);
}
}
else {
BLI_assert(rdata->ob_curve_cache != nullptr);
int v_idx = 0;
LISTBASE_FOREACH (const BevList *, bl, &rdata->ob_curve_cache->bev) {
if (bl->nr <= 0) {
continue;
}
const bool is_cyclic = bl->poly != -1;
if (is_cyclic) {
GPU_indexbuf_add_generic_vert(&elb, v_idx + (bl->nr - 1));
}
for (int i = 0; i < bl->nr; i++) {
GPU_indexbuf_add_generic_vert(&elb, v_idx + i);
}
GPU_indexbuf_add_primitive_restart(&elb);
v_idx += bl->nr;
}
LISTBASE_FOREACH (const DispList *, dl, &rdata->ob_curve_cache->disp) {
if (ELEM(dl->type, DL_SEGM, DL_POLY)) {
const bool is_cyclic = dl->type == DL_POLY;
if (is_cyclic) {
GPU_indexbuf_add_generic_vert(&elb, v_idx + (dl->nr - 1));
}
for (int i = 0; i < dl->nr; i++) {
GPU_indexbuf_add_generic_vert(&elb, v_idx + i);
}
GPU_indexbuf_add_primitive_restart(&elb);
v_idx += dl->nr;
}
for (const int i_point : IndexRange(eval_size)) {
GPU_indexbuf_add_generic_vert(&elb, offsets[i_spline] + i_point);
}
GPU_indexbuf_add_primitive_restart(&elb);
}
GPU_indexbuf_build_in_place(&elb, ibo_curve_lines);
@@ -1148,7 +1054,7 @@ void DRW_curve_batch_cache_create_requested(Object *ob, const struct Scene *scen
printf(" mr_flag %d\n\n", mr_flag);
#endif
CurveRenderData *rdata = curve_render_data_create(cu, ob->runtime.curve_cache, mr_flag);
CurveRenderData *rdata = curve_render_data_create(cu, ob, mr_flag);
/* The object's curve cache can be empty (in one case because we use #CurveEval's cache instead),
* If so, point to an empty DispList list to avoid the need to check for null in the following

View File

@@ -535,7 +535,6 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf)
newob = true;
cu = (Curve *)obedit->data;
cu->flag |= CU_DEFORM_FILL;
if (type & CU_PRIM_PATH) {
cu->flag |= CU_PATH | CU_3D;

View File

@@ -270,7 +270,7 @@ Object *spreadsheet_get_object_eval(const SpaceSpreadsheet *sspreadsheet,
return nullptr;
}
Object *object_orig = (Object *)used_id;
if (!ELEM(object_orig->type, OB_MESH, OB_POINTCLOUD, OB_VOLUME)) {
if (!ELEM(object_orig->type, OB_MESH, OB_POINTCLOUD, OB_VOLUME, OB_CURVE)) {
return nullptr;
}

View File

@@ -94,7 +94,7 @@ void AbcCurveReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSele
{
Curve *cu = BKE_curve_add(bmain, m_data_name.c_str(), OB_CURVE);
cu->flag |= CU_DEFORM_FILL | CU_3D;
cu->flag |= CU_3D;
cu->actvert = CU_ACT_NONE;
cu->resolu = 1;

View File

@@ -301,12 +301,6 @@ typedef struct Curve {
char _pad2[6];
float fsize_realtime;
/**
* A pointer to curve data from geometry nodes, currently only set for evaluated
* objects by the dependency graph iterator, and owned by #geometry_set_eval.
*/
struct CurveEval *curve_eval;
void *batch_cache;
} Curve;
@@ -344,8 +338,7 @@ enum {
CU_DS_EXPAND = 1 << 11,
/** make use of the path radius if this is enabled (default for new curves) */
CU_PATH_RADIUS = 1 << 12,
/** fill 2d curve after deformation */
CU_DEFORM_FILL = 1 << 13,
/* CU_DEFORM_FILL = 1 << 13, */ /* DEPRECATED */
/** fill bevel caps */
CU_FILL_CAPS = 1 << 14,
/** map taper object to beveled area */

View File

@@ -1809,12 +1809,6 @@ static void rna_def_curve(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Twist Smooth", "Smoothing iteration for tangents");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
prop = RNA_def_property(srna, "use_fill_deform", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_DEFORM_FILL);
RNA_def_property_ui_text(
prop, "Fill Deformed", "Fill curve after applying shape keys and all modifiers");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
prop = RNA_def_property(srna, "use_fill_caps", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_FILL_CAPS);
RNA_def_property_ui_text(prop, "Fill Caps", "Fill caps for beveled curves");

View File

@@ -1201,9 +1201,10 @@ ModifierTypeInfo modifierType_Nodes = {
/* srna */ &RNA_NodesModifier,
/* type */ eModifierTypeType_Constructive,
/* flags */
static_cast<ModifierTypeFlag>(
eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode |
eModifierTypeFlag_EnableInEditmode | eModifierTypeFlag_SupportsMapping),
static_cast<ModifierTypeFlag>(eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs |
eModifierTypeFlag_SupportsEditmode |
eModifierTypeFlag_EnableInEditmode |
eModifierTypeFlag_SupportsMapping),
/* icon */ ICON_NODETREE,
/* copyData */ copyData,