Compare commits
66 Commits
temp-inter
...
curve-node
Author | SHA1 | Date | |
---|---|---|---|
b9343028e4 | |||
2ee86901fd | |||
8e907841c4 | |||
60e68e8b28 | |||
a26494e196 | |||
b95d647fb1 | |||
ff75ce1016 | |||
9ccf5c3d4c | |||
9c6b2331a1 | |||
5cdf5416d9 | |||
18a43b5dd5 | |||
dbdb60a2b2 | |||
e5032cf821 | |||
16cf3a0014 | |||
c4562691da | |||
65d5595b4a | |||
f9ce74425c | |||
d6b296a5bf | |||
32d5cd8b52 | |||
ce5c6e4d0d | |||
b21c16b627 | |||
ca87f08814 | |||
af64b0ad5f | |||
cc13189d96 | |||
bb6b926b04 | |||
1cdfb9ad5a | |||
9363099526 | |||
98f8534789 | |||
9773b0fb0b | |||
6e2e772667 | |||
1ad81a6706 | |||
4c0c91cb60 | |||
e253b6bef3 | |||
49304aa303 | |||
f7b2d30d8f | |||
78c086f686 | |||
66e00013c9 | |||
86fc715349 | |||
3036b724f7 | |||
e77f3d92ee | |||
e0b3d64186 | |||
0dc68aeff8 | |||
4a89a39166 | |||
7ae47bc368 | |||
e51c10d71e | |||
229d30587b | |||
59be5bf228 | |||
65c326cbe9 | |||
e14ce0fefe | |||
3476da4d60 | |||
8203470174 | |||
afbb61dc35 | |||
61bd814f2b | |||
aa7c42d5f9 | |||
49fc3ddc5d | |||
59455f9b66 | |||
54241d1b77 | |||
5c2267bbd4 | |||
5ab4ce5856 | |||
8e1239eedf | |||
bf68462387 | |||
18355a505d | |||
7008d183c4 | |||
4a2eac8897 | |||
8ceb07bd58 | |||
0bc5800754 |
@@ -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
|
||||
|
@@ -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()
|
||||
|
@@ -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,
|
||||
|
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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_;
|
||||
}
|
||||
|
@@ -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. */
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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 */
|
||||
|
@@ -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");
|
||||
|
@@ -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,
|
||||
|
Reference in New Issue
Block a user