2011-10-10 09:38:02 +00:00
|
|
|
/*
|
2002-10-12 11:37:38 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
2008-01-07 19:13:47 +00:00
|
|
|
* of the License, or (at your option) any later version.
|
2002-10-12 11:37:38 +00:00
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2002-10-12 11:37:38 +00:00
|
|
|
*
|
|
|
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*/
|
2002-11-25 10:13:52 +00:00
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup bke
|
2011-02-27 20:40:57 +00:00
|
|
|
*/
|
|
|
|
|
|
2021-04-26 15:11:53 -05:00
|
|
|
#include <cmath>
|
|
|
|
|
#include <cstdio>
|
|
|
|
|
#include <cstring>
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
|
|
#include "DNA_curve_types.h"
|
2018-06-05 15:59:30 +02:00
|
|
|
#include "DNA_mesh_types.h"
|
2010-08-04 04:01:27 +00:00
|
|
|
#include "DNA_object_types.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "DNA_scene_types.h"
|
2014-01-03 14:18:06 +11:00
|
|
|
#include "DNA_vfont_types.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2020-02-26 14:24:57 +11:00
|
|
|
#include "BLI_bitmap.h"
|
2021-06-07 13:08:03 -05:00
|
|
|
#include "BLI_index_range.hh"
|
2020-02-26 14:24:57 +11:00
|
|
|
#include "BLI_linklist.h"
|
|
|
|
|
#include "BLI_listbase.h"
|
2009-11-10 20:43:45 +00:00
|
|
|
#include "BLI_math.h"
|
2020-02-26 14:24:57 +11:00
|
|
|
#include "BLI_memarena.h"
|
2010-11-03 01:56:02 +00:00
|
|
|
#include "BLI_scanfill.h"
|
2020-02-26 14:24:57 +11:00
|
|
|
#include "BLI_string.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2020-04-03 11:35:04 +02:00
|
|
|
#include "BKE_anim_path.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BKE_curve.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "BKE_displist.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BKE_font.h"
|
|
|
|
|
#include "BKE_key.h"
|
|
|
|
|
#include "BKE_lattice.h"
|
2020-02-10 12:58:59 +01:00
|
|
|
#include "BKE_lib_id.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "BKE_mball.h"
|
2015-03-25 22:36:43 +11:00
|
|
|
#include "BKE_mball_tessellate.h"
|
2018-06-05 15:59:30 +02:00
|
|
|
#include "BKE_mesh.h"
|
2005-08-14 12:17:34 +00:00
|
|
|
#include "BKE_modifier.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BKE_object.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2013-05-28 19:35:26 +00:00
|
|
|
#include "BLI_sys_types.h" // for intptr_t support
|
2008-08-17 17:08:00 +00:00
|
|
|
|
2017-04-06 15:37:46 +02:00
|
|
|
#include "DEG_depsgraph.h"
|
2017-04-06 16:11:50 +02:00
|
|
|
#include "DEG_depsgraph_query.h"
|
2017-04-06 15:37:46 +02:00
|
|
|
|
2021-06-07 13:08:03 -05:00
|
|
|
using blender::IndexRange;
|
|
|
|
|
|
2013-08-19 09:13:15 +00:00
|
|
|
static void boundbox_displist_object(Object *ob);
|
2005-07-17 04:17:33 +00:00
|
|
|
|
2021-06-07 13:12:06 -05:00
|
|
|
static void displist_elem_free(DispList *dl)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2012-03-24 06:18:31 +00:00
|
|
|
if (dl) {
|
2019-04-22 09:39:35 +10:00
|
|
|
if (dl->verts) {
|
2012-03-24 06:18:31 +00:00
|
|
|
MEM_freeN(dl->verts);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
if (dl->nors) {
|
2012-03-24 06:18:31 +00:00
|
|
|
MEM_freeN(dl->nors);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
if (dl->index) {
|
2012-03-24 06:18:31 +00:00
|
|
|
MEM_freeN(dl->index);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
MEM_freeN(dl);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-07 06:58:03 +00:00
|
|
|
void BKE_displist_free(ListBase *lb)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
|
|
|
|
DispList *dl;
|
|
|
|
|
|
2021-04-26 15:11:53 -05:00
|
|
|
while ((dl = (DispList *)BLI_pophead(lb))) {
|
2021-06-07 13:12:06 -05:00
|
|
|
displist_elem_free(dl);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-07 06:58:03 +00:00
|
|
|
DispList *BKE_displist_find(ListBase *lb, int type)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2020-10-21 23:52:29 -05:00
|
|
|
LISTBASE_FOREACH (DispList *, dl, lb) {
|
2019-04-22 09:39:35 +10:00
|
|
|
if (dl->type == type) {
|
2012-05-07 06:58:03 +00:00
|
|
|
return dl;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2021-04-26 15:11:53 -05:00
|
|
|
return nullptr;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2021-03-31 18:07:15 -05:00
|
|
|
bool BKE_displist_has_faces(const ListBase *lb)
|
2004-10-29 15:39:01 +00:00
|
|
|
{
|
2021-03-31 18:07:15 -05:00
|
|
|
LISTBASE_FOREACH (const DispList *, dl, lb) {
|
2014-07-20 01:30:29 +10:00
|
|
|
if (ELEM(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)) {
|
2013-03-20 23:14:18 +00:00
|
|
|
return true;
|
2012-03-25 22:35:18 +00:00
|
|
|
}
|
2004-10-29 15:39:01 +00:00
|
|
|
}
|
2012-05-07 06:58:03 +00:00
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
return false;
|
2004-10-29 15:39:01 +00:00
|
|
|
}
|
|
|
|
|
|
2021-03-31 18:07:15 -05:00
|
|
|
void BKE_displist_copy(ListBase *lbn, const ListBase *lb)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2012-05-07 06:58:03 +00:00
|
|
|
BKE_displist_free(lbn);
|
|
|
|
|
|
2020-10-21 23:52:29 -05:00
|
|
|
LISTBASE_FOREACH (const DispList *, dl, lb) {
|
2021-04-26 15:11:53 -05:00
|
|
|
DispList *dln = (DispList *)MEM_dupallocN(dl);
|
2002-10-12 11:37:38 +00:00
|
|
|
BLI_addtail(lbn, dln);
|
2021-04-26 15:11:53 -05:00
|
|
|
dln->verts = (float *)MEM_dupallocN(dl->verts);
|
|
|
|
|
dln->nors = (float *)MEM_dupallocN(dl->nors);
|
|
|
|
|
dln->index = (int *)MEM_dupallocN(dl->index);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-07 06:58:03 +00:00
|
|
|
void BKE_displist_normals_add(ListBase *lb)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
|
|
|
|
float *vdata, *ndata, nor[3];
|
|
|
|
|
float *v1, *v2, *v3, *v4;
|
|
|
|
|
float *n1, *n2, *n3, *n4;
|
|
|
|
|
int a, b, p1, p2, p3, p4;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-21 23:52:29 -05:00
|
|
|
LISTBASE_FOREACH (DispList *, dl, lb) {
|
2012-05-06 17:22:54 +00:00
|
|
|
if (dl->type == DL_INDEX3) {
|
2021-04-26 15:11:53 -05:00
|
|
|
if (dl->nors == nullptr) {
|
|
|
|
|
dl->nors = (float *)MEM_callocN(sizeof(float[3]), "dlnors");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-26 19:03:30 +10:00
|
|
|
if (dl->flag & DL_BACK_CURVE) {
|
2012-05-07 06:58:03 +00:00
|
|
|
dl->nors[2] = -1.0f;
|
2017-05-26 19:03:30 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2012-05-07 06:58:03 +00:00
|
|
|
dl->nors[2] = 1.0f;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2017-05-26 19:03:30 +10:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2012-05-06 17:22:54 +00:00
|
|
|
else if (dl->type == DL_SURF) {
|
2021-04-26 15:11:53 -05:00
|
|
|
if (dl->nors == nullptr) {
|
|
|
|
|
dl->nors = (float *)MEM_callocN(sizeof(float[3]) * dl->nr * dl->parts, "dlnors");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-06 17:22:54 +00:00
|
|
|
vdata = dl->verts;
|
|
|
|
|
ndata = dl->nors;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-06 17:22:54 +00:00
|
|
|
for (a = 0; a < dl->parts; a++) {
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (BKE_displist_surfindex_get(dl, a, &b, &p1, &p2, &p3, &p4) == 0) {
|
2008-10-06 06:10:14 +00:00
|
|
|
break;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-06 17:22:54 +00:00
|
|
|
v1 = vdata + 3 * p1;
|
|
|
|
|
n1 = ndata + 3 * p1;
|
|
|
|
|
v2 = vdata + 3 * p2;
|
|
|
|
|
n2 = ndata + 3 * p2;
|
|
|
|
|
v3 = vdata + 3 * p3;
|
|
|
|
|
n3 = ndata + 3 * p3;
|
|
|
|
|
v4 = vdata + 3 * p4;
|
|
|
|
|
n4 = ndata + 3 * p4;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-06 17:22:54 +00:00
|
|
|
for (; b < dl->nr; b++) {
|
2012-04-29 15:47:02 +00:00
|
|
|
normal_quad_v3(nor, v1, v3, v4, v2);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-04-21 12:27:48 +00:00
|
|
|
add_v3_v3(n1, nor);
|
|
|
|
|
add_v3_v3(n2, nor);
|
|
|
|
|
add_v3_v3(n3, nor);
|
|
|
|
|
add_v3_v3(n4, nor);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-06 17:22:54 +00:00
|
|
|
v2 = v1;
|
|
|
|
|
v1 += 3;
|
|
|
|
|
v4 = v3;
|
|
|
|
|
v3 += 3;
|
|
|
|
|
n2 = n1;
|
|
|
|
|
n1 += 3;
|
|
|
|
|
n4 = n3;
|
|
|
|
|
n3 += 3;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2012-05-06 17:22:54 +00:00
|
|
|
a = dl->parts * dl->nr;
|
|
|
|
|
v1 = ndata;
|
2012-03-24 06:18:31 +00:00
|
|
|
while (a--) {
|
2009-11-10 20:43:45 +00:00
|
|
|
normalize_v3(v1);
|
2012-05-06 17:22:54 +00:00
|
|
|
v1 += 3;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-31 18:07:15 -05:00
|
|
|
void BKE_displist_count(const ListBase *lb, int *totvert, int *totface, int *tottri)
|
2006-05-28 11:49:22 +00:00
|
|
|
{
|
2021-03-31 18:07:15 -05:00
|
|
|
LISTBASE_FOREACH (const DispList *, dl, lb) {
|
2012-12-27 03:51:45 +00:00
|
|
|
int vert_tot = 0;
|
|
|
|
|
int face_tot = 0;
|
|
|
|
|
int tri_tot = 0;
|
2019-03-05 19:06:59 +01:00
|
|
|
bool cyclic_u = dl->flag & DL_CYCL_U;
|
|
|
|
|
bool cyclic_v = dl->flag & DL_CYCL_V;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-04-28 06:31:57 +00:00
|
|
|
switch (dl->type) {
|
2006-05-28 11:49:22 +00:00
|
|
|
case DL_SURF: {
|
2019-03-05 19:06:59 +01:00
|
|
|
int segments_u = dl->nr - (cyclic_u == false);
|
|
|
|
|
int segments_v = dl->parts - (cyclic_v == false);
|
2012-12-27 03:51:45 +00:00
|
|
|
vert_tot = dl->nr * dl->parts;
|
2019-03-05 19:06:59 +01:00
|
|
|
face_tot = segments_u * segments_v;
|
2012-12-27 03:51:45 +00:00
|
|
|
tri_tot = face_tot * 2;
|
2006-05-28 11:49:22 +00:00
|
|
|
break;
|
2012-12-27 03:51:45 +00:00
|
|
|
}
|
2006-05-28 11:49:22 +00:00
|
|
|
case DL_INDEX3: {
|
2012-12-27 03:51:45 +00:00
|
|
|
vert_tot = dl->nr;
|
|
|
|
|
face_tot = dl->parts;
|
|
|
|
|
tri_tot = face_tot;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2006-05-28 11:49:22 +00:00
|
|
|
case DL_INDEX4: {
|
2012-12-27 03:51:45 +00:00
|
|
|
vert_tot = dl->nr;
|
|
|
|
|
face_tot = dl->parts;
|
|
|
|
|
tri_tot = face_tot * 2;
|
2006-05-28 11:49:22 +00:00
|
|
|
break;
|
2012-12-27 03:51:45 +00:00
|
|
|
}
|
2006-05-28 11:49:22 +00:00
|
|
|
case DL_POLY:
|
|
|
|
|
case DL_SEGM: {
|
2012-12-27 03:51:45 +00:00
|
|
|
vert_tot = dl->nr * dl->parts;
|
2012-05-07 06:58:03 +00:00
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2012-12-27 03:51:45 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-27 03:51:45 +00:00
|
|
|
*totvert += vert_tot;
|
|
|
|
|
*totface += face_tot;
|
|
|
|
|
*tottri += tri_tot;
|
2006-05-28 11:49:22 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-31 18:07:15 -05:00
|
|
|
bool BKE_displist_surfindex_get(
|
|
|
|
|
const DispList *dl, int a, int *b, int *p1, int *p2, int *p3, int *p4)
|
2008-10-06 06:10:14 +00:00
|
|
|
{
|
2012-05-06 17:22:54 +00:00
|
|
|
if ((dl->flag & DL_CYCL_V) == 0 && a == (dl->parts) - 1) {
|
2013-03-20 23:14:18 +00:00
|
|
|
return false;
|
2008-10-06 06:10:14 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:18:31 +00:00
|
|
|
if (dl->flag & DL_CYCL_U) {
|
2012-05-06 17:22:54 +00:00
|
|
|
(*p1) = dl->nr * a;
|
|
|
|
|
(*p2) = (*p1) + dl->nr - 1;
|
|
|
|
|
(*p3) = (*p1) + dl->nr;
|
|
|
|
|
(*p4) = (*p2) + dl->nr;
|
|
|
|
|
(*b) = 0;
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-05-06 17:22:54 +00:00
|
|
|
(*p2) = dl->nr * a;
|
|
|
|
|
(*p1) = (*p2) + 1;
|
|
|
|
|
(*p4) = (*p2) + dl->nr;
|
|
|
|
|
(*p3) = (*p1) + dl->nr;
|
|
|
|
|
(*b) = 1;
|
2008-10-06 06:10:14 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-07 06:58:03 +00:00
|
|
|
if ((dl->flag & DL_CYCL_V) && a == dl->parts - 1) {
|
2012-05-06 17:22:54 +00:00
|
|
|
(*p3) -= dl->nr * dl->parts;
|
|
|
|
|
(*p4) -= dl->nr * dl->parts;
|
2008-10-06 06:10:14 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
return true;
|
2008-10-06 06:10:14 +00:00
|
|
|
}
|
2006-05-28 11:49:22 +00:00
|
|
|
|
|
|
|
|
/* ****************** make displists ********************* */
|
2018-04-02 16:11:11 +02:00
|
|
|
#ifdef __INTEL_COMPILER
|
|
|
|
|
/* ICC with the optimization -02 causes crashes. */
|
|
|
|
|
# pragma intel optimization_level 1
|
|
|
|
|
#endif
|
2021-02-16 21:40:16 -06:00
|
|
|
|
2021-02-12 16:06:17 -06:00
|
|
|
static void curve_to_displist(const Curve *cu,
|
|
|
|
|
const ListBase *nubase,
|
|
|
|
|
const bool for_render,
|
|
|
|
|
ListBase *r_dispbase)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2014-03-20 22:56:28 +11:00
|
|
|
const bool editmode = (!for_render && (cu->editnurb || cu->editfont));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-21 23:52:29 -05:00
|
|
|
LISTBASE_FOREACH (Nurb *, nu, nubase) {
|
2020-10-23 23:29:52 -05:00
|
|
|
if (nu->hide != 0 && editmode) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (!BKE_nurb_check_valid_u(nu)) {
|
2021-02-12 16:06:17 -06:00
|
|
|
continue;
|
2020-10-23 23:29:52 -05:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-12 16:06:17 -06:00
|
|
|
const int resolution = (for_render && cu->resolu_ren != 0) ? cu->resolu_ren : nu->resolu;
|
|
|
|
|
const bool is_cyclic = nu->flagu & CU_NURB_CYCLIC;
|
|
|
|
|
const BezTriple *bezt_first = &nu->bezt[0];
|
|
|
|
|
const BezTriple *bezt_last = &nu->bezt[nu->pntsu - 1];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-12 16:06:17 -06:00
|
|
|
if (nu->type == CU_BEZIER) {
|
|
|
|
|
int samples_len = 0;
|
|
|
|
|
for (int i = 1; i < nu->pntsu; i++) {
|
|
|
|
|
const BezTriple *prevbezt = &nu->bezt[i - 1];
|
|
|
|
|
const BezTriple *bezt = &nu->bezt[i];
|
2020-10-23 23:29:52 -05:00
|
|
|
if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) {
|
2021-02-12 16:06:17 -06:00
|
|
|
samples_len++;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2021-02-12 16:06:17 -06:00
|
|
|
samples_len += resolution;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2021-02-12 16:06:17 -06:00
|
|
|
}
|
|
|
|
|
if (is_cyclic) {
|
|
|
|
|
/* If the curve is cyclic, sample the last edge between the last and first points. */
|
|
|
|
|
if (bezt_first->h1 == HD_VECT && bezt_last->h2 == HD_VECT) {
|
|
|
|
|
samples_len++;
|
2020-10-23 23:29:52 -05:00
|
|
|
}
|
2021-02-12 16:06:17 -06:00
|
|
|
else {
|
|
|
|
|
samples_len += resolution;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Otherwise, we only need one additional sample to complete the last edge. */
|
|
|
|
|
samples_len++;
|
2020-10-23 23:29:52 -05:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-12 16:06:17 -06:00
|
|
|
/* Check that there are more than two points so the curve doesn't loop back on itself. This
|
|
|
|
|
* needs to be separate from `is_cyclic` because cyclic sampling can work with two points
|
|
|
|
|
* and resolution > 1. */
|
|
|
|
|
const bool use_cyclic_sample = is_cyclic && (samples_len != 2);
|
|
|
|
|
|
2021-04-26 15:11:53 -05:00
|
|
|
DispList *dl = (DispList *)MEM_callocN(sizeof(DispList), __func__);
|
2021-02-12 16:06:17 -06:00
|
|
|
/* Add one to the length because of 'BKE_curve_forward_diff_bezier'. */
|
2021-04-26 15:11:53 -05:00
|
|
|
dl->verts = (float *)MEM_mallocN(sizeof(float[3]) * (samples_len + 1), "dlverts");
|
2021-02-12 16:06:17 -06:00
|
|
|
BLI_addtail(r_dispbase, dl);
|
2020-10-23 23:29:52 -05:00
|
|
|
dl->parts = 1;
|
2021-02-12 16:06:17 -06:00
|
|
|
dl->nr = samples_len;
|
2020-10-23 23:29:52 -05:00
|
|
|
dl->col = nu->mat_nr;
|
|
|
|
|
dl->charidx = nu->charidx;
|
|
|
|
|
|
2021-02-12 16:06:17 -06:00
|
|
|
dl->type = use_cyclic_sample ? DL_POLY : DL_SEGM;
|
2020-10-23 23:29:52 -05:00
|
|
|
|
2021-02-12 16:06:17 -06:00
|
|
|
float *data = dl->verts;
|
|
|
|
|
for (int i = 1; i < nu->pntsu; i++) {
|
|
|
|
|
const BezTriple *prevbezt = &nu->bezt[i - 1];
|
|
|
|
|
const BezTriple *bezt = &nu->bezt[i];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-23 23:29:52 -05:00
|
|
|
if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) {
|
|
|
|
|
copy_v3_v3(data, prevbezt->vec[1]);
|
|
|
|
|
data += 3;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2021-02-12 16:06:17 -06:00
|
|
|
for (int j = 0; j < 3; j++) {
|
2020-10-23 23:29:52 -05:00
|
|
|
BKE_curve_forward_diff_bezier(prevbezt->vec[1][j],
|
|
|
|
|
prevbezt->vec[2][j],
|
|
|
|
|
bezt->vec[0][j],
|
|
|
|
|
bezt->vec[1][j],
|
|
|
|
|
data + j,
|
2021-02-12 16:06:17 -06:00
|
|
|
resolution,
|
2020-10-23 23:29:52 -05:00
|
|
|
sizeof(float[3]));
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2021-02-12 16:06:17 -06:00
|
|
|
data += 3 * resolution;
|
2020-10-23 23:29:52 -05:00
|
|
|
}
|
2021-02-12 16:06:17 -06:00
|
|
|
}
|
|
|
|
|
if (is_cyclic) {
|
|
|
|
|
if (bezt_first->h1 == HD_VECT && bezt_last->h2 == HD_VECT) {
|
|
|
|
|
copy_v3_v3(data, bezt_last->vec[1]);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
for (int j = 0; j < 3; j++) {
|
|
|
|
|
BKE_curve_forward_diff_bezier(bezt_last->vec[1][j],
|
|
|
|
|
bezt_last->vec[2][j],
|
|
|
|
|
bezt_first->vec[0][j],
|
|
|
|
|
bezt_first->vec[1][j],
|
|
|
|
|
data + j,
|
|
|
|
|
resolution,
|
|
|
|
|
sizeof(float[3]));
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2021-02-12 16:06:17 -06:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
copy_v3_v3(data, bezt_last->vec[1]);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2020-10-23 23:29:52 -05:00
|
|
|
}
|
|
|
|
|
else if (nu->type == CU_NURBS) {
|
2021-02-12 16:06:17 -06:00
|
|
|
const int len = (resolution * SEGMENTSU(nu));
|
2021-04-26 15:11:53 -05:00
|
|
|
DispList *dl = (DispList *)MEM_callocN(sizeof(DispList), __func__);
|
|
|
|
|
dl->verts = (float *)MEM_mallocN(len * sizeof(float[3]), "dlverts");
|
2021-02-12 16:06:17 -06:00
|
|
|
BLI_addtail(r_dispbase, dl);
|
2020-10-23 23:29:52 -05:00
|
|
|
dl->parts = 1;
|
|
|
|
|
dl->nr = len;
|
|
|
|
|
dl->col = nu->mat_nr;
|
|
|
|
|
dl->charidx = nu->charidx;
|
2021-02-12 16:06:17 -06:00
|
|
|
dl->type = is_cyclic ? DL_POLY : DL_SEGM;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-04-26 15:11:53 -05:00
|
|
|
BKE_nurb_makeCurve(nu, dl->verts, nullptr, nullptr, nullptr, resolution, sizeof(float[3]));
|
2020-10-23 23:29:52 -05:00
|
|
|
}
|
|
|
|
|
else if (nu->type == CU_POLY) {
|
2021-02-12 16:06:17 -06:00
|
|
|
const int len = nu->pntsu;
|
2021-04-26 15:11:53 -05:00
|
|
|
DispList *dl = (DispList *)MEM_callocN(sizeof(DispList), __func__);
|
|
|
|
|
dl->verts = (float *)MEM_mallocN(len * sizeof(float[3]), "dlverts");
|
2021-02-12 16:06:17 -06:00
|
|
|
BLI_addtail(r_dispbase, dl);
|
2020-10-23 23:29:52 -05:00
|
|
|
dl->parts = 1;
|
|
|
|
|
dl->nr = len;
|
|
|
|
|
dl->col = nu->mat_nr;
|
|
|
|
|
dl->charidx = nu->charidx;
|
2021-02-12 16:06:17 -06:00
|
|
|
dl->type = (is_cyclic && (dl->nr != 2)) ? DL_POLY : DL_SEGM;
|
2020-10-23 23:29:52 -05:00
|
|
|
|
2021-02-16 21:40:16 -06:00
|
|
|
float(*coords)[3] = (float(*)[3])dl->verts;
|
2021-02-12 16:06:17 -06:00
|
|
|
for (int i = 0; i < len; i++) {
|
|
|
|
|
const BPoint *bp = &nu->bp[i];
|
2021-02-16 21:40:16 -06:00
|
|
|
copy_v3_v3(coords[i], bp->vec);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-26 21:04:12 +00:00
|
|
|
/**
|
2019-08-01 13:53:25 +10:00
|
|
|
* \param normal_proj: Optional normal that's used to project the scanfill verts into 2d coords.
|
2013-04-26 21:04:12 +00:00
|
|
|
* Pass this along if known since it saves time calculating the normal.
|
2021-01-19 17:06:14 +11:00
|
|
|
* This is also used to initialize #DispList.nors (one normal per display list).
|
2018-12-12 12:50:58 +11:00
|
|
|
* \param flipnormal: Flip the normal (same as passing \a normal_proj negated)
|
2013-04-26 21:04:12 +00:00
|
|
|
*/
|
2021-02-12 16:06:17 -06:00
|
|
|
void BKE_displist_fill(const ListBase *dispbase,
|
2013-04-26 21:04:12 +00:00
|
|
|
ListBase *to,
|
|
|
|
|
const float normal_proj[3],
|
2021-02-12 16:06:17 -06:00
|
|
|
const bool flip_normal)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2021-04-26 15:11:53 -05:00
|
|
|
if (dispbase == nullptr) {
|
2012-05-07 06:58:03 +00:00
|
|
|
return;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
if (BLI_listbase_is_empty(dispbase)) {
|
2012-05-07 06:58:03 +00:00
|
|
|
return;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-12 16:06:17 -06:00
|
|
|
const int scanfill_flag = BLI_SCANFILL_CALC_REMOVE_DOUBLES | BLI_SCANFILL_CALC_POLYS |
|
|
|
|
|
BLI_SCANFILL_CALC_HOLES;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-12 16:06:17 -06:00
|
|
|
MemArena *sf_arena = BLI_memarena_new(BLI_SCANFILL_ARENA_SIZE, __func__);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-12 16:06:17 -06:00
|
|
|
short colnr = 0;
|
|
|
|
|
int charidx = 0;
|
|
|
|
|
bool should_continue = true;
|
|
|
|
|
while (should_continue) {
|
|
|
|
|
should_continue = false;
|
|
|
|
|
bool nextcol = false;
|
|
|
|
|
|
|
|
|
|
ScanFillContext sf_ctx;
|
2013-08-28 02:07:54 +00:00
|
|
|
BLI_scanfill_begin_arena(&sf_ctx, sf_arena);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-12 16:06:17 -06:00
|
|
|
int totvert = 0;
|
|
|
|
|
short dl_flag_accum = 0;
|
|
|
|
|
short dl_rt_accum = 0;
|
|
|
|
|
LISTBASE_FOREACH (const DispList *, dl, dispbase) {
|
2012-05-06 17:22:54 +00:00
|
|
|
if (dl->type == DL_POLY) {
|
2019-04-22 09:39:35 +10:00
|
|
|
if (charidx < dl->charidx) {
|
2021-02-12 16:06:17 -06:00
|
|
|
should_continue = true;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-05-06 17:22:54 +00:00
|
|
|
else if (charidx == dl->charidx) { /* character with needed index */
|
|
|
|
|
if (colnr == dl->col) {
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-02-05 05:22:21 +11:00
|
|
|
sf_ctx.poly_nr++;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-12 16:06:17 -06:00
|
|
|
/* Make verts and edges. */
|
2021-04-26 15:11:53 -05:00
|
|
|
ScanFillVert *sf_vert = nullptr;
|
|
|
|
|
ScanFillVert *sf_vert_last = nullptr;
|
|
|
|
|
ScanFillVert *sf_vert_new = nullptr;
|
2021-02-12 16:06:17 -06:00
|
|
|
for (int i = 0; i < dl->nr; i++) {
|
2012-05-13 14:47:53 +00:00
|
|
|
sf_vert_last = sf_vert;
|
2021-02-12 16:06:17 -06:00
|
|
|
sf_vert = BLI_scanfill_vert_add(&sf_ctx, &dl->verts[3 * i]);
|
2010-09-22 05:08:52 +00:00
|
|
|
totvert++;
|
2021-04-26 15:11:53 -05:00
|
|
|
if (sf_vert_last == nullptr) {
|
2012-05-13 14:47:53 +00:00
|
|
|
sf_vert_new = sf_vert;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2010-09-22 05:08:52 +00:00
|
|
|
else {
|
2012-05-13 14:47:53 +00:00
|
|
|
BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert);
|
2010-09-22 05:08:52 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-04-26 15:11:53 -05:00
|
|
|
if (sf_vert != nullptr && sf_vert_new != nullptr) {
|
2012-05-13 14:47:53 +00:00
|
|
|
BLI_scanfill_edge_add(&sf_ctx, sf_vert, sf_vert_new);
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2012-05-06 17:22:54 +00:00
|
|
|
else if (colnr < dl->col) {
|
2010-09-22 05:08:52 +00:00
|
|
|
/* got poly with next material at current char */
|
2021-02-12 16:06:17 -06:00
|
|
|
should_continue = true;
|
|
|
|
|
nextcol = true;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2017-05-26 19:03:30 +10:00
|
|
|
dl_flag_accum |= dl->flag;
|
2021-01-19 17:24:25 +11:00
|
|
|
dl_rt_accum |= dl->rt;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-12 16:06:17 -06:00
|
|
|
const int triangles_len = BLI_scanfill_calc_ex(&sf_ctx, scanfill_flag, normal_proj);
|
|
|
|
|
if (totvert != 0 && triangles_len != 0) {
|
2021-04-26 15:11:53 -05:00
|
|
|
DispList *dlnew = (DispList *)MEM_callocN(sizeof(DispList), "filldisplist");
|
2021-02-12 16:06:17 -06:00
|
|
|
dlnew->type = DL_INDEX3;
|
|
|
|
|
dlnew->flag = (dl_flag_accum & (DL_BACK_CURVE | DL_FRONT_CURVE));
|
|
|
|
|
dlnew->rt = (dl_rt_accum & CU_SMOOTH);
|
|
|
|
|
dlnew->col = colnr;
|
|
|
|
|
dlnew->nr = totvert;
|
|
|
|
|
dlnew->parts = triangles_len;
|
|
|
|
|
|
2021-04-26 15:11:53 -05:00
|
|
|
dlnew->index = (int *)MEM_mallocN(sizeof(int[3]) * triangles_len, "dlindex");
|
|
|
|
|
dlnew->verts = (float *)MEM_mallocN(sizeof(float[3]) * totvert, "dlverts");
|
2021-02-12 16:06:17 -06:00
|
|
|
|
|
|
|
|
/* vert data */
|
|
|
|
|
int i;
|
|
|
|
|
LISTBASE_FOREACH_INDEX (ScanFillVert *, sf_vert, &sf_ctx.fillvertbase, i) {
|
|
|
|
|
copy_v3_v3(&dlnew->verts[3 * i], sf_vert->co);
|
|
|
|
|
sf_vert->tmp.i = i; /* Index number. */
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-12 16:06:17 -06:00
|
|
|
/* index data */
|
|
|
|
|
int *index = dlnew->index;
|
|
|
|
|
LISTBASE_FOREACH (ScanFillFace *, sf_tri, &sf_ctx.fillfacebase) {
|
|
|
|
|
index[0] = sf_tri->v1->tmp.i;
|
|
|
|
|
index[1] = flip_normal ? sf_tri->v3->tmp.i : sf_tri->v2->tmp.i;
|
|
|
|
|
index[2] = flip_normal ? sf_tri->v2->tmp.i : sf_tri->v3->tmp.i;
|
|
|
|
|
index += 3;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
BLI_addhead(to, dlnew);
|
|
|
|
|
}
|
2013-08-28 02:07:54 +00:00
|
|
|
BLI_scanfill_end_arena(&sf_ctx, sf_arena);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:18:31 +00:00
|
|
|
if (nextcol) {
|
2010-09-22 05:08:52 +00:00
|
|
|
/* stay at current char but fill polys with next material */
|
|
|
|
|
colnr++;
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2010-09-22 05:08:52 +00:00
|
|
|
/* switch to next char and start filling from first material */
|
|
|
|
|
charidx++;
|
2012-05-06 17:22:54 +00:00
|
|
|
colnr = 0;
|
2010-09-22 05:08:52 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-28 02:07:54 +00:00
|
|
|
BLI_memarena_free(sf_arena);
|
2003-04-25 15:48:11 +00:00
|
|
|
/* do not free polys, needed for wireframe display */
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2021-02-12 16:06:17 -06:00
|
|
|
static void bevels_to_filledpoly(const Curve *cu, ListBase *dispbase)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2021-04-26 15:11:53 -05:00
|
|
|
ListBase front = {nullptr, nullptr};
|
|
|
|
|
ListBase back = {nullptr, nullptr};
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-12 16:06:17 -06:00
|
|
|
LISTBASE_FOREACH (const DispList *, dl, dispbase) {
|
2012-05-06 17:22:54 +00:00
|
|
|
if (dl->type == DL_SURF) {
|
2012-05-07 06:58:03 +00:00
|
|
|
if ((dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U) == 0) {
|
2014-03-17 21:48:13 +11:00
|
|
|
if ((cu->flag & CU_BACK) && (dl->flag & DL_BACK_CURVE)) {
|
2021-04-26 15:11:53 -05:00
|
|
|
DispList *dlnew = (DispList *)MEM_callocN(sizeof(DispList), __func__);
|
2002-10-12 11:37:38 +00:00
|
|
|
BLI_addtail(&front, dlnew);
|
2021-04-26 15:11:53 -05:00
|
|
|
dlnew->verts = (float *)MEM_mallocN(sizeof(float[3]) * dl->parts, __func__);
|
2012-05-06 17:22:54 +00:00
|
|
|
dlnew->nr = dl->parts;
|
|
|
|
|
dlnew->parts = 1;
|
|
|
|
|
dlnew->type = DL_POLY;
|
2017-05-26 19:03:30 +10:00
|
|
|
dlnew->flag = DL_BACK_CURVE;
|
2012-05-06 17:22:54 +00:00
|
|
|
dlnew->col = dl->col;
|
2006-02-02 12:13:08 +00:00
|
|
|
dlnew->charidx = dl->charidx;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-12 16:06:17 -06:00
|
|
|
const float *old_verts = dl->verts;
|
|
|
|
|
float *new_verts = dlnew->verts;
|
|
|
|
|
for (int i = 0; i < dl->parts; i++) {
|
|
|
|
|
copy_v3_v3(new_verts, old_verts);
|
|
|
|
|
new_verts += 3;
|
|
|
|
|
old_verts += 3 * dl->nr;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
}
|
2012-05-07 06:58:03 +00:00
|
|
|
if ((cu->flag & CU_FRONT) && (dl->flag & DL_FRONT_CURVE)) {
|
2021-04-26 15:11:53 -05:00
|
|
|
DispList *dlnew = (DispList *)MEM_callocN(sizeof(DispList), __func__);
|
2002-10-12 11:37:38 +00:00
|
|
|
BLI_addtail(&back, dlnew);
|
2021-04-26 15:11:53 -05:00
|
|
|
dlnew->verts = (float *)MEM_mallocN(sizeof(float[3]) * dl->parts, __func__);
|
2012-05-06 17:22:54 +00:00
|
|
|
dlnew->nr = dl->parts;
|
|
|
|
|
dlnew->parts = 1;
|
|
|
|
|
dlnew->type = DL_POLY;
|
2017-05-26 19:03:30 +10:00
|
|
|
dlnew->flag = DL_FRONT_CURVE;
|
2012-05-06 17:22:54 +00:00
|
|
|
dlnew->col = dl->col;
|
|
|
|
|
dlnew->charidx = dl->charidx;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-12 16:06:17 -06:00
|
|
|
const float *old_verts = dl->verts + 3 * (dl->nr - 1);
|
|
|
|
|
float *new_verts = dlnew->verts;
|
|
|
|
|
for (int i = 0; i < dl->parts; i++) {
|
|
|
|
|
copy_v3_v3(new_verts, old_verts);
|
|
|
|
|
new_verts += 3;
|
|
|
|
|
old_verts += 3 * dl->nr;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-02-12 16:06:17 -06:00
|
|
|
const float z_up[3] = {0.0f, 0.0f, -1.0f};
|
2013-04-26 21:04:12 +00:00
|
|
|
BKE_displist_fill(&front, dispbase, z_up, true);
|
|
|
|
|
BKE_displist_fill(&back, dispbase, z_up, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-07 06:58:03 +00:00
|
|
|
BKE_displist_free(&front);
|
|
|
|
|
BKE_displist_free(&back);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-04-26 21:04:12 +00:00
|
|
|
BKE_displist_fill(dispbase, dispbase, z_up, false);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2021-03-31 18:07:15 -05:00
|
|
|
static void curve_to_filledpoly(const Curve *cu, ListBase *dispbase)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!CU_DO_2DFILL(cu)) {
|
2013-12-15 01:49:12 +11:00
|
|
|
return;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-06 17:22:54 +00:00
|
|
|
if (dispbase->first && ((DispList *)dispbase->first)->type == DL_SURF) {
|
2005-08-14 06:08:41 +00:00
|
|
|
bevels_to_filledpoly(cu, dispbase);
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
else {
|
2019-10-15 17:23:23 +11:00
|
|
|
const float z_up[3] = {0.0f, 0.0f, -1.0f};
|
2014-08-07 09:14:54 +10:00
|
|
|
BKE_displist_fill(dispbase, dispbase, z_up, false);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-08-29 09:21:52 +00:00
|
|
|
/* taper rules:
|
2012-03-09 18:28:30 +00:00
|
|
|
* - only 1 curve
|
|
|
|
|
* - first point left, last point right
|
|
|
|
|
* - based on subdivided points in original curve, not on points in taper curve (still)
|
|
|
|
|
*/
|
2021-03-31 18:07:15 -05:00
|
|
|
static float displist_calc_taper(Depsgraph *depsgraph,
|
|
|
|
|
const Scene *scene,
|
|
|
|
|
Object *taperobj,
|
|
|
|
|
float fac)
|
2004-08-29 09:21:52 +00:00
|
|
|
{
|
2021-04-26 15:11:53 -05:00
|
|
|
if (taperobj == nullptr || taperobj->type != OB_CURVE) {
|
2012-05-07 06:58:03 +00:00
|
|
|
return 1.0;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-04-26 15:11:53 -05:00
|
|
|
DispList *dl = taperobj->runtime.curve_cache ?
|
|
|
|
|
(DispList *)taperobj->runtime.curve_cache->disp.first :
|
|
|
|
|
nullptr;
|
|
|
|
|
if (dl == nullptr) {
|
2019-05-21 14:54:08 +02:00
|
|
|
BKE_displist_make_curveTypes(depsgraph, scene, taperobj, false, false);
|
2021-04-26 15:11:53 -05:00
|
|
|
dl = (DispList *)taperobj->runtime.curve_cache->disp.first;
|
2004-08-29 09:21:52 +00:00
|
|
|
}
|
2012-03-24 06:18:31 +00:00
|
|
|
if (dl) {
|
2004-08-29 09:21:52 +00:00
|
|
|
float minx, dx, *fp;
|
|
|
|
|
int a;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2004-08-29 09:21:52 +00:00
|
|
|
/* horizontal size */
|
2012-05-06 17:22:54 +00:00
|
|
|
minx = dl->verts[0];
|
|
|
|
|
dx = dl->verts[3 * (dl->nr - 1)] - minx;
|
2012-03-24 06:18:31 +00:00
|
|
|
if (dx > 0.0f) {
|
2012-05-06 17:22:54 +00:00
|
|
|
fp = dl->verts;
|
|
|
|
|
for (a = 0; a < dl->nr; a++, fp += 3) {
|
2012-05-07 06:58:03 +00:00
|
|
|
if ((fp[0] - minx) / dx >= fac) {
|
2004-08-29 09:21:52 +00:00
|
|
|
/* interpolate with prev */
|
2012-05-06 17:22:54 +00:00
|
|
|
if (a > 0) {
|
|
|
|
|
float fac1 = (fp[-3] - minx) / dx;
|
|
|
|
|
float fac2 = (fp[0] - minx) / dx;
|
2019-04-22 09:39:35 +10:00
|
|
|
if (fac1 != fac2) {
|
2012-05-06 17:22:54 +00:00
|
|
|
return fp[1] * (fac1 - fac) / (fac1 - fac2) + fp[-2] * (fac - fac2) / (fac1 - fac2);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2004-08-29 09:21:52 +00:00
|
|
|
}
|
|
|
|
|
return fp[1];
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-05-06 17:22:54 +00:00
|
|
|
return fp[-2]; // last y coord
|
2004-08-29 09:21:52 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2004-08-29 09:21:52 +00:00
|
|
|
return 1.0;
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-06 12:07:27 +02:00
|
|
|
float BKE_displist_calc_taper(
|
2021-03-31 18:07:15 -05:00
|
|
|
Depsgraph *depsgraph, const Scene *scene, Object *taperobj, int cur, int tot)
|
2012-11-08 08:16:44 +00:00
|
|
|
{
|
2021-06-07 13:08:03 -05:00
|
|
|
const float fac = ((float)cur) / (float)(tot - 1);
|
2012-11-08 08:16:44 +00:00
|
|
|
|
2018-04-06 12:07:27 +02:00
|
|
|
return displist_calc_taper(depsgraph, scene, taperobj, fac);
|
2012-11-08 08:16:44 +00:00
|
|
|
}
|
|
|
|
|
|
2018-04-06 12:07:27 +02:00
|
|
|
void BKE_displist_make_mball(Depsgraph *depsgraph, Scene *scene, Object *ob)
|
2005-07-14 15:48:01 +00:00
|
|
|
{
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!ob || ob->type != OB_MBALL) {
|
2012-05-07 06:58:03 +00:00
|
|
|
return;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2005-07-14 15:48:01 +00:00
|
|
|
|
2014-07-18 17:46:45 +02:00
|
|
|
if (ob == BKE_mball_basis_find(scene, ob)) {
|
2018-07-30 16:54:40 +02:00
|
|
|
if (ob->runtime.curve_cache) {
|
|
|
|
|
BKE_displist_free(&(ob->runtime.curve_cache->disp));
|
2014-07-18 18:08:56 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2021-04-26 15:11:53 -05:00
|
|
|
ob->runtime.curve_cache = (CurveCache *)MEM_callocN(sizeof(CurveCache),
|
|
|
|
|
"CurveCache for MBall");
|
2014-07-18 18:08:56 +02:00
|
|
|
}
|
|
|
|
|
|
2018-07-30 16:54:40 +02:00
|
|
|
BKE_mball_polygonize(depsgraph, scene, ob, &ob->runtime.curve_cache->disp);
|
2014-07-18 17:46:45 +02:00
|
|
|
BKE_mball_texspace_calc(ob);
|
2003-10-14 12:09:57 +00:00
|
|
|
|
2018-07-30 16:54:40 +02:00
|
|
|
object_deform_mball(ob, &ob->runtime.curve_cache->disp);
|
2014-07-18 17:46:45 +02:00
|
|
|
|
2021-06-07 13:29:37 -05:00
|
|
|
/* No-op for MBALLs anyway... */
|
2014-07-18 18:08:56 +02:00
|
|
|
boundbox_displist_object(ob);
|
|
|
|
|
}
|
2005-07-14 15:48:01 +00:00
|
|
|
}
|
2005-08-14 12:17:34 +00:00
|
|
|
|
2018-04-06 12:07:27 +02:00
|
|
|
void BKE_displist_make_mball_forRender(Depsgraph *depsgraph,
|
|
|
|
|
Scene *scene,
|
|
|
|
|
Object *ob,
|
|
|
|
|
ListBase *dispbase)
|
2010-06-28 11:07:02 +00:00
|
|
|
{
|
2018-04-06 12:07:27 +02:00
|
|
|
BKE_mball_polygonize(depsgraph, scene, ob, dispbase);
|
2012-05-07 06:38:41 +00:00
|
|
|
BKE_mball_texspace_calc(ob);
|
2012-05-07 06:58:03 +00:00
|
|
|
|
2010-06-28 11:07:02 +00:00
|
|
|
object_deform_mball(ob, dispbase);
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-31 18:07:15 -05:00
|
|
|
static ModifierData *curve_get_tessellate_point(const Scene *scene,
|
|
|
|
|
const Object *ob,
|
2019-05-13 09:42:32 +02:00
|
|
|
const bool for_render,
|
2014-03-20 22:56:28 +11:00
|
|
|
const bool editmode)
|
2005-08-14 12:17:34 +00:00
|
|
|
{
|
2013-08-19 09:05:34 +00:00
|
|
|
VirtualModifierData virtualModifierData;
|
2020-05-08 10:14:02 +02:00
|
|
|
ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-06-07 13:08:03 -05:00
|
|
|
ModifierMode required_mode = for_render ? eModifierMode_Render : eModifierMode_Realtime;
|
2019-04-22 09:39:35 +10:00
|
|
|
if (editmode) {
|
2021-06-07 13:08:03 -05:00
|
|
|
required_mode = (ModifierMode)((int)required_mode | eModifierMode_Editmode);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-06-07 13:08:03 -05:00
|
|
|
ModifierData *pretessellatePoint = nullptr;
|
2012-05-06 17:22:54 +00:00
|
|
|
for (; md; md = md->next) {
|
2021-04-26 15:11:53 -05:00
|
|
|
const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-05-08 10:14:02 +02:00
|
|
|
if (!BKE_modifier_is_enabled(scene, md, required_mode)) {
|
2012-05-07 06:58:03 +00:00
|
|
|
continue;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
if (mti->type == eModifierTypeType_Constructive) {
|
2012-05-07 06:58:03 +00:00
|
|
|
return pretessellatePoint;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-07-20 01:30:29 +10:00
|
|
|
if (ELEM(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) {
|
2012-03-20 22:56:26 +00:00
|
|
|
pretessellatePoint = md;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-02 16:05:54 +00:00
|
|
|
/* this modifiers are moving point of tessellation automatically
|
2012-03-18 07:38:51 +00:00
|
|
|
* (some of them even can't be applied on tessellated curve), set flag
|
2021-06-07 13:29:37 -05:00
|
|
|
* for information button in modifier's header. */
|
2011-01-14 16:57:53 +00:00
|
|
|
md->mode |= eModifierMode_ApplyOnSpline;
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
2012-05-06 17:22:54 +00:00
|
|
|
else if (md->mode & eModifierMode_ApplyOnSpline) {
|
2012-03-20 22:56:26 +00:00
|
|
|
pretessellatePoint = md;
|
2005-08-14 12:17:34 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-20 22:56:26 +00:00
|
|
|
return pretessellatePoint;
|
2005-08-14 12:17:34 +00:00
|
|
|
}
|
|
|
|
|
|
2021-06-07 13:29:37 -05:00
|
|
|
/**
|
|
|
|
|
* \return True if any modifier was applied.
|
|
|
|
|
*/
|
2021-02-20 18:05:13 +02:00
|
|
|
bool BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph,
|
2021-03-31 18:07:15 -05:00
|
|
|
const Scene *scene,
|
2021-02-20 18:05:13 +02:00
|
|
|
Object *ob,
|
|
|
|
|
ListBase *source_nurb,
|
|
|
|
|
ListBase *target_nurb,
|
|
|
|
|
const bool for_render)
|
2005-08-14 12:17:34 +00:00
|
|
|
{
|
2021-06-07 13:08:03 -05:00
|
|
|
const Curve *cu = (const Curve *)ob->data;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-05-08 10:14:02 +02:00
|
|
|
BKE_modifiers_clear_errors(ob);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-06-07 13:08:03 -05:00
|
|
|
const bool editmode = (!for_render && (cu->editnurb || cu->editfont));
|
|
|
|
|
ModifierMode required_mode = for_render ? eModifierMode_Render : eModifierMode_Realtime;
|
|
|
|
|
if (editmode) {
|
|
|
|
|
required_mode = (ModifierMode)((int)required_mode | eModifierMode_Editmode);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ModifierApplyFlag apply_flag = (ModifierApplyFlag)0;
|
2019-04-22 09:39:35 +10:00
|
|
|
if (editmode) {
|
2021-04-26 15:11:53 -05:00
|
|
|
apply_flag = MOD_APPLY_USECACHE;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-05-13 09:42:32 +02:00
|
|
|
if (for_render) {
|
2021-04-26 15:11:53 -05:00
|
|
|
apply_flag = MOD_APPLY_RENDER;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-06-07 13:08:03 -05:00
|
|
|
float *keyVerts = nullptr;
|
|
|
|
|
float(*deformedVerts)[3] = nullptr;
|
|
|
|
|
int numVerts = 0;
|
Fix T50745: Shape key editing on bezier objects broken with Rendered Viewport Shading
So... Curve+shapekey was even more broken than it looked, this report was
actually a nice crasher (immediate crash in an ASAN build when trying to
edit a curve shapekey with some viewport rendering enabled).
There were actually two different issues here.
I) The less critical: rB6f1493f68fe was not fully fixing issues from
T50614. More specifically, if you updated obdata from editnurb
*without* freeing editnurb afterwards, you had a 'restored' (to
original curve) editnurb, without the edited shapekey modifications
anymore. This was fixed by tweaking again `calc_shapeKeys()` behavior in
`ED_curve_editnurb_load()`.
II) The crasher: in `ED_curve_editnurb_make()`, the call to
`init_editNurb_keyIndex()` was directly storing pointers of obdata
nurbs. Since those get freed every time `ED_curve_editnurb_load()` is
executed, it easily ended up being pointers to freed memory. This was
fixed by copying those data, which implied more complex handling code
for editnurbs->keyindex, and some reshuffling of a few functions to
avoid duplicating things between editor's editcurve.c and BKE's curve.c
Note that the separation of functions between editors and BKE area for
curve could use a serious update, it's currently messy to say the least.
Then again, that area is due to rework since a long time now... :/
Finally, aligned 'for_render' curve evaluation to mesh one - now
editing a shapekey will show in rendered viewports, if it does have some
weight (exactly as with shapekeys of meshes).
2017-02-22 21:20:50 +01:00
|
|
|
if (!editmode) {
|
2021-06-07 13:08:03 -05:00
|
|
|
int numElems = 0;
|
Put the Radius property of Curve points under shape key control.
Since shape keys are stored as raw floating point data, this
unfortunately requires changes to all code that works with it.
An additional complication is that bezier and nurbs control
points have different entry size, and can be mixed in the same
object (and hence shape key buffer).
Shape key entries are changed from:
bezier: float v1[3], v2[3], v3[3], tilt, pad, pad;
nurbs: float vec[3], tilt;
To:
bezier: float v1[3], v2[3], v3[3], tilt, radius, pad;
nurbs: float vec[3], tilt, radius, pad;
The official shape key element size is changed to 3 floats,
with 4 elements for bezier nodes, and 2 for nurbs. This also
means that the element count is not equal to the vertex count
anymore.
While searching for all curve Shape Key code, I also found that
BKE_curve_transform_ex and BKE_curve_translate were broken. This
can be seen by trying to change the Origin of a Curve with keys.
Reviewers: campbellbarton, sergey
Differential Revision: https://developer.blender.org/D3676
2018-09-05 16:17:59 +03:00
|
|
|
keyVerts = BKE_key_evaluate_object(ob, &numElems);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:18:31 +00:00
|
|
|
if (keyVerts) {
|
2021-02-20 18:05:13 +02:00
|
|
|
BLI_assert(BKE_keyblock_curve_element_count(source_nurb) == numElems);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-10-22 09:31:07 +00:00
|
|
|
/* split coords from key data, the latter also includes
|
2012-03-09 18:28:30 +00:00
|
|
|
* tilts, which is passed through in the modifier stack.
|
|
|
|
|
* this is also the reason curves do not use a virtual
|
|
|
|
|
* shape key modifier yet. */
|
2021-02-20 18:05:13 +02:00
|
|
|
deformedVerts = BKE_curve_nurbs_key_vert_coords_alloc(source_nurb, keyVerts, &numVerts);
|
2009-10-22 09:31:07 +00:00
|
|
|
}
|
2005-09-26 15:34:21 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-06-07 13:08:03 -05:00
|
|
|
const ModifierEvalContext mectx = {depsgraph, ob, apply_flag};
|
|
|
|
|
ModifierData *pretessellatePoint = curve_get_tessellate_point(scene, ob, for_render, editmode);
|
|
|
|
|
bool modified = false;
|
|
|
|
|
|
2012-03-20 22:56:26 +00:00
|
|
|
if (pretessellatePoint) {
|
2021-06-07 13:08:03 -05:00
|
|
|
VirtualModifierData virtualModifierData;
|
|
|
|
|
for (ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData); md;
|
|
|
|
|
md = md->next) {
|
2021-04-26 15:11:53 -05:00
|
|
|
const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-05-08 10:14:02 +02:00
|
|
|
if (!BKE_modifier_is_enabled(scene, md, required_mode)) {
|
2012-05-07 06:58:03 +00:00
|
|
|
continue;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
if (mti->type != eModifierTypeType_OnlyDeform) {
|
2012-05-07 06:58:03 +00:00
|
|
|
continue;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2005-08-14 12:17:34 +00:00
|
|
|
if (!deformedVerts) {
|
2021-02-20 18:05:13 +02:00
|
|
|
deformedVerts = BKE_curve_nurbs_vert_coords_alloc(source_nurb, &numVerts);
|
2005-08-14 12:17:34 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-04-26 15:11:53 -05:00
|
|
|
mti->deformVerts(md, &mectx, nullptr, deformedVerts, numVerts);
|
2020-04-30 15:46:45 +02:00
|
|
|
modified = true;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (md == pretessellatePoint) {
|
2005-08-14 12:17:34 +00:00
|
|
|
break;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2005-08-14 12:17:34 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-19 09:36:40 +00:00
|
|
|
if (deformedVerts) {
|
2021-02-20 18:05:13 +02:00
|
|
|
BKE_curve_nurbs_vert_coords_apply(target_nurb, deformedVerts, false);
|
2013-08-19 09:36:40 +00:00
|
|
|
MEM_freeN(deformedVerts);
|
|
|
|
|
}
|
2019-04-22 09:39:35 +10:00
|
|
|
if (keyVerts) { /* these are not passed through modifier stack */
|
2021-02-20 18:05:13 +02:00
|
|
|
BKE_curve_nurbs_key_vert_tilts_apply(target_nurb, keyVerts);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (keyVerts) {
|
2009-10-22 09:31:07 +00:00
|
|
|
MEM_freeN(keyVerts);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2020-04-30 15:46:45 +02:00
|
|
|
return modified;
|
2005-08-14 12:17:34 +00:00
|
|
|
}
|
|
|
|
|
|
2019-08-22 06:28:35 +10:00
|
|
|
static float (*displist_vert_coords_alloc(ListBase *dispbase, int *r_vert_len))[3]
|
2010-05-13 19:23:52 +00:00
|
|
|
{
|
2019-08-22 06:28:35 +10:00
|
|
|
*r_vert_len = 0;
|
2010-05-13 19:23:52 +00:00
|
|
|
|
2020-10-21 23:52:29 -05:00
|
|
|
LISTBASE_FOREACH (DispList *, dl, dispbase) {
|
2019-08-22 06:28:35 +10:00
|
|
|
*r_vert_len += (dl->type == DL_INDEX3) ? dl->nr : dl->parts * dl->nr;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2010-05-13 19:23:52 +00:00
|
|
|
|
2021-06-07 13:08:03 -05:00
|
|
|
float(*allverts)[3] = (float(*)[3])MEM_mallocN(sizeof(float[3]) * (*r_vert_len), __func__);
|
|
|
|
|
float *fp = (float *)allverts;
|
2020-10-21 23:52:29 -05:00
|
|
|
LISTBASE_FOREACH (DispList *, dl, dispbase) {
|
2021-06-07 13:08:03 -05:00
|
|
|
const int ofs = 3 * ((dl->type == DL_INDEX3) ? dl->nr : dl->parts * dl->nr);
|
2021-03-08 14:48:45 +11:00
|
|
|
memcpy(fp, dl->verts, sizeof(float) * ofs);
|
|
|
|
|
fp += ofs;
|
2010-05-13 19:23:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return allverts;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-31 18:07:15 -05:00
|
|
|
static void displist_vert_coords_apply(ListBase *dispbase, const float (*allverts)[3])
|
2010-05-13 19:23:52 +00:00
|
|
|
{
|
2021-06-07 13:08:03 -05:00
|
|
|
const float *fp = (float *)allverts;
|
2020-10-21 23:52:29 -05:00
|
|
|
LISTBASE_FOREACH (DispList *, dl, dispbase) {
|
2021-03-08 14:48:45 +11:00
|
|
|
int ofs = 3 * ((dl->type == DL_INDEX3) ? dl->nr : dl->parts * dl->nr);
|
|
|
|
|
memcpy(dl->verts, fp, sizeof(float) * ofs);
|
|
|
|
|
fp += ofs;
|
2010-05-13 19:23:52 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-16 12:45:11 +10:00
|
|
|
static void curve_calc_modifiers_post(Depsgraph *depsgraph,
|
2021-03-31 18:07:15 -05:00
|
|
|
const Scene *scene,
|
2018-04-06 12:07:27 +02:00
|
|
|
Object *ob,
|
2018-10-15 15:58:58 +11:00
|
|
|
ListBase *dispbase,
|
2020-04-30 15:46:45 +02:00
|
|
|
const bool for_render,
|
2021-06-07 17:04:31 -05:00
|
|
|
const bool force_mesh_conversion,
|
|
|
|
|
Mesh **r_final)
|
2005-08-14 12:17:34 +00:00
|
|
|
{
|
2021-04-26 15:11:53 -05:00
|
|
|
const Curve *cu = (const Curve *)ob->data;
|
2021-06-07 13:08:03 -05:00
|
|
|
|
2014-03-20 22:56:28 +11:00
|
|
|
const bool editmode = (!for_render && (cu->editnurb || cu->editfont));
|
2021-06-07 13:08:03 -05:00
|
|
|
const bool use_cache = !for_render;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-06-07 13:08:03 -05:00
|
|
|
ModifierApplyFlag apply_flag = for_render ? MOD_APPLY_RENDER : (ModifierApplyFlag)0;
|
|
|
|
|
ModifierMode required_mode = for_render ? eModifierMode_Render : eModifierMode_Realtime;
|
|
|
|
|
if (editmode) {
|
|
|
|
|
required_mode = (ModifierMode)((int)required_mode | eModifierMode_Editmode);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-01 17:33:04 +02:00
|
|
|
const ModifierEvalContext mectx_deform = {
|
2021-04-26 15:11:53 -05:00
|
|
|
depsgraph, ob, editmode ? (ModifierApplyFlag)(apply_flag | MOD_APPLY_USECACHE) : apply_flag};
|
2018-05-01 17:33:04 +02:00
|
|
|
const ModifierEvalContext mectx_apply = {
|
2021-06-07 13:08:03 -05:00
|
|
|
depsgraph,
|
|
|
|
|
ob,
|
|
|
|
|
use_cache ? (ModifierApplyFlag)(apply_flag | MOD_APPLY_USECACHE) : apply_flag};
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-06-07 13:08:03 -05:00
|
|
|
ModifierData *pretessellatePoint = curve_get_tessellate_point(scene, ob, for_render, editmode);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-06-07 13:08:03 -05:00
|
|
|
VirtualModifierData virtualModifierData;
|
|
|
|
|
ModifierData *md = pretessellatePoint == nullptr ?
|
|
|
|
|
BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData) :
|
2021-06-07 22:33:05 -05:00
|
|
|
pretessellatePoint->next;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-10-15 15:58:58 +11:00
|
|
|
if (r_final && *r_final) {
|
2021-04-26 15:11:53 -05:00
|
|
|
BKE_id_free(nullptr, *r_final);
|
2010-03-05 16:47:52 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-06-07 13:08:03 -05:00
|
|
|
Mesh *modified = nullptr;
|
|
|
|
|
float(*vertCos)[3] = nullptr;
|
2012-05-06 17:22:54 +00:00
|
|
|
for (; md; md = md->next) {
|
2021-04-26 15:11:53 -05:00
|
|
|
const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-05-08 10:14:02 +02:00
|
|
|
if (!BKE_modifier_is_enabled(scene, md, required_mode)) {
|
2012-05-07 06:58:03 +00:00
|
|
|
continue;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-12-27 15:01:48 +01:00
|
|
|
/* If we need normals, no choice, have to convert to mesh now. */
|
2021-06-07 13:08:03 -05:00
|
|
|
const bool need_normal = mti->dependsOnNormals != nullptr && mti->dependsOnNormals(md);
|
2019-04-24 19:11:28 +02:00
|
|
|
/* 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. */
|
2021-04-26 15:11:53 -05:00
|
|
|
if (modified == nullptr /* && need_normal */) {
|
|
|
|
|
if (vertCos != nullptr) {
|
2019-08-22 06:28:35 +10:00
|
|
|
displist_vert_coords_apply(dispbase, vertCos);
|
2018-12-27 15:01:48 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-12-27 15:01:48 +01:00
|
|
|
if (ELEM(ob->type, OB_CURVE, OB_FONT) && (cu->flag & CU_DEFORM_FILL)) {
|
2021-03-31 18:07:15 -05:00
|
|
|
curve_to_filledpoly(cu, dispbase);
|
2018-12-27 15:01:48 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-12-27 15:01:48 +01:00
|
|
|
modified = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-05-13 19:23:52 +00:00
|
|
|
if (mti->type == eModifierTypeType_OnlyDeform ||
|
2018-06-05 15:59:30 +02:00
|
|
|
(mti->type == eModifierTypeType_DeformOrConstruct && !modified)) {
|
|
|
|
|
if (modified) {
|
2021-06-07 13:08:03 -05:00
|
|
|
int totvert = 0;
|
2010-05-13 19:23:52 +00:00
|
|
|
if (!vertCos) {
|
2019-08-22 06:28:35 +10:00
|
|
|
vertCos = BKE_mesh_vert_coords_alloc(modified, &totvert);
|
2010-03-08 10:05:51 +00:00
|
|
|
}
|
2019-04-24 19:11:28 +02:00
|
|
|
if (need_normal) {
|
2018-12-27 15:01:48 +01:00
|
|
|
BKE_mesh_ensure_normals(modified);
|
|
|
|
|
}
|
2018-09-19 16:59:05 +02:00
|
|
|
mti->deformVerts(md, &mectx_deform, modified, vertCos, totvert);
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2021-06-07 13:08:03 -05:00
|
|
|
int totvert = 0;
|
2010-05-13 19:23:52 +00:00
|
|
|
if (!vertCos) {
|
2019-08-22 06:28:35 +10:00
|
|
|
vertCos = displist_vert_coords_alloc(dispbase, &totvert);
|
2010-03-05 16:47:52 +00:00
|
|
|
}
|
2021-04-26 15:11:53 -05:00
|
|
|
mti->deformVerts(md, &mectx_deform, nullptr, vertCos, totvert);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2008-10-04 12:31:54 +00:00
|
|
|
}
|
2012-03-24 06:18:31 +00:00
|
|
|
else {
|
2018-10-15 15:58:58 +11:00
|
|
|
if (!r_final) {
|
2021-06-07 13:29:37 -05:00
|
|
|
/* makeDisplistCurveTypes could be used for beveling, where mesh
|
2012-05-07 06:58:03 +00:00
|
|
|
* is totally unnecessary, so we could stop modifiers applying
|
2021-06-07 13:29:37 -05:00
|
|
|
* when we found constructive modifier but mesh is unwanted. */
|
2010-03-26 15:06:30 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-06-05 15:59:30 +02:00
|
|
|
if (modified) {
|
2010-05-13 19:23:52 +00:00
|
|
|
if (vertCos) {
|
2020-10-07 14:27:33 +02:00
|
|
|
Mesh *temp_mesh = (Mesh *)BKE_id_copy_ex(
|
2021-04-26 15:11:53 -05:00
|
|
|
nullptr, &modified->id, nullptr, LIB_ID_COPY_LOCALIZE);
|
|
|
|
|
BKE_id_free(nullptr, modified);
|
2018-06-05 15:59:30 +02:00
|
|
|
modified = temp_mesh;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-08-22 06:28:35 +10:00
|
|
|
BKE_mesh_vert_coords_apply(modified, vertCos);
|
2010-03-08 10:05:51 +00:00
|
|
|
}
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2010-05-13 19:23:52 +00:00
|
|
|
if (vertCos) {
|
2019-08-22 06:28:35 +10:00
|
|
|
displist_vert_coords_apply(dispbase, vertCos);
|
2010-05-13 19:23:52 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-03-16 21:09:53 +00:00
|
|
|
if (ELEM(ob->type, OB_CURVE, OB_FONT) && (cu->flag & CU_DEFORM_FILL)) {
|
2021-03-31 18:07:15 -05:00
|
|
|
curve_to_filledpoly(cu, dispbase);
|
2010-03-16 21:09:53 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-06-05 15:59:30 +02:00
|
|
|
modified = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase);
|
2010-03-08 10:05:51 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-05-13 19:23:52 +00:00
|
|
|
if (vertCos) {
|
|
|
|
|
/* Vertex coordinates were applied to necessary data, could free it */
|
|
|
|
|
MEM_freeN(vertCos);
|
2021-04-26 15:11:53 -05:00
|
|
|
vertCos = nullptr;
|
2010-05-13 19:23:52 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-24 19:11:28 +02:00
|
|
|
if (need_normal) {
|
2018-12-27 15:01:48 +01:00
|
|
|
BKE_mesh_ensure_normals(modified);
|
|
|
|
|
}
|
2021-06-07 13:08:03 -05:00
|
|
|
Mesh *mesh_applied = mti->modifyMesh(md, &mectx_apply, modified);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-06-05 15:59:30 +02:00
|
|
|
if (mesh_applied) {
|
2021-06-07 13:29:37 -05:00
|
|
|
if (modified && modified != mesh_applied) {
|
2021-04-26 15:11:53 -05:00
|
|
|
BKE_id_free(nullptr, modified);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2018-06-05 15:59:30 +02:00
|
|
|
modified = mesh_applied;
|
2010-03-08 10:05:51 +00:00
|
|
|
}
|
2005-08-14 12:17:34 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-05-13 19:23:52 +00:00
|
|
|
if (vertCos) {
|
2018-06-05 15:59:30 +02:00
|
|
|
if (modified) {
|
2021-04-26 15:11:53 -05:00
|
|
|
Mesh *temp_mesh = (Mesh *)BKE_id_copy_ex(
|
|
|
|
|
nullptr, &modified->id, nullptr, LIB_ID_COPY_LOCALIZE);
|
|
|
|
|
BKE_id_free(nullptr, modified);
|
2018-06-05 15:59:30 +02:00
|
|
|
modified = temp_mesh;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-08-22 06:28:35 +10:00
|
|
|
BKE_mesh_vert_coords_apply(modified, vertCos);
|
2018-06-05 15:59:30 +02:00
|
|
|
BKE_mesh_calc_normals_mapping_simple(modified);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-05-13 19:23:52 +00:00
|
|
|
MEM_freeN(vertCos);
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2019-08-22 06:28:35 +10:00
|
|
|
displist_vert_coords_apply(dispbase, vertCos);
|
2010-05-13 19:23:52 +00:00
|
|
|
MEM_freeN(vertCos);
|
2021-04-26 15:11:53 -05:00
|
|
|
vertCos = nullptr;
|
2010-05-13 19:23:52 +00:00
|
|
|
}
|
2010-03-08 10:05:51 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-10-15 15:58:58 +11:00
|
|
|
if (r_final) {
|
2020-04-30 15:46:45 +02:00
|
|
|
if (force_mesh_conversion && !modified) {
|
2020-05-21 16:22:37 +10:00
|
|
|
/* XXX 2.8 : This is a workaround for by some deeper technical debts:
|
2020-04-30 15:46:45 +02:00
|
|
|
* - DRW Batch cache is stored inside the ob->data.
|
|
|
|
|
* - Curve data is not COWed for instances that use different modifiers.
|
2020-05-21 16:22:37 +10:00
|
|
|
* This can causes the modifiers to be applied on all user of the same data-block
|
|
|
|
|
* (see T71055)
|
2020-04-30 15:46:45 +02:00
|
|
|
*
|
|
|
|
|
* 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.
|
|
|
|
|
*
|
2020-05-21 16:22:37 +10:00
|
|
|
* 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.
|
2021-01-20 15:15:38 +11:00
|
|
|
*/
|
2020-04-30 15:46:45 +02:00
|
|
|
modified = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase);
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-05 15:59:30 +02:00
|
|
|
if (modified) {
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-06-05 15:59:30 +02:00
|
|
|
/* XXX2.8(Sybren): make sure the face normals are recalculated as well */
|
|
|
|
|
BKE_mesh_ensure_normals(modified);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-01-03 18:01:56 +01:00
|
|
|
/* Special tweaks, needed since neither BKE_mesh_new_nomain_from_template() nor
|
2021-06-07 13:29:37 -05:00
|
|
|
* BKE_mesh_new_nomain_from_curve_displist() properly duplicate mat info... */
|
2019-01-03 18:01:56 +01:00
|
|
|
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;
|
2021-04-26 15:11:53 -05:00
|
|
|
modified->mat = (Material **)MEM_dupallocN(cu->mat);
|
2019-01-03 18:01:56 +01:00
|
|
|
modified->totcol = cu->totcol;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-10-15 15:58:58 +11:00
|
|
|
(*r_final) = modified;
|
2013-06-19 08:19:36 +00:00
|
|
|
}
|
2018-06-05 15:59:30 +02:00
|
|
|
else {
|
2021-04-26 15:11:53 -05:00
|
|
|
(*r_final) = nullptr;
|
2018-06-05 15:59:30 +02:00
|
|
|
}
|
2010-03-26 15:06:30 +00:00
|
|
|
}
|
2021-04-26 15:11:53 -05:00
|
|
|
else if (modified != nullptr) {
|
2019-06-09 21:11:37 +02:00
|
|
|
/* Pretty stupid to generate that whole mesh if it's unused, yet we have to free it. */
|
2021-04-26 15:11:53 -05:00
|
|
|
BKE_id_free(nullptr, modified);
|
2019-06-09 21:11:37 +02:00
|
|
|
}
|
2005-08-14 12:17:34 +00:00
|
|
|
}
|
|
|
|
|
|
2006-11-20 21:25:02 +00:00
|
|
|
static void displist_surf_indices(DispList *dl)
|
|
|
|
|
{
|
2021-06-07 13:08:03 -05:00
|
|
|
int b, p1, p2, p3, p4;
|
2012-05-07 06:58:03 +00:00
|
|
|
|
2012-05-06 17:22:54 +00:00
|
|
|
dl->totindex = 0;
|
2012-05-07 06:58:03 +00:00
|
|
|
|
2021-06-07 13:08:03 -05:00
|
|
|
int *index = dl->index = (int *)MEM_mallocN(sizeof(int[4]) * (dl->parts + 1) * (dl->nr + 1),
|
|
|
|
|
"index array nurbs");
|
2012-05-07 06:58:03 +00:00
|
|
|
|
2021-06-07 13:08:03 -05:00
|
|
|
for (int a = 0; a < dl->parts; a++) {
|
2012-05-07 06:58:03 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (BKE_displist_surfindex_get(dl, a, &b, &p1, &p2, &p3, &p4) == 0) {
|
2008-10-06 06:10:14 +00:00
|
|
|
break;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-05-07 06:58:03 +00:00
|
|
|
|
2012-05-06 17:22:54 +00:00
|
|
|
for (; b < dl->nr; b++, index += 4) {
|
|
|
|
|
index[0] = p1;
|
|
|
|
|
index[1] = p2;
|
|
|
|
|
index[2] = p4;
|
|
|
|
|
index[3] = p3;
|
2012-05-07 06:58:03 +00:00
|
|
|
|
2006-11-20 21:25:02 +00:00
|
|
|
dl->totindex++;
|
2012-05-07 06:58:03 +00:00
|
|
|
|
2012-05-06 17:22:54 +00:00
|
|
|
p2 = p1;
|
|
|
|
|
p1++;
|
|
|
|
|
p4 = p3;
|
|
|
|
|
p3++;
|
2006-11-20 21:25:02 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2006-11-20 21:25:02 +00:00
|
|
|
}
|
|
|
|
|
|
2021-06-07 13:42:41 -05:00
|
|
|
static void displist_make_surf(Depsgraph *depsgraph,
|
|
|
|
|
const Scene *scene,
|
|
|
|
|
Object *ob,
|
|
|
|
|
ListBase *dispbase,
|
|
|
|
|
Mesh **r_final,
|
|
|
|
|
const bool for_render,
|
|
|
|
|
const bool for_orco)
|
2005-07-14 15:48:01 +00:00
|
|
|
{
|
2021-04-26 15:11:53 -05:00
|
|
|
ListBase nubase = {nullptr, nullptr};
|
2021-06-07 13:08:03 -05:00
|
|
|
const Curve *cu = (const Curve *)ob->data;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-03-20 22:56:28 +11:00
|
|
|
if (!for_render && cu->editnurb) {
|
2021-06-07 13:08:03 -05:00
|
|
|
BKE_nurbList_duplicate(&nubase, BKE_curve_editNurbs_get(const_cast<Curve *>(cu)));
|
2013-08-19 09:36:40 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BKE_nurbList_duplicate(&nubase, &cu->nurb);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-06-07 13:08:03 -05:00
|
|
|
bool force_mesh_conversion = false;
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!for_orco) {
|
2021-02-20 18:05:13 +02:00
|
|
|
force_mesh_conversion = BKE_curve_calc_modifiers_pre(
|
|
|
|
|
depsgraph, scene, ob, &nubase, &nubase, for_render);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-21 23:52:29 -05:00
|
|
|
LISTBASE_FOREACH (Nurb *, nu, &nubase) {
|
2020-10-23 23:29:52 -05:00
|
|
|
if (!(for_render || nu->hide == 0) || !BKE_nurb_check_valid_uv(nu)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-06-07 13:08:03 -05:00
|
|
|
const int resolu = (for_render && cu->resolu_ren) ? cu->resolu_ren : nu->resolu;
|
|
|
|
|
const int resolv = (for_render && cu->resolv_ren) ? cu->resolv_ren : nu->resolv;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-23 23:29:52 -05:00
|
|
|
if (nu->pntsv == 1) {
|
2021-06-07 13:08:03 -05:00
|
|
|
const int len = SEGMENTSU(nu) * resolu;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-06-07 13:08:03 -05:00
|
|
|
DispList *dl = (DispList *)MEM_callocN(sizeof(DispList), "makeDispListsurf");
|
2021-04-26 15:11:53 -05:00
|
|
|
dl->verts = (float *)MEM_mallocN(len * sizeof(float[3]), "dlverts");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-23 23:29:52 -05:00
|
|
|
BLI_addtail(dispbase, dl);
|
|
|
|
|
dl->parts = 1;
|
|
|
|
|
dl->nr = len;
|
|
|
|
|
dl->col = nu->mat_nr;
|
|
|
|
|
dl->charidx = nu->charidx;
|
2021-04-01 10:41:12 -03:00
|
|
|
dl->rt = nu->flag;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-06-07 13:08:03 -05:00
|
|
|
float *data = dl->verts;
|
2020-10-23 23:29:52 -05:00
|
|
|
if (nu->flagu & CU_NURB_CYCLIC) {
|
|
|
|
|
dl->type = DL_POLY;
|
2005-08-14 06:08:41 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2020-10-23 23:29:52 -05:00
|
|
|
dl->type = DL_SEGM;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-04-26 15:11:53 -05:00
|
|
|
BKE_nurb_makeCurve(nu, data, nullptr, nullptr, nullptr, resolu, sizeof(float[3]));
|
2020-10-23 23:29:52 -05:00
|
|
|
}
|
|
|
|
|
else {
|
2021-06-07 13:08:03 -05:00
|
|
|
const int len = (nu->pntsu * resolu) * (nu->pntsv * resolv);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-06-07 13:08:03 -05:00
|
|
|
DispList *dl = (DispList *)MEM_callocN(sizeof(DispList), "makeDispListsurf");
|
2021-04-26 15:11:53 -05:00
|
|
|
dl->verts = (float *)MEM_mallocN(len * sizeof(float[3]), "dlverts");
|
2020-10-23 23:29:52 -05:00
|
|
|
BLI_addtail(dispbase, dl);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-23 23:29:52 -05:00
|
|
|
dl->col = nu->mat_nr;
|
|
|
|
|
dl->charidx = nu->charidx;
|
2021-04-01 10:41:12 -03:00
|
|
|
dl->rt = nu->flag;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-06-07 13:08:03 -05:00
|
|
|
float *data = dl->verts;
|
2020-10-23 23:29:52 -05:00
|
|
|
dl->type = DL_SURF;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-23 23:29:52 -05:00
|
|
|
dl->parts = (nu->pntsu * resolu); /* in reverse, because makeNurbfaces works that way */
|
|
|
|
|
dl->nr = (nu->pntsv * resolv);
|
|
|
|
|
if (nu->flagv & CU_NURB_CYCLIC) {
|
|
|
|
|
dl->flag |= DL_CYCL_U; /* reverse too! */
|
|
|
|
|
}
|
|
|
|
|
if (nu->flagu & CU_NURB_CYCLIC) {
|
|
|
|
|
dl->flag |= DL_CYCL_V;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2020-10-23 23:29:52 -05:00
|
|
|
|
|
|
|
|
BKE_nurb_makeFaces(nu, data, 0, resolu, resolv);
|
|
|
|
|
|
|
|
|
|
/* gl array drawing: using indices */
|
|
|
|
|
displist_surf_indices(dl);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2005-08-14 06:08:41 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-03-20 22:56:28 +11:00
|
|
|
if (!for_orco) {
|
2018-07-30 16:54:40 +02:00
|
|
|
BKE_nurbList_duplicate(&ob->runtime.curve_cache->deformed_nurbs, &nubase);
|
2020-04-30 15:46:45 +02:00
|
|
|
curve_calc_modifiers_post(
|
2021-06-07 17:04:31 -05:00
|
|
|
depsgraph, scene, ob, dispbase, for_render, force_mesh_conversion, r_final);
|
2012-05-07 06:58:03 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-19 09:36:40 +00:00
|
|
|
BKE_nurbList_free(&nubase);
|
2005-08-14 06:08:41 +00:00
|
|
|
}
|
2005-10-03 14:13:47 +00:00
|
|
|
|
2020-11-22 12:11:15 -05:00
|
|
|
static void rotateBevelPiece(const Curve *cu,
|
|
|
|
|
const BevPoint *bevp,
|
|
|
|
|
const BevPoint *nbevp,
|
|
|
|
|
const DispList *dlb,
|
|
|
|
|
const float bev_blend,
|
|
|
|
|
const float widfac,
|
|
|
|
|
const float radius_factor,
|
2014-03-16 03:24:05 +11:00
|
|
|
float **r_data)
|
2012-02-02 15:15:52 +00:00
|
|
|
{
|
2020-11-22 12:11:15 -05:00
|
|
|
float *data = *r_data;
|
|
|
|
|
const float *fp = dlb->verts;
|
|
|
|
|
for (int b = 0; b < dlb->nr; b++, fp += 3, data += 3) {
|
2012-03-24 06:18:31 +00:00
|
|
|
if (cu->flag & CU_3D) {
|
2012-11-08 08:16:44 +00:00
|
|
|
float vec[3], quat[4];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-06 17:22:54 +00:00
|
|
|
vec[0] = fp[1] + widfac;
|
2012-02-02 15:15:52 +00:00
|
|
|
vec[1] = fp[2];
|
2012-05-06 17:22:54 +00:00
|
|
|
vec[2] = 0.0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-04-26 15:11:53 -05:00
|
|
|
if (nbevp == nullptr) {
|
2012-11-08 08:16:44 +00:00
|
|
|
copy_v3_v3(data, bevp->vec);
|
|
|
|
|
copy_qt_qt(quat, bevp->quat);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
interp_v3_v3v3(data, bevp->vec, nbevp->vec, bev_blend);
|
|
|
|
|
interp_qt_qtqt(quat, bevp->quat, nbevp->quat, bev_blend);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-11-08 08:16:44 +00:00
|
|
|
mul_qt_v3(quat, vec);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-22 12:11:15 -05:00
|
|
|
data[0] += radius_factor * vec[0];
|
|
|
|
|
data[1] += radius_factor * vec[1];
|
|
|
|
|
data[2] += radius_factor * vec[2];
|
2012-02-02 15:15:52 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-11-08 08:16:44 +00:00
|
|
|
float sina, cosa;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-04-26 15:11:53 -05:00
|
|
|
if (nbevp == nullptr) {
|
2012-11-08 08:16:44 +00:00
|
|
|
copy_v3_v3(data, bevp->vec);
|
|
|
|
|
sina = bevp->sina;
|
|
|
|
|
cosa = bevp->cosa;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
interp_v3_v3v3(data, bevp->vec, nbevp->vec, bev_blend);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-11-08 08:16:44 +00:00
|
|
|
/* perhaps we need to interpolate angles instead. but the thing is
|
|
|
|
|
* cosa and sina are not actually sine and cosine
|
|
|
|
|
*/
|
|
|
|
|
sina = nbevp->sina * bev_blend + bevp->sina * (1.0f - bev_blend);
|
|
|
|
|
cosa = nbevp->cosa * bev_blend + bevp->cosa * (1.0f - bev_blend);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-22 12:11:15 -05:00
|
|
|
data[0] += radius_factor * (widfac + fp[1]) * sina;
|
|
|
|
|
data[1] += radius_factor * (widfac + fp[1]) * cosa;
|
|
|
|
|
data[2] += radius_factor * fp[2];
|
2012-02-02 15:15:52 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-03-16 03:24:05 +11:00
|
|
|
*r_data = data;
|
2012-02-02 15:15:52 +00:00
|
|
|
}
|
|
|
|
|
|
2021-03-31 18:07:15 -05:00
|
|
|
static void fillBevelCap(const Nurb *nu,
|
|
|
|
|
const DispList *dlb,
|
|
|
|
|
const float *prev_fp,
|
|
|
|
|
ListBase *dispbase)
|
2012-02-02 15:15:52 +00:00
|
|
|
{
|
2021-06-07 13:08:03 -05:00
|
|
|
DispList *dl = (DispList *)MEM_callocN(sizeof(DispList), "makeDispListbev2");
|
2021-04-26 15:11:53 -05:00
|
|
|
dl->verts = (float *)MEM_mallocN(sizeof(float[3]) * dlb->nr, "dlverts");
|
2020-08-08 13:29:21 +10:00
|
|
|
memcpy(dl->verts, prev_fp, sizeof(float[3]) * dlb->nr);
|
2012-02-02 15:15:52 +00:00
|
|
|
|
2012-05-06 17:22:54 +00:00
|
|
|
dl->type = DL_POLY;
|
2012-02-02 15:15:52 +00:00
|
|
|
|
2012-05-06 17:22:54 +00:00
|
|
|
dl->parts = 1;
|
|
|
|
|
dl->nr = dlb->nr;
|
|
|
|
|
dl->col = nu->mat_nr;
|
|
|
|
|
dl->charidx = nu->charidx;
|
2021-04-01 10:41:12 -03:00
|
|
|
dl->rt = nu->flag;
|
2012-02-02 15:15:52 +00:00
|
|
|
|
2012-02-02 18:50:44 +00:00
|
|
|
BLI_addtail(dispbase, dl);
|
2012-02-02 15:15:52 +00:00
|
|
|
}
|
|
|
|
|
|
2014-08-18 17:35:51 +06:00
|
|
|
static void calc_bevfac_segment_mapping(
|
2021-03-31 18:07:15 -05:00
|
|
|
const BevList *bl, float bevfac, float spline_length, int *r_bev, float *r_blend)
|
2014-08-18 17:35:51 +06:00
|
|
|
{
|
2021-06-07 13:08:03 -05:00
|
|
|
float normsum = 0.0f;
|
2014-08-18 17:35:51 +06:00
|
|
|
float *seglen = bl->seglen;
|
|
|
|
|
int *segbevcount = bl->segbevcount;
|
|
|
|
|
int bevcount = 0, nr = bl->nr;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-08-18 17:35:51 +06:00
|
|
|
float bev_fl = bevfac * (bl->nr - 1);
|
|
|
|
|
*r_bev = (int)bev_fl;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-08-18 17:35:51 +06:00
|
|
|
while (bevcount < nr - 1) {
|
2021-06-07 13:08:03 -05:00
|
|
|
float normlen = *seglen / spline_length;
|
2014-08-20 08:47:32 +10:00
|
|
|
if (normsum + normlen > bevfac) {
|
2014-08-18 17:35:51 +06:00
|
|
|
bev_fl = bevcount + (bevfac - normsum) / normlen * *segbevcount;
|
|
|
|
|
*r_bev = (int)bev_fl;
|
|
|
|
|
*r_blend = bev_fl - *r_bev;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
normsum += normlen;
|
|
|
|
|
bevcount += *segbevcount;
|
|
|
|
|
segbevcount++;
|
|
|
|
|
seglen++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-03-28 16:41:56 +06:00
|
|
|
|
2014-08-18 17:35:51 +06:00
|
|
|
static void calc_bevfac_spline_mapping(
|
2021-03-31 18:07:15 -05:00
|
|
|
const BevList *bl, float bevfac, float spline_length, int *r_bev, float *r_blend)
|
2014-03-28 16:41:56 +06:00
|
|
|
{
|
2014-05-26 21:57:53 +10:00
|
|
|
const float len_target = bevfac * spline_length;
|
2014-08-18 17:35:51 +06:00
|
|
|
BevPoint *bevp = bl->bevpoints;
|
|
|
|
|
float len_next = 0.0f, len = 0.0f;
|
|
|
|
|
int i = 0, nr = bl->nr;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-08-18 17:35:51 +06:00
|
|
|
while (nr--) {
|
|
|
|
|
bevp++;
|
|
|
|
|
len_next = len + bevp->offset;
|
2014-05-26 21:57:53 +10:00
|
|
|
if (len_next > len_target) {
|
2014-03-28 16:41:56 +06:00
|
|
|
break;
|
|
|
|
|
}
|
2014-05-26 21:57:53 +10:00
|
|
|
len = len_next;
|
2014-08-18 17:35:51 +06:00
|
|
|
i++;
|
2014-03-28 16:41:56 +06:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-05-26 21:57:53 +10:00
|
|
|
*r_bev = i;
|
2014-08-18 17:35:51 +06:00
|
|
|
*r_blend = (len_target - len) / bevp->offset;
|
2014-03-28 16:41:56 +06:00
|
|
|
}
|
|
|
|
|
|
2014-08-18 17:35:51 +06:00
|
|
|
static void calc_bevfac_mapping_default(
|
2021-03-31 18:07:15 -05:00
|
|
|
const BevList *bl, int *r_start, float *r_firstblend, int *r_steps, float *r_lastblend)
|
2014-05-26 21:50:17 +10:00
|
|
|
{
|
|
|
|
|
*r_start = 0;
|
|
|
|
|
*r_steps = bl->nr;
|
|
|
|
|
*r_firstblend = 1.0f;
|
|
|
|
|
*r_lastblend = 1.0f;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-31 18:07:15 -05:00
|
|
|
static void calc_bevfac_mapping(const Curve *cu,
|
|
|
|
|
const BevList *bl,
|
|
|
|
|
const Nurb *nu,
|
2014-05-26 23:55:34 +10:00
|
|
|
int *r_start,
|
|
|
|
|
float *r_firstblend,
|
|
|
|
|
int *r_steps,
|
|
|
|
|
float *r_lastblend)
|
2014-03-28 16:41:56 +06:00
|
|
|
{
|
2014-08-18 17:35:51 +06:00
|
|
|
float tmpf, total_length = 0.0f;
|
|
|
|
|
int end = 0, i;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-05-26 21:50:17 +10:00
|
|
|
if ((BKE_nurb_check_valid_u(nu) == false) ||
|
|
|
|
|
/* not essential, but skips unnecessary calculation */
|
|
|
|
|
(min_ff(cu->bevfac1, cu->bevfac2) == 0.0f && max_ff(cu->bevfac1, cu->bevfac2) == 1.0f)) {
|
|
|
|
|
calc_bevfac_mapping_default(bl, r_start, r_firstblend, r_steps, r_lastblend);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-03-30 10:22:12 +02:00
|
|
|
if (ELEM(cu->bevfac1_mapping, CU_BEVFAC_MAP_SEGMENT, CU_BEVFAC_MAP_SPLINE) ||
|
|
|
|
|
ELEM(cu->bevfac2_mapping, CU_BEVFAC_MAP_SEGMENT, CU_BEVFAC_MAP_SPLINE)) {
|
2014-08-18 17:35:51 +06:00
|
|
|
for (i = 0; i < SEGMENTSU(nu); i++) {
|
|
|
|
|
total_length += bl->seglen[i];
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2014-03-28 16:41:56 +06:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-03-28 16:41:56 +06:00
|
|
|
switch (cu->bevfac1_mapping) {
|
|
|
|
|
case CU_BEVFAC_MAP_RESOLU: {
|
|
|
|
|
const float start_fl = cu->bevfac1 * (bl->nr - 1);
|
|
|
|
|
*r_start = (int)start_fl;
|
|
|
|
|
*r_firstblend = 1.0f - (start_fl - (*r_start));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case CU_BEVFAC_MAP_SEGMENT: {
|
2014-08-18 17:35:51 +06:00
|
|
|
calc_bevfac_segment_mapping(bl, cu->bevfac1, total_length, r_start, r_firstblend);
|
|
|
|
|
*r_firstblend = 1.0f - *r_firstblend;
|
2014-03-28 16:41:56 +06:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case CU_BEVFAC_MAP_SPLINE: {
|
2014-08-18 17:35:51 +06:00
|
|
|
calc_bevfac_spline_mapping(bl, cu->bevfac1, total_length, r_start, r_firstblend);
|
2014-03-28 16:41:56 +06:00
|
|
|
*r_firstblend = 1.0f - *r_firstblend;
|
|
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2014-03-28 16:41:56 +06:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-03-28 16:41:56 +06:00
|
|
|
switch (cu->bevfac2_mapping) {
|
|
|
|
|
case CU_BEVFAC_MAP_RESOLU: {
|
|
|
|
|
const float end_fl = cu->bevfac2 * (bl->nr - 1);
|
|
|
|
|
end = (int)end_fl;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-03-28 16:41:56 +06:00
|
|
|
*r_steps = 2 + end - *r_start;
|
|
|
|
|
*r_lastblend = end_fl - end;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case CU_BEVFAC_MAP_SEGMENT: {
|
2014-08-18 17:35:51 +06:00
|
|
|
calc_bevfac_segment_mapping(bl, cu->bevfac2, total_length, &end, r_lastblend);
|
2014-03-28 16:41:56 +06:00
|
|
|
*r_steps = end - *r_start + 2;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case CU_BEVFAC_MAP_SPLINE: {
|
2014-08-18 17:35:51 +06:00
|
|
|
calc_bevfac_spline_mapping(bl, cu->bevfac2, total_length, &end, r_lastblend);
|
2014-03-28 16:41:56 +06:00
|
|
|
*r_steps = end - *r_start + 2;
|
|
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2014-03-28 16:41:56 +06:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-05-26 23:55:34 +10:00
|
|
|
if (end < *r_start || (end == *r_start && *r_lastblend < 1.0f - *r_firstblend)) {
|
2014-03-28 16:41:56 +06:00
|
|
|
SWAP(int, *r_start, end);
|
|
|
|
|
tmpf = *r_lastblend;
|
|
|
|
|
*r_lastblend = 1.0f - *r_firstblend;
|
|
|
|
|
*r_firstblend = 1.0f - tmpf;
|
|
|
|
|
*r_steps = end - *r_start + 2;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-03-28 16:41:56 +06:00
|
|
|
if (*r_start + *r_steps > bl->nr) {
|
|
|
|
|
*r_steps = bl->nr - *r_start;
|
|
|
|
|
*r_lastblend = 1.0f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-16 12:45:11 +10:00
|
|
|
static void do_makeDispListCurveTypes(Depsgraph *depsgraph,
|
2021-03-31 18:07:15 -05:00
|
|
|
const Scene *scene,
|
2018-04-06 12:07:27 +02:00
|
|
|
Object *ob,
|
|
|
|
|
ListBase *dispbase,
|
2019-02-14 17:21:55 +11:00
|
|
|
const bool for_render,
|
|
|
|
|
const bool for_orco,
|
|
|
|
|
Mesh **r_final)
|
2005-08-14 06:08:41 +00:00
|
|
|
{
|
2021-06-07 13:58:47 -05:00
|
|
|
const Curve *cu = (const Curve *)ob->data;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2005-12-07 19:47:22 +00:00
|
|
|
/* we do allow duplis... this is only displist on curve level */
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!ELEM(ob->type, OB_SURF, OB_CURVE, OB_FONT)) {
|
2014-07-20 01:30:29 +10:00
|
|
|
return;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-06 17:22:54 +00:00
|
|
|
if (ob->type == OB_SURF) {
|
2021-06-07 13:42:41 -05:00
|
|
|
displist_make_surf(depsgraph, scene, ob, dispbase, r_final, for_render, for_orco);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2009-01-02 19:10:35 +00:00
|
|
|
else if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
|
2021-04-26 15:11:53 -05:00
|
|
|
ListBase nubase = {nullptr, nullptr};
|
2020-04-30 15:46:45 +02:00
|
|
|
bool force_mesh_conversion = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-30 16:54:40 +02:00
|
|
|
BKE_curve_bevelList_free(&ob->runtime.curve_cache->bev);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-10-07 15:02:06 +11:00
|
|
|
/* We only re-evaluate path if evaluation is not happening for orco.
|
2014-02-25 13:15:59 +06:00
|
|
|
* If the calculation happens for orco, we should never free data which
|
2021-06-07 13:29:37 -05:00
|
|
|
* was needed before and only not needed for orco calculation. */
|
2014-03-20 22:56:28 +11:00
|
|
|
if (!for_orco) {
|
2021-04-08 15:51:08 +02:00
|
|
|
if (ob->runtime.curve_cache->anim_path_accum_length) {
|
2021-04-09 14:55:31 +10:00
|
|
|
MEM_freeN((void *)ob->runtime.curve_cache->anim_path_accum_length);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2021-04-26 15:11:53 -05:00
|
|
|
ob->runtime.curve_cache->anim_path_accum_length = nullptr;
|
2014-02-25 13:15:59 +06:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-05 17:04:52 +06:00
|
|
|
if (ob->type == OB_FONT) {
|
2018-06-12 15:03:51 +02:00
|
|
|
BKE_vfont_to_curve_nubase(ob, FO_EDIT, &nubase);
|
2014-01-05 17:04:52 +06:00
|
|
|
}
|
|
|
|
|
else {
|
2021-06-07 13:58:47 -05:00
|
|
|
BKE_nurbList_duplicate(&nubase, BKE_curve_nurbs_get(const_cast<Curve *>(cu)));
|
2014-01-05 17:04:52 +06:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!for_orco) {
|
2021-02-20 18:05:13 +02:00
|
|
|
force_mesh_conversion = BKE_curve_calc_modifiers_pre(
|
|
|
|
|
depsgraph, scene, ob, &nubase, &nubase, for_render);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-13 09:42:32 +02:00
|
|
|
BKE_curve_bevelList_make(ob, &nubase, for_render);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2006-08-13 07:37:51 +00:00
|
|
|
/* If curve has no bevel will return nothing */
|
2021-06-07 13:58:47 -05:00
|
|
|
ListBase dlbev = BKE_curve_bevel_make(cu);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2006-06-06 10:09:44 +00:00
|
|
|
/* no bevel or extrude, and no width correction? */
|
2021-06-07 13:58:47 -05:00
|
|
|
if (BLI_listbase_is_empty(&dlbev) && cu->width == 1.0f) {
|
2021-02-12 16:06:17 -06:00
|
|
|
curve_to_displist(cu, &nubase, for_render, dispbase);
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2020-11-22 12:11:15 -05:00
|
|
|
const float widfac = cu->width - 1.0f;
|
2021-06-07 13:58:47 -05:00
|
|
|
|
2021-04-26 15:11:53 -05:00
|
|
|
BevList *bl = (BevList *)ob->runtime.curve_cache->bev.first;
|
|
|
|
|
Nurb *nu = (Nurb *)nubase.first;
|
2012-05-06 17:22:54 +00:00
|
|
|
for (; bl && nu; bl = bl->next, nu = nu->next) {
|
2012-02-02 15:15:52 +00:00
|
|
|
float *data;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-22 11:25:10 -05:00
|
|
|
if (bl->nr == 0) { /* blank bevel lists can happen */
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-22 11:25:10 -05:00
|
|
|
/* exception handling; curve without bevel or extrude, with width correction */
|
|
|
|
|
if (BLI_listbase_is_empty(&dlbev)) {
|
2021-04-26 15:11:53 -05:00
|
|
|
DispList *dl = (DispList *)MEM_callocN(sizeof(DispList), "makeDispListbev");
|
|
|
|
|
dl->verts = (float *)MEM_mallocN(sizeof(float[3]) * bl->nr, "dlverts");
|
2020-11-22 11:25:10 -05:00
|
|
|
BLI_addtail(dispbase, dl);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-22 11:25:10 -05:00
|
|
|
if (bl->poly != -1) {
|
|
|
|
|
dl->type = DL_POLY;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
dl->type = DL_SEGM;
|
|
|
|
|
dl->flag = (DL_FRONT_CURVE | DL_BACK_CURVE);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-22 11:25:10 -05:00
|
|
|
dl->parts = 1;
|
|
|
|
|
dl->nr = bl->nr;
|
|
|
|
|
dl->col = nu->mat_nr;
|
|
|
|
|
dl->charidx = nu->charidx;
|
2021-04-01 10:41:12 -03:00
|
|
|
dl->rt = nu->flag;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-22 11:47:37 -05:00
|
|
|
int a = dl->nr;
|
|
|
|
|
BevPoint *bevp = bl->bevpoints;
|
2020-11-22 11:25:10 -05:00
|
|
|
data = dl->verts;
|
|
|
|
|
while (a--) {
|
|
|
|
|
data[0] = bevp->vec[0] + widfac * bevp->sina;
|
|
|
|
|
data[1] = bevp->vec[1] + widfac * bevp->cosa;
|
|
|
|
|
data[2] = bevp->vec[2];
|
|
|
|
|
bevp++;
|
|
|
|
|
data += 3;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
2021-04-26 15:11:53 -05:00
|
|
|
ListBase bottom_capbase = {nullptr, nullptr};
|
|
|
|
|
ListBase top_capbase = {nullptr, nullptr};
|
2020-11-22 11:25:10 -05:00
|
|
|
float bottom_no[3] = {0.0f};
|
|
|
|
|
float top_no[3] = {0.0f};
|
2020-11-22 11:47:37 -05:00
|
|
|
float first_blend = 0.0f, last_blend = 0.0f;
|
|
|
|
|
int start, steps = 0;
|
2020-11-22 11:25:10 -05:00
|
|
|
|
|
|
|
|
if (nu->flagu & CU_NURB_CYCLIC) {
|
2020-11-22 11:47:37 -05:00
|
|
|
calc_bevfac_mapping_default(bl, &start, &first_blend, &steps, &last_blend);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2007-12-03 22:42:48 +00:00
|
|
|
else {
|
2020-11-22 11:25:10 -05:00
|
|
|
if (fabsf(cu->bevfac2 - cu->bevfac1) < FLT_EPSILON) {
|
|
|
|
|
continue;
|
2014-05-26 21:50:17 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-22 11:47:37 -05:00
|
|
|
calc_bevfac_mapping(cu, bl, nu, &start, &first_blend, &steps, &last_blend);
|
2020-11-22 11:25:10 -05:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-22 11:47:37 -05:00
|
|
|
LISTBASE_FOREACH (DispList *, dlb, &dlbev) {
|
2020-11-22 11:25:10 -05:00
|
|
|
/* for each part of the bevel use a separate displblock */
|
2021-04-26 15:11:53 -05:00
|
|
|
DispList *dl = (DispList *)MEM_callocN(sizeof(DispList), "makeDispListbev1");
|
|
|
|
|
dl->verts = data = (float *)MEM_mallocN(sizeof(float[3]) * dlb->nr * steps, "dlverts");
|
2020-11-22 11:25:10 -05:00
|
|
|
BLI_addtail(dispbase, dl);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-22 11:25:10 -05:00
|
|
|
dl->type = DL_SURF;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-22 11:25:10 -05:00
|
|
|
dl->flag = dlb->flag & (DL_FRONT_CURVE | DL_BACK_CURVE);
|
|
|
|
|
if (dlb->type == DL_POLY) {
|
|
|
|
|
dl->flag |= DL_CYCL_U;
|
|
|
|
|
}
|
|
|
|
|
if ((bl->poly >= 0) && (steps > 2)) {
|
|
|
|
|
dl->flag |= DL_CYCL_V;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dl->parts = steps;
|
|
|
|
|
dl->nr = dlb->nr;
|
|
|
|
|
dl->col = nu->mat_nr;
|
|
|
|
|
dl->charidx = nu->charidx;
|
2021-04-01 10:41:12 -03:00
|
|
|
dl->rt = nu->flag;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-22 11:25:10 -05:00
|
|
|
/* for each point of poly make a bevel piece */
|
2020-11-22 11:47:37 -05:00
|
|
|
BevPoint *bevp_first = bl->bevpoints;
|
|
|
|
|
BevPoint *bevp_last = &bl->bevpoints[bl->nr - 1];
|
|
|
|
|
BevPoint *bevp = &bl->bevpoints[start];
|
|
|
|
|
for (int i = start, a = 0; a < steps; i++, bevp++, a++) {
|
|
|
|
|
float radius_factor = 1.0;
|
2020-11-22 11:25:10 -05:00
|
|
|
float *cur_data = data;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-04-26 15:11:53 -05:00
|
|
|
if (cu->taperobj == nullptr) {
|
2020-11-22 11:47:37 -05:00
|
|
|
radius_factor = bevp->radius;
|
2020-11-22 11:25:10 -05:00
|
|
|
}
|
|
|
|
|
else {
|
2020-11-22 11:47:37 -05:00
|
|
|
float taper_factor;
|
2020-11-22 11:25:10 -05:00
|
|
|
if (cu->flag & CU_MAP_TAPER) {
|
2020-11-22 11:47:37 -05:00
|
|
|
float len = (steps - 3) + first_blend + last_blend;
|
2020-11-22 11:25:10 -05:00
|
|
|
|
|
|
|
|
if (a == 0) {
|
2020-11-22 11:47:37 -05:00
|
|
|
taper_factor = 0.0f;
|
2020-11-22 11:25:10 -05:00
|
|
|
}
|
|
|
|
|
else if (a == steps - 1) {
|
2020-11-22 11:47:37 -05:00
|
|
|
taper_factor = 1.0f;
|
2012-11-08 08:16:44 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2020-11-22 11:47:37 -05:00
|
|
|
taper_factor = ((float)a - (1.0f - first_blend)) / len;
|
2012-11-08 08:16:44 +00:00
|
|
|
}
|
2014-05-26 21:39:46 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2020-11-22 11:47:37 -05:00
|
|
|
float len = bl->nr - 1;
|
|
|
|
|
taper_factor = (float)i / len;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-22 11:25:10 -05:00
|
|
|
if (a == 0) {
|
2020-11-22 11:47:37 -05:00
|
|
|
taper_factor += (1.0f - first_blend) / len;
|
2013-04-26 21:04:12 +00:00
|
|
|
}
|
2020-11-22 11:25:10 -05:00
|
|
|
else if (a == steps - 1) {
|
2020-11-22 11:47:37 -05:00
|
|
|
taper_factor -= (1.0f - last_blend) / len;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2020-11-22 11:25:10 -05:00
|
|
|
|
2020-11-22 11:47:37 -05:00
|
|
|
radius_factor = displist_calc_taper(depsgraph, scene, cu->taperobj, taper_factor);
|
2021-03-23 18:26:13 +11:00
|
|
|
|
|
|
|
|
if (cu->taper_radius_mode == CU_TAPER_RADIUS_MULTIPLY) {
|
|
|
|
|
radius_factor *= bevp->radius;
|
|
|
|
|
}
|
|
|
|
|
else if (cu->taper_radius_mode == CU_TAPER_RADIUS_ADD) {
|
|
|
|
|
radius_factor += bevp->radius;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2020-11-22 11:25:10 -05:00
|
|
|
/* rotate bevel piece and write in data */
|
|
|
|
|
if ((a == 0) && (bevp != bevp_last)) {
|
2020-11-22 11:47:37 -05:00
|
|
|
rotateBevelPiece(
|
|
|
|
|
cu, bevp, bevp + 1, dlb, 1.0f - first_blend, widfac, radius_factor, &data);
|
2020-11-22 11:25:10 -05:00
|
|
|
}
|
|
|
|
|
else if ((a == steps - 1) && (bevp != bevp_first)) {
|
2020-11-22 11:47:37 -05:00
|
|
|
rotateBevelPiece(
|
|
|
|
|
cu, bevp, bevp - 1, dlb, 1.0f - last_blend, widfac, radius_factor, &data);
|
2020-11-22 11:25:10 -05:00
|
|
|
}
|
|
|
|
|
else {
|
2021-04-26 15:11:53 -05:00
|
|
|
rotateBevelPiece(cu, bevp, nullptr, dlb, 0.0f, widfac, radius_factor, &data);
|
2020-11-22 11:25:10 -05:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-22 11:25:10 -05:00
|
|
|
if ((cu->flag & CU_FILL_CAPS) && !(nu->flagu & CU_NURB_CYCLIC)) {
|
|
|
|
|
if (a == 1) {
|
|
|
|
|
fillBevelCap(nu, dlb, cur_data - 3 * dlb->nr, &bottom_capbase);
|
|
|
|
|
copy_v3_v3(bottom_no, bevp->dir);
|
|
|
|
|
}
|
|
|
|
|
if (a == steps - 1) {
|
|
|
|
|
fillBevelCap(nu, dlb, cur_data, &top_capbase);
|
|
|
|
|
negate_v3_v3(top_no, bevp->dir);
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2020-11-22 11:25:10 -05:00
|
|
|
|
|
|
|
|
/* gl array drawing: using indices */
|
|
|
|
|
displist_surf_indices(dl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bottom_capbase.first) {
|
|
|
|
|
BKE_displist_fill(&bottom_capbase, dispbase, bottom_no, false);
|
|
|
|
|
BKE_displist_fill(&top_capbase, dispbase, top_no, false);
|
|
|
|
|
BKE_displist_free(&bottom_capbase);
|
|
|
|
|
BKE_displist_free(&top_capbase);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2006-06-06 10:09:44 +00:00
|
|
|
}
|
2012-05-07 06:58:03 +00:00
|
|
|
BKE_displist_free(&dlbev);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-03-16 21:09:53 +00:00
|
|
|
if (!(cu->flag & CU_DEFORM_FILL)) {
|
2021-03-31 18:07:15 -05:00
|
|
|
curve_to_filledpoly(cu, dispbase);
|
2010-03-16 21:09:53 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-03-20 22:56:28 +11:00
|
|
|
if (!for_orco) {
|
2014-01-10 01:45:53 +06:00
|
|
|
if ((cu->flag & CU_PATH) ||
|
2018-04-06 12:07:27 +02:00
|
|
|
DEG_get_eval_flags_for_id(depsgraph, &ob->id) & DAG_EVAL_NEED_CURVE_PATH) {
|
2021-04-08 15:51:08 +02:00
|
|
|
BKE_anim_path_calc_data(ob);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2018-07-30 16:54:40 +02:00
|
|
|
BKE_nurbList_duplicate(&ob->runtime.curve_cache->deformed_nurbs, &nubase);
|
2020-04-30 15:46:45 +02:00
|
|
|
curve_calc_modifiers_post(
|
2021-06-07 17:04:31 -05:00
|
|
|
depsgraph, scene, ob, dispbase, for_render, force_mesh_conversion, r_final);
|
2014-10-21 14:44:08 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-02-27 11:23:15 +01:00
|
|
|
if (cu->flag & CU_DEFORM_FILL && !ob->runtime.data_eval) {
|
2021-03-31 18:07:15 -05:00
|
|
|
curve_to_filledpoly(cu, dispbase);
|
2010-03-16 21:09:53 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-19 09:36:40 +00:00
|
|
|
BKE_nurbList_free(&nubase);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2010-03-08 13:49:13 +00:00
|
|
|
}
|
|
|
|
|
|
2021-03-31 18:07:15 -05:00
|
|
|
void BKE_displist_make_curveTypes(Depsgraph *depsgraph,
|
|
|
|
|
const Scene *scene,
|
|
|
|
|
Object *ob,
|
|
|
|
|
const bool for_render,
|
|
|
|
|
const bool for_orco)
|
2010-03-08 13:49:13 +00:00
|
|
|
{
|
2011-08-16 10:31:28 +00:00
|
|
|
/* The same check for duplis as in do_makeDispListCurveTypes.
|
2012-03-09 18:28:30 +00:00
|
|
|
* Happens when curve used for constraint/bevel was converted to mesh.
|
|
|
|
|
* check there is still needed for render displist and orco displists. */
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!ELEM(ob->type, OB_SURF, OB_CURVE, OB_FONT)) {
|
2012-05-07 06:58:03 +00:00
|
|
|
return;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2011-08-16 10:31:28 +00:00
|
|
|
|
2013-08-21 07:40:19 +00:00
|
|
|
BKE_object_free_derived_caches(ob);
|
|
|
|
|
|
2018-07-30 16:54:40 +02:00
|
|
|
if (!ob->runtime.curve_cache) {
|
2021-04-26 15:11:53 -05:00
|
|
|
ob->runtime.curve_cache = (CurveCache *)MEM_callocN(sizeof(CurveCache),
|
|
|
|
|
"CurveCache for curve types");
|
2013-08-19 09:25:24 +00:00
|
|
|
}
|
|
|
|
|
|
2021-06-07 13:08:03 -05:00
|
|
|
ListBase *dispbase = &(ob->runtime.curve_cache->disp);
|
2010-03-08 13:49:13 +00:00
|
|
|
|
2021-04-26 15:11:53 -05:00
|
|
|
Mesh *mesh_eval = nullptr;
|
2020-02-27 11:23:15 +01:00
|
|
|
do_makeDispListCurveTypes(depsgraph, scene, ob, dispbase, for_render, for_orco, &mesh_eval);
|
2010-03-05 16:47:52 +00:00
|
|
|
|
2021-04-26 15:11:53 -05:00
|
|
|
if (mesh_eval != nullptr) {
|
2020-02-27 11:23:15 +01:00
|
|
|
BKE_object_eval_assign_data(ob, &mesh_eval->id, true);
|
2019-06-09 21:11:37 +02:00
|
|
|
}
|
|
|
|
|
|
2013-08-19 09:13:15 +00:00
|
|
|
boundbox_displist_object(ob);
|
2010-03-05 16:47:52 +00:00
|
|
|
}
|
|
|
|
|
|
2017-08-16 12:45:11 +10:00
|
|
|
void BKE_displist_make_curveTypes_forRender(Depsgraph *depsgraph,
|
2021-03-31 18:07:15 -05:00
|
|
|
const Scene *scene,
|
2018-04-06 12:07:27 +02:00
|
|
|
Object *ob,
|
|
|
|
|
ListBase *dispbase,
|
2018-10-15 15:58:58 +11:00
|
|
|
Mesh **r_final,
|
2019-05-21 14:54:08 +02:00
|
|
|
const bool for_orco)
|
2010-03-08 13:49:13 +00:00
|
|
|
{
|
2021-04-26 15:11:53 -05:00
|
|
|
if (ob->runtime.curve_cache == nullptr) {
|
|
|
|
|
ob->runtime.curve_cache = (CurveCache *)MEM_callocN(sizeof(CurveCache),
|
|
|
|
|
"CurveCache for Curve");
|
2013-08-19 14:22:02 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-21 14:54:08 +02:00
|
|
|
do_makeDispListCurveTypes(depsgraph, scene, ob, dispbase, true, for_orco, r_final);
|
2010-03-08 13:49:13 +00:00
|
|
|
}
|
|
|
|
|
|
2021-03-31 18:07:15 -05:00
|
|
|
void BKE_displist_minmax(const ListBase *dispbase, float min[3], float max[3])
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2021-06-07 13:08:03 -05:00
|
|
|
bool doit = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-03-31 18:07:15 -05:00
|
|
|
LISTBASE_FOREACH (const DispList *, dl, dispbase) {
|
2021-06-07 13:08:03 -05:00
|
|
|
const int tot = (dl->type == DL_INDEX3) ? dl->nr : dl->nr * dl->parts;
|
|
|
|
|
for (const int i : IndexRange(tot)) {
|
|
|
|
|
minmax_v3v3_v3(min, max, &dl->verts[i]);
|
|
|
|
|
}
|
|
|
|
|
if (tot != 0) {
|
|
|
|
|
doit = true;
|
2013-01-29 08:21:21 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-01-29 08:21:21 +00:00
|
|
|
if (!doit) {
|
|
|
|
|
/* there's no geometry in displist, use zero-sized boundbox */
|
|
|
|
|
zero_v3(min);
|
|
|
|
|
zero_v3(max);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-01 13:53:25 +10:00
|
|
|
/* this is confusing, there's also min_max_object, applying the obmat... */
|
2013-08-19 09:13:15 +00:00
|
|
|
static void boundbox_displist_object(Object *ob)
|
2013-01-29 08:21:21 +00:00
|
|
|
{
|
2014-07-20 01:30:29 +10:00
|
|
|
if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
|
2014-07-18 17:46:45 +02:00
|
|
|
/* Curve's BB is already calculated as a part of modifier stack,
|
2021-06-07 13:29:37 -05:00
|
|
|
* here we only calculate object BB based on final display list. */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-01-29 08:21:21 +00:00
|
|
|
/* object's BB is calculated from final displist */
|
2021-04-26 15:11:53 -05:00
|
|
|
if (ob->runtime.bb == nullptr) {
|
|
|
|
|
ob->runtime.bb = (BoundBox *)MEM_callocN(sizeof(BoundBox), "boundbox");
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-02-27 11:23:15 +01:00
|
|
|
Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
|
|
|
|
|
if (mesh_eval) {
|
|
|
|
|
BKE_object_boundbox_calc_from_mesh(ob, mesh_eval);
|
2013-08-19 09:13:15 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2013-08-21 07:40:19 +00:00
|
|
|
float min[3], max[3];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-08-21 07:40:19 +00:00
|
|
|
INIT_MINMAX(min, max);
|
2018-07-30 16:54:40 +02:00
|
|
|
BKE_displist_minmax(&ob->runtime.curve_cache->disp, min, max);
|
2019-02-17 12:24:08 +11:00
|
|
|
BKE_boundbox_init_from_minmax(ob->runtime.bb, min, max);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-02-17 12:24:08 +11:00
|
|
|
ob->runtime.bb->flag &= ~BOUNDBOX_DIRTY;
|
2013-08-19 09:13:15 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
}
|