2022-02-10 23:07:11 +01:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
* Copyright 2005 Blender Foundation. All rights reserved. */
|
2005-03-27 22:34:18 +02:00
|
|
|
|
2019-02-17 22:08:12 +01:00
|
|
|
/** \file
|
|
|
|
* \ingroup bke
|
2011-02-27 21:40:57 +01:00
|
|
|
*/
|
|
|
|
|
2020-12-14 13:00:28 +01:00
|
|
|
#include <climits>
|
|
|
|
#include <cstring>
|
2005-07-23 21:15:08 +02:00
|
|
|
|
2005-03-27 22:34:18 +02:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
2010-03-30 13:49:07 +02:00
|
|
|
#include "DNA_cloth_types.h"
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
#include "DNA_customdata_types.h"
|
2006-08-28 03:12:36 +02:00
|
|
|
#include "DNA_key_types.h"
|
2014-07-21 12:02:05 +02:00
|
|
|
#include "DNA_material_types.h"
|
2012-02-19 23:17:30 +01:00
|
|
|
#include "DNA_mesh_types.h"
|
2005-03-27 22:34:18 +02:00
|
|
|
#include "DNA_meshdata_types.h"
|
|
|
|
#include "DNA_object_types.h"
|
2014-04-27 18:22:03 +02:00
|
|
|
#include "DNA_scene_types.h"
|
2005-03-27 22:34:18 +02:00
|
|
|
|
Fix T47038: Particles in Particle Edit Mode get added in completely wrong location.
It also fixes another issue (crash) related to symmetric editing.
Quite involved, we (try to!) fix complete broken logic of parts of particle code, which would use poly index
as tessface one (or vice-versa). Issue most probably goes back to BMesh integration time...
This patch mostly fixes particle editing mode:
- Adding/removing particles when using generative modifiers (like subsurf) should now work.
- Adding/removing particles with a non-tessellated mesh (i.e. one having ngons) should also mostly work.
- X-axis-mirror-editing particles over ngons does not really work, not sure why currently.
- All this in both 'modes' (with or without using modifier stack for particles).
Tech side:
- Store a deformed-only DM in particle modifier data.
- Rename existing DM to make it clear it's a final one.
- Use deformed-only DM's tessface2poly mapping to 'solve' poly/tessface mismatches.
- Make (part of) mirror-editing code able to use a DM instead of raw mesh, so that we can mirror based on final DM
when editing particles using modifier stack (mandatory, since there is no way currently to find orig tessface
from an final DM tessface index).
Note that this patch is not really nice and clean (current particles are beyond hope on this side anyway),
it's more like some urgency bandage. Whole crap needs complete rewrite anyway,
BMesh's polygons make it really hard to work with current system (and looptri would not help much here).
Also, did not test everything possibly affected by those changes, so it needs some users' testing & validation too.
Reviewers: psy-fi
Subscribers: dfelinto, eyecandy
Maniphest Tasks: T47038
Differential Revision: https://developer.blender.org/D1685
2016-01-04 12:19:45 +01:00
|
|
|
#include "BLI_array.h"
|
2014-09-04 09:53:10 +02:00
|
|
|
#include "BLI_bitmap.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_blenlib.h"
|
2011-10-22 03:53:35 +02:00
|
|
|
#include "BLI_linklist.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_math.h"
|
BLI: Refactor vector types & functions to use templates
This patch implements the vector types (i.e:`float2`) by making heavy
usage of templating. All vector functions are now outside of the vector
classes (inside the `blender::math` namespace) and are not vector size
dependent for the most part.
In the ongoing effort to make shaders less GL centric, we are aiming
to share more code between GLSL and C++ to avoid code duplication.
####Motivations:
- We are aiming to share UBO and SSBO structures between GLSL and C++.
This means we will use many of the existing vector types and others
we currently don't have (uintX, intX). All these variations were
asking for many more code duplication.
- Deduplicate existing code which is duplicated for each vector size.
- We also want to share small functions. Which means that vector
functions should be static and not in the class namespace.
- Reduce friction to use these types in new projects due to their
incompleteness.
- The current state of the `BLI_(float|double|mpq)(2|3|4).hh` is a
bit of a let down. Most clases are incomplete, out of sync with each
others with different codestyles, and some functions that should be
static are not (i.e: `float3::reflect()`).
####Upsides:
- Still support `.x, .y, .z, .w` for readability.
- Compact, readable and easilly extendable.
- All of the vector functions are available for all the vectors types
and can be restricted to certain types. Also template specialization
let us define exception for special class (like mpq).
- With optimization ON, the compiler unroll the loops and performance
is the same.
####Downsides:
- Might impact debugability. Though I would arge that the bugs are
rarelly caused by the vector class itself (since the operations are
quite trivial) but by the type conversions.
- Might impact compile time. I did not saw a significant impact since
the usage is not really widespread.
- Functions needs to be rewritten to support arbitrary vector length.
For instance, one can't call `len_squared_v3v3` in
`math::length_squared()` and call it a day.
- Type cast does not work with the template version of the `math::`
vector functions. Meaning you need to manually cast `float *` and
`(float *)[3]` to `float3` for the function calls.
i.e: `math::distance_squared(float3(nearest.co), positions[i]);`
- Some parts might loose in readability:
`float3::dot(v1.normalized(), v2.normalized())`
becoming
`math::dot(math::normalize(v1), math::normalize(v2))`
But I propose, when appropriate, to use
`using namespace blender::math;` on function local or file scope to
increase readability.
`dot(normalize(v1), normalize(v2))`
####Consideration:
- Include back `.length()` method. It is quite handy and is more C++
oriented.
- I considered the GLM library as a candidate for replacement. It felt
like too much for what we need and would be difficult to extend / modify
to our needs.
- I used Macros to reduce code in operators declaration and potential
copy paste bugs. This could reduce debugability and could be reverted.
- This touches `delaunay_2d.cc` and the intersection code. I would like
to know @howardt opinion on the matter.
- The `noexcept` on the copy constructor of `mpq(2|3)` is being removed.
But according to @JacquesLucke it is not a real problem for now.
I would like to give a huge thanks to @JacquesLucke who helped during this
and pushed me to reduce the duplication further.
Reviewed By: brecht, sergey, JacquesLucke
Differential Revision: https://developer.blender.org/D13791
2022-01-12 12:57:07 +01:00
|
|
|
#include "BLI_math_vec_types.hh"
|
2016-04-26 10:43:02 +02:00
|
|
|
#include "BLI_task.h"
|
2021-06-21 18:44:40 +02:00
|
|
|
#include "BLI_task.hh"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_utildefines.h"
|
2020-12-14 13:00:28 +01:00
|
|
|
#include "BLI_vector.hh"
|
2005-03-27 22:34:18 +02:00
|
|
|
|
2020-02-26 04:24:57 +01:00
|
|
|
#include "BKE_DerivedMesh.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BKE_bvhutils.h"
|
2017-12-07 05:36:26 +01:00
|
|
|
#include "BKE_colorband.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BKE_deform.h"
|
2013-04-18 19:09:56 +02:00
|
|
|
#include "BKE_editmesh.h"
|
2020-12-15 12:42:10 +01:00
|
|
|
#include "BKE_geometry_set.hh"
|
2021-02-17 12:27:32 +01:00
|
|
|
#include "BKE_geometry_set_instances.hh"
|
2007-10-31 14:56:07 +01:00
|
|
|
#include "BKE_key.h"
|
2017-04-18 14:55:31 +02:00
|
|
|
#include "BKE_layer.h"
|
2020-02-10 12:58:59 +01:00
|
|
|
#include "BKE_lib_id.h"
|
2014-04-09 03:03:25 +02:00
|
|
|
#include "BKE_material.h"
|
2005-03-27 22:34:18 +02:00
|
|
|
#include "BKE_mesh.h"
|
2018-10-09 07:52:46 +02:00
|
|
|
#include "BKE_mesh_iterators.h"
|
2014-01-21 16:32:36 +01:00
|
|
|
#include "BKE_mesh_mapping.h"
|
2018-06-05 15:59:53 +02:00
|
|
|
#include "BKE_mesh_runtime.h"
|
2017-05-24 14:33:21 +02:00
|
|
|
#include "BKE_mesh_tangent.h"
|
2020-06-10 14:32:06 +02:00
|
|
|
#include "BKE_mesh_wrapper.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BKE_modifier.h"
|
|
|
|
#include "BKE_multires.h"
|
2005-03-27 22:34:18 +02:00
|
|
|
#include "BKE_object.h"
|
2012-09-05 05:45:32 +02:00
|
|
|
#include "BKE_object_deform.h"
|
2009-08-15 21:48:50 +02:00
|
|
|
#include "BKE_paint.h"
|
2005-03-27 22:34:18 +02:00
|
|
|
|
2013-05-28 21:35:26 +02:00
|
|
|
#include "BLI_sys_types.h" /* for intptr_t support */
|
2008-08-17 19:08:00 +02:00
|
|
|
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BKE_shrinkwrap.h"
|
2018-04-16 20:45:43 +02:00
|
|
|
#include "DEG_depsgraph.h"
|
|
|
|
#include "DEG_depsgraph_query.h"
|
|
|
|
|
2019-02-01 02:44:19 +01:00
|
|
|
#include "CLG_log.h"
|
|
|
|
|
2015-08-03 20:35:43 +02:00
|
|
|
#ifdef WITH_OPENSUBDIV
|
|
|
|
# include "DNA_userdef_types.h"
|
|
|
|
#endif
|
|
|
|
|
2013-09-04 03:29:34 +02:00
|
|
|
/* very slow! enable for testing only! */
|
2014-12-02 13:49:40 +01:00
|
|
|
//#define USE_MODIFIER_VALIDATE
|
2013-09-04 03:29:34 +02:00
|
|
|
|
|
|
|
#ifdef USE_MODIFIER_VALIDATE
|
2018-05-11 09:53:52 +02:00
|
|
|
# define ASSERT_IS_VALID_MESH(mesh) \
|
2020-12-14 13:00:28 +01:00
|
|
|
(BLI_assert((mesh == nullptr) || (BKE_mesh_is_valid(mesh) == true)))
|
2013-09-04 03:29:34 +02:00
|
|
|
#else
|
2018-05-11 09:53:52 +02:00
|
|
|
# define ASSERT_IS_VALID_MESH(mesh)
|
2013-09-04 03:29:34 +02:00
|
|
|
#endif
|
|
|
|
|
2017-09-19 13:09:35 +02:00
|
|
|
static ThreadRWMutex loops_cache_lock = PTHREAD_RWLOCK_INITIALIZER;
|
2017-08-11 16:51:19 +02:00
|
|
|
|
2018-05-11 09:53:52 +02:00
|
|
|
static void mesh_init_origspace(Mesh *mesh);
|
2020-05-25 12:16:42 +02:00
|
|
|
static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final,
|
|
|
|
const CustomData_MeshMasks *final_datamask);
|
2018-05-11 09:53:52 +02:00
|
|
|
|
2013-09-04 03:29:34 +02:00
|
|
|
/* -------------------------------------------------------------------- */
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 05:28:02 +01:00
|
|
|
|
2008-09-29 19:08:11 +02:00
|
|
|
static MVert *dm_getVertArray(DerivedMesh *dm)
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 05:28:02 +01:00
|
|
|
{
|
2020-12-14 13:00:28 +01:00
|
|
|
MVert *mvert = (MVert *)CustomData_get_layer(&dm->vertData, CD_MVERT);
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 05:28:02 +01:00
|
|
|
|
|
|
|
if (!mvert) {
|
2020-12-14 13:00:28 +01:00
|
|
|
mvert = (MVert *)CustomData_add_layer(
|
|
|
|
&dm->vertData, CD_MVERT, CD_CALLOC, nullptr, dm->getNumVerts(dm));
|
2006-12-12 22:29:09 +01:00
|
|
|
CustomData_set_layer_flag(&dm->vertData, CD_MVERT, CD_FLAG_TEMPORARY);
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 05:28:02 +01:00
|
|
|
dm->copyVertArray(dm, mvert);
|
|
|
|
}
|
|
|
|
|
|
|
|
return mvert;
|
|
|
|
}
|
|
|
|
|
2008-09-29 19:08:11 +02:00
|
|
|
static MEdge *dm_getEdgeArray(DerivedMesh *dm)
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 05:28:02 +01:00
|
|
|
{
|
2020-12-14 13:00:28 +01:00
|
|
|
MEdge *medge = (MEdge *)CustomData_get_layer(&dm->edgeData, CD_MEDGE);
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 05:28:02 +01:00
|
|
|
|
|
|
|
if (!medge) {
|
2020-12-14 13:00:28 +01:00
|
|
|
medge = (MEdge *)CustomData_add_layer(
|
|
|
|
&dm->edgeData, CD_MEDGE, CD_CALLOC, nullptr, dm->getNumEdges(dm));
|
2006-12-12 22:29:09 +01:00
|
|
|
CustomData_set_layer_flag(&dm->edgeData, CD_MEDGE, CD_FLAG_TEMPORARY);
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 05:28:02 +01:00
|
|
|
dm->copyEdgeArray(dm, medge);
|
|
|
|
}
|
|
|
|
|
|
|
|
return medge;
|
|
|
|
}
|
|
|
|
|
2011-06-14 05:16:08 +02:00
|
|
|
static MLoop *dm_getLoopArray(DerivedMesh *dm)
|
|
|
|
{
|
2020-12-14 13:00:28 +01:00
|
|
|
MLoop *mloop = (MLoop *)CustomData_get_layer(&dm->loopData, CD_MLOOP);
|
2011-06-14 05:16:08 +02:00
|
|
|
|
|
|
|
if (!mloop) {
|
2020-12-14 13:00:28 +01:00
|
|
|
mloop = (MLoop *)CustomData_add_layer(
|
|
|
|
&dm->loopData, CD_MLOOP, CD_CALLOC, nullptr, dm->getNumLoops(dm));
|
2011-06-14 05:16:08 +02:00
|
|
|
CustomData_set_layer_flag(&dm->loopData, CD_MLOOP, CD_FLAG_TEMPORARY);
|
|
|
|
dm->copyLoopArray(dm, mloop);
|
|
|
|
}
|
|
|
|
|
|
|
|
return mloop;
|
|
|
|
}
|
|
|
|
|
|
|
|
static MPoly *dm_getPolyArray(DerivedMesh *dm)
|
|
|
|
{
|
2020-12-14 13:00:28 +01:00
|
|
|
MPoly *mpoly = (MPoly *)CustomData_get_layer(&dm->polyData, CD_MPOLY);
|
2011-06-14 05:16:08 +02:00
|
|
|
|
|
|
|
if (!mpoly) {
|
2020-12-14 13:00:28 +01:00
|
|
|
mpoly = (MPoly *)CustomData_add_layer(
|
|
|
|
&dm->polyData, CD_MPOLY, CD_CALLOC, nullptr, dm->getNumPolys(dm));
|
2011-06-14 05:16:08 +02:00
|
|
|
CustomData_set_layer_flag(&dm->polyData, CD_MPOLY, CD_FLAG_TEMPORARY);
|
|
|
|
dm->copyPolyArray(dm, mpoly);
|
|
|
|
}
|
|
|
|
|
|
|
|
return mpoly;
|
|
|
|
}
|
|
|
|
|
2008-09-29 19:08:11 +02:00
|
|
|
static MVert *dm_dupVertArray(DerivedMesh *dm)
|
2006-08-28 03:12:36 +02:00
|
|
|
{
|
2020-12-14 13:00:28 +01:00
|
|
|
MVert *tmp = (MVert *)MEM_malloc_arrayN(
|
|
|
|
dm->getNumVerts(dm), sizeof(*tmp), "dm_dupVertArray tmp");
|
2006-08-28 03:12:36 +02:00
|
|
|
|
2019-04-22 01:39:35 +02:00
|
|
|
if (tmp) {
|
2012-03-24 07:18:31 +01:00
|
|
|
dm->copyVertArray(dm, tmp);
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
2006-08-28 03:12:36 +02:00
|
|
|
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
2008-09-29 19:08:11 +02:00
|
|
|
static MEdge *dm_dupEdgeArray(DerivedMesh *dm)
|
2006-08-28 03:12:36 +02:00
|
|
|
{
|
2020-12-14 13:00:28 +01:00
|
|
|
MEdge *tmp = (MEdge *)MEM_malloc_arrayN(
|
|
|
|
dm->getNumEdges(dm), sizeof(*tmp), "dm_dupEdgeArray tmp");
|
2006-08-28 03:12:36 +02:00
|
|
|
|
2019-04-22 01:39:35 +02:00
|
|
|
if (tmp) {
|
2012-03-24 07:18:31 +01:00
|
|
|
dm->copyEdgeArray(dm, tmp);
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
2006-08-28 03:12:36 +02:00
|
|
|
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
2011-06-14 05:16:08 +02:00
|
|
|
static MLoop *dm_dupLoopArray(DerivedMesh *dm)
|
|
|
|
{
|
2020-12-14 13:00:28 +01:00
|
|
|
MLoop *tmp = (MLoop *)MEM_malloc_arrayN(
|
|
|
|
dm->getNumLoops(dm), sizeof(*tmp), "dm_dupLoopArray tmp");
|
2011-06-14 05:16:08 +02:00
|
|
|
|
2019-04-22 01:39:35 +02:00
|
|
|
if (tmp) {
|
2012-03-24 07:18:31 +01:00
|
|
|
dm->copyLoopArray(dm, tmp);
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
2011-06-14 05:16:08 +02:00
|
|
|
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
static MPoly *dm_dupPolyArray(DerivedMesh *dm)
|
|
|
|
{
|
2020-12-14 13:00:28 +01:00
|
|
|
MPoly *tmp = (MPoly *)MEM_malloc_arrayN(
|
|
|
|
dm->getNumPolys(dm), sizeof(*tmp), "dm_dupPolyArray tmp");
|
2011-06-14 05:16:08 +02:00
|
|
|
|
2019-04-22 01:39:35 +02:00
|
|
|
if (tmp) {
|
2012-03-24 07:18:31 +01:00
|
|
|
dm->copyPolyArray(dm, tmp);
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
2011-06-14 05:16:08 +02:00
|
|
|
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
2015-07-16 19:36:03 +02:00
|
|
|
static int dm_getNumLoopTri(DerivedMesh *dm)
|
|
|
|
{
|
2016-11-23 20:19:03 +01:00
|
|
|
const int numlooptris = poly_to_tri_count(dm->getNumPolys(dm), dm->getNumLoops(dm));
|
|
|
|
BLI_assert(ELEM(dm->looptris.num, 0, numlooptris));
|
|
|
|
return numlooptris;
|
2015-07-16 19:36:03 +02:00
|
|
|
}
|
|
|
|
|
2017-08-11 15:41:53 +02:00
|
|
|
static const MLoopTri *dm_getLoopTriArray(DerivedMesh *dm)
|
|
|
|
{
|
2017-09-19 13:09:35 +02:00
|
|
|
MLoopTri *looptri;
|
|
|
|
|
|
|
|
BLI_rw_mutex_lock(&loops_cache_lock, THREAD_LOCK_READ);
|
|
|
|
looptri = dm->looptris.array;
|
|
|
|
BLI_rw_mutex_unlock(&loops_cache_lock);
|
|
|
|
|
2020-12-14 13:00:28 +01:00
|
|
|
if (looptri != nullptr) {
|
2017-08-11 16:18:01 +02:00
|
|
|
BLI_assert(dm->getNumLoopTri(dm) == dm->looptris.num);
|
2017-08-11 15:41:53 +02:00
|
|
|
}
|
|
|
|
else {
|
2017-09-19 13:09:35 +02:00
|
|
|
BLI_rw_mutex_lock(&loops_cache_lock, THREAD_LOCK_WRITE);
|
2020-12-14 13:00:28 +01:00
|
|
|
/* We need to ensure array is still nullptr inside mutex-protected code,
|
2019-04-27 04:07:07 +02:00
|
|
|
* some other thread might have already recomputed those looptris. */
|
2020-12-14 13:00:28 +01:00
|
|
|
if (dm->looptris.array == nullptr) {
|
2017-08-11 16:51:19 +02:00
|
|
|
dm->recalcLoopTri(dm);
|
|
|
|
}
|
2017-09-19 13:09:35 +02:00
|
|
|
looptri = dm->looptris.array;
|
|
|
|
BLI_rw_mutex_unlock(&loops_cache_lock);
|
2017-08-11 15:41:53 +02:00
|
|
|
}
|
2017-09-19 13:09:35 +02:00
|
|
|
return looptri;
|
2017-08-11 15:41:53 +02:00
|
|
|
}
|
|
|
|
|
2006-08-28 03:12:36 +02:00
|
|
|
void DM_init_funcs(DerivedMesh *dm)
|
|
|
|
{
|
|
|
|
/* default function implementations */
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 05:28:02 +01:00
|
|
|
dm->getVertArray = dm_getVertArray;
|
|
|
|
dm->getEdgeArray = dm_getEdgeArray;
|
2011-06-14 05:16:08 +02:00
|
|
|
dm->getLoopArray = dm_getLoopArray;
|
|
|
|
dm->getPolyArray = dm_getPolyArray;
|
2006-08-28 03:12:36 +02:00
|
|
|
dm->dupVertArray = dm_dupVertArray;
|
|
|
|
dm->dupEdgeArray = dm_dupEdgeArray;
|
2011-06-14 05:16:08 +02:00
|
|
|
dm->dupLoopArray = dm_dupLoopArray;
|
|
|
|
dm->dupPolyArray = dm_dupPolyArray;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-08-11 15:41:53 +02:00
|
|
|
dm->getLoopTriArray = dm_getLoopTriArray;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-07-16 19:36:03 +02:00
|
|
|
/* subtypes handle getting actual data */
|
|
|
|
dm->getNumLoopTri = dm_getNumLoopTri;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2006-08-28 03:12:36 +02:00
|
|
|
dm->getVertDataArray = DM_get_vert_data_layer;
|
|
|
|
dm->getEdgeDataArray = DM_get_edge_data_layer;
|
2012-10-30 20:20:17 +01:00
|
|
|
dm->getPolyDataArray = DM_get_poly_data_layer;
|
2013-04-03 22:10:08 +02:00
|
|
|
dm->getLoopDataArray = DM_get_loop_data_layer;
|
2006-08-28 03:12:36 +02:00
|
|
|
}
|
|
|
|
|
2015-07-02 08:20:22 +02:00
|
|
|
void DM_init(DerivedMesh *dm,
|
|
|
|
DerivedMeshType type,
|
|
|
|
int numVerts,
|
|
|
|
int numEdges,
|
|
|
|
int numTessFaces,
|
|
|
|
int numLoops,
|
|
|
|
int numPolys)
|
2006-08-28 03:12:36 +02:00
|
|
|
{
|
2010-01-06 13:05:46 +01:00
|
|
|
dm->type = type;
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 05:28:02 +01:00
|
|
|
dm->numVertData = numVerts;
|
|
|
|
dm->numEdgeData = numEdges;
|
2011-11-30 19:03:56 +01:00
|
|
|
dm->numTessFaceData = numTessFaces;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 12:06:25 +02:00
|
|
|
dm->numLoopData = numLoops;
|
2011-11-30 19:03:56 +01:00
|
|
|
dm->numPolyData = numPolys;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2006-08-28 03:12:36 +02:00
|
|
|
DM_init_funcs(dm);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 05:28:02 +01:00
|
|
|
dm->needsFree = 1;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-08-12 06:34:41 +02:00
|
|
|
/* Don't use #CustomData_reset because we don't want to touch custom-data. */
|
2015-05-05 09:08:29 +02:00
|
|
|
copy_vn_i(dm->vertData.typemap, CD_NUMTYPES, -1);
|
|
|
|
copy_vn_i(dm->edgeData.typemap, CD_NUMTYPES, -1);
|
|
|
|
copy_vn_i(dm->faceData.typemap, CD_NUMTYPES, -1);
|
|
|
|
copy_vn_i(dm->loopData.typemap, CD_NUMTYPES, -1);
|
|
|
|
copy_vn_i(dm->polyData.typemap, CD_NUMTYPES, -1);
|
2006-08-28 03:12:36 +02:00
|
|
|
}
|
|
|
|
|
2022-01-31 01:15:38 +01:00
|
|
|
void DM_from_template(DerivedMesh *dm,
|
|
|
|
DerivedMesh *source,
|
|
|
|
DerivedMeshType type,
|
|
|
|
int numVerts,
|
|
|
|
int numEdges,
|
|
|
|
int numTessFaces,
|
|
|
|
int numLoops,
|
|
|
|
int numPolys)
|
2006-08-28 03:12:36 +02:00
|
|
|
{
|
2022-01-31 01:15:38 +01:00
|
|
|
const CustomData_MeshMasks *mask = &CD_MASK_DERIVEDMESH;
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
CustomData_copy(&source->vertData, &dm->vertData, mask->vmask, CD_CALLOC, numVerts);
|
|
|
|
CustomData_copy(&source->edgeData, &dm->edgeData, mask->emask, CD_CALLOC, numEdges);
|
|
|
|
CustomData_copy(&source->faceData, &dm->faceData, mask->fmask, CD_CALLOC, numTessFaces);
|
|
|
|
CustomData_copy(&source->loopData, &dm->loopData, mask->lmask, CD_CALLOC, numLoops);
|
|
|
|
CustomData_copy(&source->polyData, &dm->polyData, mask->pmask, CD_CALLOC, numPolys);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-01-10 05:43:31 +01:00
|
|
|
dm->cd_flag = source->cd_flag;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-01-06 13:05:46 +01:00
|
|
|
dm->type = type;
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 05:28:02 +01:00
|
|
|
dm->numVertData = numVerts;
|
|
|
|
dm->numEdgeData = numEdges;
|
2011-11-30 19:03:56 +01:00
|
|
|
dm->numTessFaceData = numTessFaces;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 12:06:25 +02:00
|
|
|
dm->numLoopData = numLoops;
|
|
|
|
dm->numPolyData = numPolys;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2006-08-28 03:12:36 +02:00
|
|
|
DM_init_funcs(dm);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 05:28:02 +01:00
|
|
|
dm->needsFree = 1;
|
2006-08-28 03:12:36 +02:00
|
|
|
}
|
|
|
|
|
2020-09-02 19:10:18 +02:00
|
|
|
bool DM_release(DerivedMesh *dm)
|
2006-08-28 03:12:36 +02:00
|
|
|
{
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 05:28:02 +01:00
|
|
|
if (dm->needsFree) {
|
|
|
|
CustomData_free(&dm->vertData, dm->numVertData);
|
|
|
|
CustomData_free(&dm->edgeData, dm->numEdgeData);
|
2011-11-30 19:03:56 +01:00
|
|
|
CustomData_free(&dm->faceData, dm->numTessFaceData);
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 12:06:25 +02:00
|
|
|
CustomData_free(&dm->loopData, dm->numLoopData);
|
|
|
|
CustomData_free(&dm->polyData, dm->numPolyData);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-07-16 19:36:03 +02:00
|
|
|
MEM_SAFE_FREE(dm->looptris.array);
|
|
|
|
dm->looptris.num = 0;
|
|
|
|
dm->looptris.num_alloc = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-09-02 19:10:18 +02:00
|
|
|
return true;
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 05:28:02 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-07-03 18:04:40 +02:00
|
|
|
CustomData_free_temporary(&dm->vertData, dm->numVertData);
|
|
|
|
CustomData_free_temporary(&dm->edgeData, dm->numEdgeData);
|
|
|
|
CustomData_free_temporary(&dm->faceData, dm->numTessFaceData);
|
|
|
|
CustomData_free_temporary(&dm->loopData, dm->numLoopData);
|
|
|
|
CustomData_free_temporary(&dm->polyData, dm->numPolyData);
|
|
|
|
|
2020-09-02 19:10:18 +02:00
|
|
|
return false;
|
2006-08-28 03:12:36 +02:00
|
|
|
}
|
|
|
|
|
2011-06-14 05:16:08 +02:00
|
|
|
void DM_DupPolys(DerivedMesh *source, DerivedMesh *target)
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 12:06:25 +02:00
|
|
|
{
|
2011-10-27 14:17:02 +02:00
|
|
|
CustomData_free(&target->loopData, source->numLoopData);
|
|
|
|
CustomData_free(&target->polyData, source->numPolyData);
|
|
|
|
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
CustomData_copy(&source->loopData,
|
|
|
|
&target->loopData,
|
|
|
|
CD_MASK_DERIVEDMESH.lmask,
|
|
|
|
CD_DUPLICATE,
|
|
|
|
source->numLoopData);
|
|
|
|
CustomData_copy(&source->polyData,
|
|
|
|
&target->polyData,
|
|
|
|
CD_MASK_DERIVEDMESH.pmask,
|
|
|
|
CD_DUPLICATE,
|
|
|
|
source->numPolyData);
|
2009-08-18 22:05:08 +02:00
|
|
|
|
2011-06-14 05:16:08 +02:00
|
|
|
target->numLoopData = source->numLoopData;
|
|
|
|
target->numPolyData = source->numPolyData;
|
2009-08-18 22:05:08 +02:00
|
|
|
|
2011-06-14 05:16:08 +02:00
|
|
|
if (!CustomData_has_layer(&target->polyData, CD_MPOLY)) {
|
|
|
|
MPoly *mpoly;
|
|
|
|
MLoop *mloop;
|
2009-08-18 22:05:08 +02:00
|
|
|
|
2011-06-14 05:16:08 +02:00
|
|
|
mloop = source->dupLoopArray(source);
|
|
|
|
mpoly = source->dupPolyArray(source);
|
|
|
|
CustomData_add_layer(&target->loopData, CD_MLOOP, CD_ASSIGN, mloop, source->numLoopData);
|
|
|
|
CustomData_add_layer(&target->polyData, CD_MPOLY, CD_ASSIGN, mpoly, source->numPolyData);
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 12:06:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-16 19:36:03 +02:00
|
|
|
void DM_ensure_looptri_data(DerivedMesh *dm)
|
|
|
|
{
|
|
|
|
const unsigned int totpoly = dm->numPolyData;
|
|
|
|
const unsigned int totloop = dm->numLoopData;
|
|
|
|
const int looptris_num = poly_to_tri_count(totpoly, totloop);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-14 13:00:28 +01:00
|
|
|
BLI_assert(dm->looptris.array_wip == nullptr);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-09-19 13:57:46 +02:00
|
|
|
SWAP(MLoopTri *, dm->looptris.array, dm->looptris.array_wip);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-07-16 19:36:03 +02:00
|
|
|
if ((looptris_num > dm->looptris.num_alloc) || (looptris_num < dm->looptris.num_alloc * 2) ||
|
|
|
|
(totpoly == 0)) {
|
2017-09-19 13:57:46 +02:00
|
|
|
MEM_SAFE_FREE(dm->looptris.array_wip);
|
2015-07-16 19:36:03 +02:00
|
|
|
dm->looptris.num_alloc = 0;
|
|
|
|
dm->looptris.num = 0;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-07-16 19:36:03 +02:00
|
|
|
if (totpoly) {
|
2020-12-14 13:00:28 +01:00
|
|
|
if (dm->looptris.array_wip == nullptr) {
|
|
|
|
dm->looptris.array_wip = (MLoopTri *)MEM_malloc_arrayN(
|
2018-01-14 22:14:20 +01:00
|
|
|
looptris_num, sizeof(*dm->looptris.array_wip), __func__);
|
2015-07-16 19:36:03 +02:00
|
|
|
dm->looptris.num_alloc = looptris_num;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-07-16 19:36:03 +02:00
|
|
|
dm->looptris.num = looptris_num;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2015-07-16 19:36:03 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-06-21 18:24:32 +02:00
|
|
|
void BKE_mesh_runtime_eval_to_meshkey(Mesh *me_deformed, Mesh *me, KeyBlock *kb)
|
2009-11-22 14:44:09 +01:00
|
|
|
{
|
2021-12-07 07:19:15 +01:00
|
|
|
/* Just a shallow wrapper around #BKE_keyblock_convert_from_mesh,
|
|
|
|
* that ensures both evaluated mesh and original one has same number of vertices. */
|
|
|
|
|
2018-06-21 18:24:32 +02:00
|
|
|
const int totvert = me_deformed->totvert;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2015-07-02 08:20:22 +02:00
|
|
|
if (totvert == 0 || me->totvert == 0 || me->totvert != totvert) {
|
|
|
|
return;
|
|
|
|
}
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2018-06-21 18:24:32 +02:00
|
|
|
BKE_keyblock_convert_from_mesh(me_deformed, me->key, kb);
|
2009-11-22 14:44:09 +01:00
|
|
|
}
|
|
|
|
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
void DM_set_only_copy(DerivedMesh *dm, const CustomData_MeshMasks *mask)
|
2006-12-05 18:42:03 +01:00
|
|
|
{
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
CustomData_set_only_copy(&dm->vertData, mask->vmask);
|
|
|
|
CustomData_set_only_copy(&dm->edgeData, mask->emask);
|
|
|
|
CustomData_set_only_copy(&dm->faceData, mask->fmask);
|
2012-10-01 16:23:57 +02:00
|
|
|
/* this wasn't in 2.63 and is disabled for 2.64 because it gives problems with
|
|
|
|
* weight paint mode when there are modifiers applied, needs further investigation,
|
|
|
|
* see replies to r50969, Campbell */
|
|
|
|
#if 0
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
CustomData_set_only_copy(&dm->loopData, mask->lmask);
|
2022-01-31 00:01:03 +01:00
|
|
|
Custom(&dm->polyData, mask->pmask);
|
2012-10-01 16:23:57 +02:00
|
|
|
#endif
|
2006-12-05 18:42:03 +01:00
|
|
|
}
|
|
|
|
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
static void mesh_set_only_copy(Mesh *mesh, const CustomData_MeshMasks *mask)
|
2018-05-11 09:53:52 +02:00
|
|
|
{
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
CustomData_set_only_copy(&mesh->vdata, mask->vmask);
|
|
|
|
CustomData_set_only_copy(&mesh->edata, mask->emask);
|
|
|
|
CustomData_set_only_copy(&mesh->fdata, mask->fmask);
|
2018-05-11 09:53:52 +02:00
|
|
|
/* this wasn't in 2.63 and is disabled for 2.64 because it gives problems with
|
|
|
|
* weight paint mode when there are modifiers applied, needs further investigation,
|
|
|
|
* see replies to r50969, Campbell */
|
|
|
|
#if 0
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
CustomData_set_only_copy(&mesh->ldata, mask->lmask);
|
|
|
|
CustomData_set_only_copy(&mesh->pdata, mask->pmask);
|
2018-05-11 09:53:52 +02:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2018-05-30 10:28:24 +02:00
|
|
|
void DM_add_vert_layer(DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer)
|
2006-08-28 03:12:36 +02:00
|
|
|
{
|
2006-12-12 22:29:09 +01:00
|
|
|
CustomData_add_layer(&dm->vertData, type, alloctype, layer, dm->numVertData);
|
2006-08-28 03:12:36 +02:00
|
|
|
}
|
|
|
|
|
2018-05-30 10:28:24 +02:00
|
|
|
void DM_add_edge_layer(DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer)
|
2006-08-28 03:12:36 +02:00
|
|
|
{
|
2006-12-12 22:29:09 +01:00
|
|
|
CustomData_add_layer(&dm->edgeData, type, alloctype, layer, dm->numEdgeData);
|
2006-08-28 03:12:36 +02:00
|
|
|
}
|
|
|
|
|
2018-05-30 10:28:24 +02:00
|
|
|
void DM_add_poly_layer(DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer)
|
2009-08-15 19:31:28 +02:00
|
|
|
{
|
|
|
|
CustomData_add_layer(&dm->polyData, type, alloctype, layer, dm->numPolyData);
|
|
|
|
}
|
|
|
|
|
2006-08-28 03:12:36 +02:00
|
|
|
void *DM_get_vert_data_layer(DerivedMesh *dm, int type)
|
|
|
|
{
|
2019-04-22 01:39:35 +02:00
|
|
|
if (type == CD_MVERT) {
|
2010-01-06 13:05:46 +01:00
|
|
|
return dm->getVertArray(dm);
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
2010-01-06 13:05:46 +01:00
|
|
|
|
2006-08-28 03:12:36 +02:00
|
|
|
return CustomData_get_layer(&dm->vertData, type);
|
|
|
|
}
|
|
|
|
|
|
|
|
void *DM_get_edge_data_layer(DerivedMesh *dm, int type)
|
|
|
|
{
|
2019-04-22 01:39:35 +02:00
|
|
|
if (type == CD_MEDGE) {
|
2010-01-06 13:05:46 +01:00
|
|
|
return dm->getEdgeArray(dm);
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
2010-01-06 13:05:46 +01:00
|
|
|
|
2006-08-28 03:12:36 +02:00
|
|
|
return CustomData_get_layer(&dm->edgeData, type);
|
|
|
|
}
|
|
|
|
|
2011-11-29 06:09:54 +01:00
|
|
|
void *DM_get_poly_data_layer(DerivedMesh *dm, int type)
|
2009-08-15 19:31:28 +02:00
|
|
|
{
|
|
|
|
return CustomData_get_layer(&dm->polyData, type);
|
|
|
|
}
|
|
|
|
|
2012-02-05 12:30:26 +01:00
|
|
|
void *DM_get_loop_data_layer(DerivedMesh *dm, int type)
|
|
|
|
{
|
|
|
|
return CustomData_get_layer(&dm->loopData, type);
|
|
|
|
}
|
|
|
|
|
2006-08-28 03:12:36 +02:00
|
|
|
void DM_copy_vert_data(
|
2012-05-12 21:18:02 +02:00
|
|
|
DerivedMesh *source, DerivedMesh *dest, int source_index, int dest_index, int count)
|
2006-08-28 03:12:36 +02:00
|
|
|
{
|
|
|
|
CustomData_copy_data(&source->vertData, &dest->vertData, source_index, dest_index, count);
|
|
|
|
}
|
|
|
|
|
2015-07-02 08:20:22 +02:00
|
|
|
void DM_interp_vert_data(DerivedMesh *source,
|
|
|
|
DerivedMesh *dest,
|
|
|
|
int *src_indices,
|
|
|
|
float *weights,
|
|
|
|
int count,
|
|
|
|
int dest_index)
|
2006-08-28 03:12:36 +02:00
|
|
|
{
|
|
|
|
CustomData_interp(
|
2020-12-14 13:00:28 +01:00
|
|
|
&source->vertData, &dest->vertData, src_indices, weights, nullptr, count, dest_index);
|
2006-08-28 03:12:36 +02:00
|
|
|
}
|
|
|
|
|
2012-12-21 08:28:14 +01:00
|
|
|
static float (*get_editbmesh_orco_verts(BMEditMesh *em))[3]
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 22:51:28 +02:00
|
|
|
{
|
2009-05-16 18:18:08 +02:00
|
|
|
BMIter iter;
|
|
|
|
BMVert *eve;
|
2012-12-21 08:28:14 +01:00
|
|
|
float(*orco)[3];
|
|
|
|
int i;
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 22:51:28 +02:00
|
|
|
|
|
|
|
/* these may not really be the orco's, but it's only for preview.
|
|
|
|
* could be solver better once, but isn't simple */
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2020-12-14 13:00:28 +01:00
|
|
|
orco = (float(*)[3])MEM_malloc_arrayN(em->bm->totvert, sizeof(float[3]), "BMEditMesh Orco");
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 22:51:28 +02:00
|
|
|
|
2012-12-21 08:28:14 +01:00
|
|
|
BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
|
|
|
|
copy_v3_v3(orco[i], eve->co);
|
2011-11-06 16:39:20 +01:00
|
|
|
}
|
2018-06-17 17:05:51 +02:00
|
|
|
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 22:51:28 +02:00
|
|
|
return orco;
|
|
|
|
}
|
|
|
|
|
2009-05-23 05:24:15 +02:00
|
|
|
/* orco custom data layer */
|
2018-10-09 06:04:51 +02:00
|
|
|
static float (*get_orco_coords(Object *ob, BMEditMesh *em, int layer, int *free))[3]
|
2010-03-30 13:49:07 +02:00
|
|
|
{
|
2012-05-12 21:18:02 +02:00
|
|
|
*free = 0;
|
2010-03-30 13:49:07 +02:00
|
|
|
|
2012-03-24 07:18:31 +01:00
|
|
|
if (layer == CD_ORCO) {
|
2010-03-30 13:49:07 +02:00
|
|
|
/* get original coordinates */
|
2012-05-12 21:18:02 +02:00
|
|
|
*free = 1;
|
2010-03-30 13:49:07 +02:00
|
|
|
|
2019-04-22 01:39:35 +02:00
|
|
|
if (em) {
|
2012-12-21 08:28:14 +01:00
|
|
|
return get_editbmesh_orco_verts(em);
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
2020-07-03 18:04:40 +02:00
|
|
|
return BKE_mesh_orco_verts_get(ob);
|
2010-03-30 13:49:07 +02:00
|
|
|
}
|
2020-07-03 18:04:40 +02:00
|
|
|
if (layer == CD_CLOTH_ORCO) {
|
2010-03-30 13:49:07 +02:00
|
|
|
/* apply shape key for cloth, this should really be solved
|
2012-03-09 19:28:30 +01:00
|
|
|
* by a more flexible customdata system, but not simple */
|
2012-03-24 07:18:31 +01:00
|
|
|
if (!em) {
|
2020-05-08 11:02:03 +02:00
|
|
|
ClothModifierData *clmd = (ClothModifierData *)BKE_modifiers_findby_type(
|
|
|
|
ob, eModifierType_Cloth);
|
2021-05-12 23:14:58 +02:00
|
|
|
if (clmd) {
|
|
|
|
KeyBlock *kb = BKE_keyblock_from_key(BKE_key_from_object(ob),
|
|
|
|
clmd->sim_parms->shapekey_rest);
|
2011-12-05 00:13:28 +01:00
|
|
|
|
2021-05-12 23:14:58 +02:00
|
|
|
if (kb && kb->data) {
|
|
|
|
return (float(*)[3])kb->data;
|
|
|
|
}
|
2015-04-13 07:54:37 +02:00
|
|
|
}
|
2010-03-30 13:49:07 +02:00
|
|
|
}
|
|
|
|
|
2020-12-14 13:00:28 +01:00
|
|
|
return nullptr;
|
2010-03-30 13:49:07 +02:00
|
|
|
}
|
|
|
|
|
2020-12-14 13:00:28 +01:00
|
|
|
return nullptr;
|
2010-03-30 13:49:07 +02:00
|
|
|
}
|
|
|
|
|
2018-05-11 09:53:52 +02:00
|
|
|
static Mesh *create_orco_mesh(Object *ob, Mesh *me, BMEditMesh *em, int layer)
|
|
|
|
{
|
|
|
|
Mesh *mesh;
|
|
|
|
float(*orco)[3];
|
|
|
|
int free;
|
|
|
|
|
|
|
|
if (em) {
|
2020-12-14 13:00:28 +01:00
|
|
|
mesh = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, nullptr, me);
|
Mesh: Avoid creating incorrect original index layers
Currently, whenever any BMesh is converted to a Mesh (except for edit
mode switching), original index (`CD_ORIGINDEX`) layers are added.
This is incorrect, because many operations just convert some Mesh into
a BMesh and then back, but they shouldn't make any assumption about
where their input mesh came from. It might even come from a primitive
in geometry nodes, where there are no original indices at all.
Conceptually, mesh original indices should be filled by the modifier
stack when first creating the evaluated mesh. So that's where they're
moved in this patch. A separate function now fills the indices with their
default (0,1,2,3...) values. The way the mesh wrapper system defers
the BMesh to Mesh conversion makes this a bit less obvious though.
The old behavior is incorrect, but it's also slower, because three
arrays the size of the mesh's vertices, edges, and faces had to be
allocated and filled during the BMesh to Mesh conversion, which just
ends up putting more pressure on the cache. In the many cases where
original indices aren't used, I measured an **8% speedup** for the
conversion (from 76.5ms to 70.7ms).
Generally there is an assumption that BMesh is "original" and Mesh is
"evaluated". After this patch, that assumption isn't quite as strong,
but it still exists for two reasons. First, original indices are added
whenever converting a BMesh "wrapper" to a Mesh. Second, original
indices are not added to the BMesh at the beginning of evaluation,
which assumes that every BMesh in the viewport is original and doesn't
need the mapping.
Differential Revision: https://developer.blender.org/D14018
2022-02-18 17:51:00 +01:00
|
|
|
BKE_mesh_ensure_default_orig_index_customdata(mesh);
|
2018-05-11 09:53:52 +02:00
|
|
|
}
|
|
|
|
else {
|
2018-09-20 12:33:45 +02:00
|
|
|
mesh = BKE_mesh_copy_for_eval(me, true);
|
2018-05-11 09:53:52 +02:00
|
|
|
}
|
|
|
|
|
2018-10-09 06:04:51 +02:00
|
|
|
orco = get_orco_coords(ob, em, layer, &free);
|
2018-05-11 09:53:52 +02:00
|
|
|
|
|
|
|
if (orco) {
|
2019-08-21 22:28:35 +02:00
|
|
|
BKE_mesh_vert_coords_apply(mesh, orco);
|
2019-04-22 01:39:35 +02:00
|
|
|
if (free) {
|
2018-05-11 09:53:52 +02:00
|
|
|
MEM_freeN(orco);
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
2018-05-11 09:53:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return mesh;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void add_orco_mesh(Object *ob, BMEditMesh *em, Mesh *mesh, Mesh *mesh_orco, int layer)
|
|
|
|
{
|
|
|
|
float(*orco)[3], (*layerorco)[3];
|
|
|
|
int totvert, free;
|
|
|
|
|
|
|
|
totvert = mesh->totvert;
|
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
if (mesh_orco) {
|
2018-05-11 09:53:52 +02:00
|
|
|
free = 1;
|
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
if (mesh_orco->totvert == totvert) {
|
2020-12-14 13:00:28 +01:00
|
|
|
orco = BKE_mesh_vert_coords_alloc(mesh_orco, nullptr);
|
2018-05-11 09:53:52 +02:00
|
|
|
}
|
|
|
|
else {
|
2020-12-14 13:00:28 +01:00
|
|
|
orco = BKE_mesh_vert_coords_alloc(mesh, nullptr);
|
2018-05-11 09:53:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* TODO(sybren): totvert should potentially change here, as ob->data
|
|
|
|
* or em may have a different number of vertices than dm. */
|
2018-10-09 06:04:51 +02:00
|
|
|
orco = get_orco_coords(ob, em, layer, &free);
|
2018-05-11 09:53:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (orco) {
|
|
|
|
if (layer == CD_ORCO) {
|
2020-12-14 13:00:28 +01:00
|
|
|
BKE_mesh_orco_verts_transform((Mesh *)ob->data, orco, totvert, 0);
|
2018-05-11 09:53:52 +02:00
|
|
|
}
|
|
|
|
|
2020-12-14 13:00:28 +01:00
|
|
|
if (!(layerorco = (float(*)[3])CustomData_get_layer(&mesh->vdata, layer))) {
|
|
|
|
CustomData_add_layer(&mesh->vdata, layer, CD_CALLOC, nullptr, mesh->totvert);
|
2018-05-11 09:53:52 +02:00
|
|
|
BKE_mesh_update_customdata_pointers(mesh, false);
|
|
|
|
|
2020-12-14 13:00:28 +01:00
|
|
|
layerorco = (float(*)[3])CustomData_get_layer(&mesh->vdata, layer);
|
2018-05-11 09:53:52 +02:00
|
|
|
}
|
|
|
|
|
2020-08-08 05:29:21 +02:00
|
|
|
memcpy(layerorco, orco, sizeof(float[3]) * totvert);
|
2019-04-22 01:39:35 +02:00
|
|
|
if (free) {
|
2018-05-11 09:53:52 +02:00
|
|
|
MEM_freeN(orco);
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
2018-05-11 09:53:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-06 20:29:28 +02:00
|
|
|
static bool mesh_has_modifier_final_normals(const Mesh *mesh_input,
|
|
|
|
const CustomData_MeshMasks *final_datamask,
|
|
|
|
Mesh *mesh_final)
|
|
|
|
{
|
|
|
|
/* Test if mesh has the required loop normals, in case an additional modifier
|
|
|
|
* evaluation from another instance or from an operator requests it but the
|
|
|
|
* initial normals were not loop normals. */
|
|
|
|
const bool do_loop_normals = ((mesh_input->flag & ME_AUTOSMOOTH) != 0 ||
|
|
|
|
(final_datamask->lmask & CD_MASK_NORMAL) != 0);
|
|
|
|
|
|
|
|
return (!do_loop_normals || CustomData_has_layer(&mesh_final->ldata, CD_NORMAL));
|
|
|
|
}
|
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
static void mesh_calc_modifier_final_normals(const Mesh *mesh_input,
|
2019-06-10 15:42:15 +02:00
|
|
|
const CustomData_MeshMasks *final_datamask,
|
2019-03-28 11:42:53 +01:00
|
|
|
const bool sculpt_dyntopo,
|
2019-03-29 21:13:55 +01:00
|
|
|
Mesh *mesh_final)
|
2019-03-28 11:42:53 +01:00
|
|
|
{
|
|
|
|
/* Compute normals. */
|
|
|
|
const bool do_loop_normals = ((mesh_input->flag & ME_AUTOSMOOTH) != 0 ||
|
2019-06-10 15:42:15 +02:00
|
|
|
(final_datamask->lmask & CD_MASK_NORMAL) != 0);
|
2019-08-05 18:04:40 +02:00
|
|
|
|
|
|
|
if (do_loop_normals) {
|
2021-07-03 15:08:40 +02:00
|
|
|
/* Compute loop normals (NOTE: will compute poly and vert normals as well, if needed!). */
|
2019-03-28 11:42:53 +01:00
|
|
|
BKE_mesh_calc_normals_split(mesh_final);
|
|
|
|
}
|
2022-04-06 20:02:04 +02:00
|
|
|
else {
|
|
|
|
if (sculpt_dyntopo == false) {
|
|
|
|
/* without this, drawing ngon tri's faces will show ugly tessellated face
|
|
|
|
* normals and will also have to calculate normals on the fly, try avoid
|
|
|
|
* this where possible since calculating polygon normals isn't fast,
|
|
|
|
* note that this isn't a problem for subsurf (only quads) or editmode
|
|
|
|
* which deals with drawing differently. */
|
2019-03-28 11:42:53 +01:00
|
|
|
BKE_mesh_ensure_normals_for_display(mesh_final);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
2022-04-06 20:02:04 +02:00
|
|
|
/* Some modifiers, like data-transfer, may generate those data as temp layer,
|
|
|
|
* we do not want to keep them, as they are used by display code when available
|
|
|
|
* (i.e. even if autosmooth is disabled). */
|
|
|
|
if (CustomData_has_layer(&mesh_final->ldata, CD_NORMAL)) {
|
|
|
|
CustomData_free_layers(&mesh_final->ldata, CD_NORMAL, mesh_final->totloop);
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-03-28 11:42:53 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-27 11:45:33 +02:00
|
|
|
/* Does final touches to the final evaluated mesh, making sure it is perfectly usable.
|
|
|
|
*
|
|
|
|
* This is needed because certain information is not passed along intermediate meshes allocated
|
|
|
|
* during stack evaluation.
|
|
|
|
*/
|
|
|
|
static void mesh_calc_finalize(const Mesh *mesh_input, Mesh *mesh_eval)
|
|
|
|
{
|
|
|
|
/* Make sure the name is the same. This is because mesh allocation from template does not
|
|
|
|
* take care of naming. */
|
|
|
|
BLI_strncpy(mesh_eval->id.name, mesh_input->id.name, sizeof(mesh_eval->id.name));
|
|
|
|
/* Make evaluated mesh to share same edit mesh pointer as original and copied meshes. */
|
|
|
|
mesh_eval->edit_mesh = mesh_input->edit_mesh;
|
|
|
|
}
|
|
|
|
|
2020-05-25 12:16:42 +02:00
|
|
|
void BKE_mesh_wrapper_deferred_finalize(Mesh *me_eval,
|
|
|
|
const CustomData_MeshMasks *cd_mask_finalize)
|
|
|
|
{
|
|
|
|
if (me_eval->runtime.wrapper_type_finalize & (1 << ME_WRAPPER_TYPE_BMESH)) {
|
|
|
|
editbmesh_calc_modifier_final_normals(me_eval, cd_mask_finalize);
|
|
|
|
me_eval->runtime.wrapper_type_finalize &= ~(1 << ME_WRAPPER_TYPE_BMESH);
|
|
|
|
}
|
|
|
|
BLI_assert(me_eval->runtime.wrapper_type_finalize == 0);
|
|
|
|
}
|
|
|
|
|
2020-12-15 12:42:10 +01:00
|
|
|
/**
|
2021-02-02 16:20:54 +01:00
|
|
|
* Modifies the given mesh and geometry set. The mesh is not passed as part of the mesh component
|
|
|
|
* in the \a geometry_set input, it is only passed in \a input_mesh and returned in the return
|
|
|
|
* value.
|
2020-12-15 12:42:10 +01:00
|
|
|
*
|
2021-02-02 16:20:54 +01:00
|
|
|
* The purpose of the geometry set is to store all geometry components that are generated
|
|
|
|
* by modifiers to allow outputting non-mesh data from modifiers.
|
2020-12-15 12:42:10 +01:00
|
|
|
*/
|
|
|
|
static Mesh *modifier_modify_mesh_and_geometry_set(ModifierData *md,
|
|
|
|
const ModifierEvalContext &mectx,
|
|
|
|
Mesh *input_mesh,
|
|
|
|
GeometrySet &geometry_set)
|
|
|
|
{
|
|
|
|
Mesh *mesh_output = nullptr;
|
|
|
|
const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type);
|
|
|
|
if (mti->modifyGeometrySet == nullptr) {
|
2021-10-19 15:39:10 +02:00
|
|
|
mesh_output = BKE_modifier_modify_mesh(md, &mectx, input_mesh);
|
2020-12-15 12:42:10 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* For performance reasons, this should be called by the modifier and/or nodes themselves at
|
|
|
|
* some point. */
|
|
|
|
BKE_mesh_wrapper_ensure_mdata(input_mesh);
|
|
|
|
|
|
|
|
/* Adds a new mesh component to the geometry set based on the #input_mesh. */
|
|
|
|
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
|
2021-02-02 16:20:54 +01:00
|
|
|
/* Replace only the mesh rather than the whole component, because the entire #MeshComponent
|
|
|
|
* might have been replaced by data from a different object in the node tree, which means the
|
|
|
|
* component contains vertex group name data for that object that should not be removed. */
|
2021-07-13 18:10:34 +02:00
|
|
|
mesh_component.replace(input_mesh, GeometryOwnershipType::Editable);
|
2020-12-15 12:42:10 +01:00
|
|
|
|
|
|
|
/* Let the modifier change the geometry set. */
|
|
|
|
mti->modifyGeometrySet(md, &mectx, &geometry_set);
|
|
|
|
|
|
|
|
/* Release the mesh from the geometry set again. */
|
|
|
|
if (geometry_set.has<MeshComponent>()) {
|
|
|
|
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
|
2021-11-03 10:42:48 +01:00
|
|
|
if (mesh_component.get_for_read() != input_mesh) {
|
|
|
|
/* Make sure the mesh component actually owns the mesh before taking over ownership. */
|
|
|
|
mesh_component.ensure_owns_direct_data();
|
|
|
|
}
|
2020-12-15 12:42:10 +01:00
|
|
|
mesh_output = mesh_component.release();
|
|
|
|
}
|
|
|
|
|
2021-06-24 07:56:58 +02:00
|
|
|
/* Return an empty mesh instead of null. */
|
2020-12-15 12:42:10 +01:00
|
|
|
if (mesh_output == nullptr) {
|
|
|
|
mesh_output = BKE_mesh_new_nomain(0, 0, 0, 0, 0);
|
2021-06-17 06:56:39 +02:00
|
|
|
BKE_mesh_copy_parameters_for_eval(mesh_output, input_mesh);
|
2020-12-15 12:42:10 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return mesh_output;
|
|
|
|
}
|
|
|
|
|
2015-07-02 08:20:22 +02:00
|
|
|
static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
|
2022-02-14 19:05:54 +01:00
|
|
|
const Scene *scene,
|
2019-03-27 19:07:16 +01:00
|
|
|
Object *ob,
|
2021-06-30 23:41:53 +02:00
|
|
|
const bool use_deform,
|
2019-03-27 19:07:16 +01:00
|
|
|
const bool need_mapping,
|
|
|
|
const CustomData_MeshMasks *dataMask,
|
|
|
|
const int index,
|
2019-03-28 11:42:53 +01:00
|
|
|
const bool use_cache,
|
2019-05-31 10:05:56 +02:00
|
|
|
const bool allow_shared_mesh,
|
2015-07-02 08:20:22 +02:00
|
|
|
/* return args */
|
2019-03-27 19:07:16 +01:00
|
|
|
Mesh **r_deform,
|
2020-12-15 12:42:10 +01:00
|
|
|
Mesh **r_final,
|
|
|
|
GeometrySet **r_geometry_set)
|
2005-03-27 22:34:18 +02:00
|
|
|
{
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Input and final mesh. Final mesh is only created the moment the first
|
|
|
|
* constructive modifier is executed, or a deform modifier needs normals
|
|
|
|
* or certain data layers. */
|
2020-12-14 13:00:28 +01:00
|
|
|
Mesh *mesh_input = (Mesh *)ob->data;
|
Refactor: Move normals out of MVert, lazy calculation
As described in T91186, this commit moves mesh vertex normals into a
contiguous array of float vectors in a custom data layer, how face
normals are currently stored.
The main interface is documented in `BKE_mesh.h`. Vertex and face
normals are now calculated on-demand and cached, retrieved with an
"ensure" function. Since the logical state of a mesh is now "has
normals when necessary", they can be retrieved from a `const` mesh.
The goal is to use on-demand calculation for all derived data, but
leave room for eager calculation for performance purposes (modifier
evaluation is threaded, but viewport data generation is not).
**Benefits**
This moves us closer to a SoA approach rather than the current AoS
paradigm. Accessing a contiguous `float3` is much more efficient than
retrieving data from a larger struct. The memory requirements for
accessing only normals or vertex locations are smaller, and at the
cost of more memory usage for just normals, they now don't have to
be converted between float and short, which also simplifies code
In the future, the remaining items can be removed from `MVert`,
leaving only `float3`, which has similar benefits (see T93602).
Removing the combination of derived and original data makes it
conceptually simpler to only calculate normals when necessary.
This is especially important now that we have more opportunities
for temporary meshes in geometry nodes.
**Performance**
In addition to the theoretical future performance improvements by
making `MVert == float3`, I've done some basic performance testing
on this patch directly. The data is fairly rough, but it gives an idea
about where things stand generally.
- Mesh line primitive 4m Verts: 1.16x faster (36 -> 31 ms),
showing that accessing just `MVert` is now more efficient.
- Spring Splash Screen: 1.03-1.06 -> 1.06-1.11 FPS, a very slight
change that at least shows there is no regression.
- Sprite Fright Snail Smoosh: 3.30-3.40 -> 3.42-3.50 FPS, a small
but observable speedup.
- Set Position Node with Scaled Normal: 1.36x faster (53 -> 39 ms),
shows that using normals in geometry nodes is faster.
- Normal Calculation 1.6m Vert Cube: 1.19x faster (25 -> 21 ms),
shows that calculating normals is slightly faster now.
- File Size of 1.6m Vert Cube: 1.03x smaller (214.7 -> 208.4 MB),
Normals are not saved in files, which can help with large meshes.
As for memory usage, it may be slightly more in some cases, but
I didn't observe any difference in the production files I tested.
**Tests**
Some modifiers and cycles test results need to be updated with this
commit, for two reasons:
- The subdivision surface modifier is not responsible for calculating
normals anymore. In master, the modifier creates different normals
than the result of the `Mesh` normal calculation, so this is a bug
fix.
- There are small differences in the results of some modifiers that
use normals because they are not converted to and from `short`
anymore.
**Future improvements**
- Remove `ModifierTypeInfo::dependsOnNormals`. Code in each modifier
already retrieves normals if they are needed anyway.
- Copy normals as part of a better CoW system for attributes.
- Make more areas use lazy instead of eager normal calculation.
- Remove `BKE_mesh_normals_tag_dirty` in more places since that is
now the default state of a new mesh.
- Possibly apply a similar change to derived face corner normals.
Differential Revision: https://developer.blender.org/D12770
2022-01-13 21:37:58 +01:00
|
|
|
BKE_mesh_assert_normals_dirty_or_calculated(mesh_input);
|
2020-12-14 13:00:28 +01:00
|
|
|
Mesh *mesh_final = nullptr;
|
|
|
|
Mesh *mesh_deform = nullptr;
|
2020-12-15 12:42:10 +01:00
|
|
|
/* This geometry set contains the non-mesh data that might be generated by modifiers. */
|
|
|
|
GeometrySet geometry_set_final;
|
2021-02-02 16:20:54 +01:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
BLI_assert((mesh_input->id.tag & LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT) == 0);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Deformed vertex locations array. Deform only modifier need this type of
|
|
|
|
* float array rather than MVert*. Tracked along with mesh_final as an
|
|
|
|
* optimization to avoid copying coordinates back and forth if there are
|
|
|
|
* multiple sequential deform only modifiers. */
|
2020-12-14 13:00:28 +01:00
|
|
|
float(*deformed_verts)[3] = nullptr;
|
2019-03-28 11:42:53 +01:00
|
|
|
int num_deformed_verts = mesh_input->totvert;
|
2014-01-27 17:52:21 +01:00
|
|
|
bool isPrevDeform = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Mesh with constructive modifiers but no deformation applied. Tracked
|
|
|
|
* along with final mesh if undeformed / orco coordinates are requested
|
|
|
|
* for texturing. */
|
2020-12-14 13:00:28 +01:00
|
|
|
Mesh *mesh_orco = nullptr;
|
|
|
|
Mesh *mesh_orco_cloth = nullptr;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Modifier evaluation modes. */
|
|
|
|
const bool use_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
|
|
|
|
const int required_mode = use_render ? eModifierMode_Render : eModifierMode_Realtime;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Sculpt can skip certain modifiers. */
|
2020-12-14 13:00:28 +01:00
|
|
|
const bool has_multires = BKE_sculpt_multires_active(scene, ob) != nullptr;
|
2014-01-27 17:52:21 +01:00
|
|
|
bool multires_applied = false;
|
2019-03-28 11:42:53 +01:00
|
|
|
const bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt && !use_render;
|
|
|
|
const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm) && !use_render;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Modifier evaluation contexts for different types of modifiers. */
|
2020-12-14 13:00:28 +01:00
|
|
|
ModifierApplyFlag apply_render = use_render ? MOD_APPLY_RENDER : (ModifierApplyFlag)0;
|
|
|
|
ModifierApplyFlag apply_cache = use_cache ? MOD_APPLY_USECACHE : (ModifierApplyFlag)0;
|
|
|
|
const ModifierEvalContext mectx = {
|
|
|
|
depsgraph, ob, (ModifierApplyFlag)(apply_render | apply_cache)};
|
|
|
|
const ModifierEvalContext mectx_orco = {
|
|
|
|
depsgraph, ob, (ModifierApplyFlag)(apply_render | MOD_APPLY_ORCO)};
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Get effective list of modifiers to execute. Some effects like shape keys
|
|
|
|
* are added as virtual modifiers before the user created modifiers. */
|
2013-08-19 11:05:34 +02:00
|
|
|
VirtualModifierData virtualModifierData;
|
2020-05-08 10:14:02 +02:00
|
|
|
ModifierData *firstmd = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
|
2019-03-28 11:42:53 +01:00
|
|
|
ModifierData *md = firstmd;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Preview colors by modifiers such as dynamic paint, to show the results
|
|
|
|
* even if the resulting data is not used in a material. Only in object mode.
|
|
|
|
* TODO: this is broken, not drawn by the drawn manager. */
|
|
|
|
const bool do_mod_mcol = (ob->mode == OB_MODE_OBJECT);
|
2020-12-14 13:00:28 +01:00
|
|
|
ModifierData *previewmd = nullptr;
|
2019-03-28 11:42:53 +01:00
|
|
|
CustomData_MeshMasks previewmask = {0};
|
2018-09-30 17:07:38 +02:00
|
|
|
if (do_mod_mcol) {
|
2020-12-14 13:00:28 +01:00
|
|
|
/* Find the last active modifier generating a preview, or nullptr if none. */
|
Add weight preview to WeightVG modifiers, and first, simple/basic refactor of how modifiers can generate preview.
User side:
* Preview for DynamicPaint should keep the same behavior (for now). Weight preview should be somawhat quicker, though.
* Preview for WeightVG modifiers is only active in WeightPaint mode, and if the affected vgroup is the active one.
* Last active preview modifier in stack wins!
Note: that modifier preview topic is yet to be further refined, quite raw/incomplete for now.
Dev side:
* In draw code, renamed DRAW_DYNAMIC_PAINT_PREVIEW flag to DRAW_MODIFIERS_PREVIEW
* Removed use of MOD_DPAINT_PREVIEW_READY in DynamicPaint code (seems unecessary, and if it was, should be of more general scope).
* Added eModifierTypeFlag_UsesPreview to ModifierTypeFlag, for modifiers that can generate some preview data.
* Added three new modifier funcs, to handle preview modifiers in draw code / mod stack.
* For weights preview: added the generic DM_update_weight_mcol func, which can update WEIGHT_MCOL layer with either a given array of weights (currently used by DynamicPaint only), or from current active vgroup(s).
So now, draw code is fully generic (i.e. no more modifier-type checking in it). Mod stack code is generic to some extent, but will need more work.
2012-01-22 18:54:23 +01:00
|
|
|
/* XXX Currently, DPaint modifier just ignores this.
|
|
|
|
* Needs a stupid hack...
|
|
|
|
* The whole "modifier preview" thing has to be (re?)designed, anyway! */
|
2020-05-08 10:14:02 +02:00
|
|
|
previewmd = BKE_modifier_get_last_preview(scene, md, required_mode);
|
Add weight preview to WeightVG modifiers, and first, simple/basic refactor of how modifiers can generate preview.
User side:
* Preview for DynamicPaint should keep the same behavior (for now). Weight preview should be somawhat quicker, though.
* Preview for WeightVG modifiers is only active in WeightPaint mode, and if the affected vgroup is the active one.
* Last active preview modifier in stack wins!
Note: that modifier preview topic is yet to be further refined, quite raw/incomplete for now.
Dev side:
* In draw code, renamed DRAW_DYNAMIC_PAINT_PREVIEW flag to DRAW_MODIFIERS_PREVIEW
* Removed use of MOD_DPAINT_PREVIEW_READY in DynamicPaint code (seems unecessary, and if it was, should be of more general scope).
* Added eModifierTypeFlag_UsesPreview to ModifierTypeFlag, for modifiers that can generate some preview data.
* Added three new modifier funcs, to handle preview modifiers in draw code / mod stack.
* For weights preview: added the generic DM_update_weight_mcol func, which can update WEIGHT_MCOL layer with either a given array of weights (currently used by DynamicPaint only), or from current active vgroup(s).
So now, draw code is fully generic (i.e. no more modifier-type checking in it). Mod stack code is generic to some extent, but will need more work.
2012-01-22 18:54:23 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Compute accumulated datamasks needed by each modifier. It helps to do
|
|
|
|
* this fine grained so that for example vertex groups are preserved up to
|
|
|
|
* an armature modifier, but not through a following subsurf modifier where
|
|
|
|
* subdividing them is expensive. */
|
2019-06-10 15:42:15 +02:00
|
|
|
CustomData_MeshMasks final_datamask = *dataMask;
|
2020-05-08 10:14:02 +02:00
|
|
|
CDMaskLink *datamasks = BKE_modifier_calc_data_masks(
|
2019-06-10 15:42:15 +02:00
|
|
|
scene, ob, md, &final_datamask, required_mode, previewmd, &previewmask);
|
2019-03-28 11:42:53 +01:00
|
|
|
CDMaskLink *md_datamask = datamasks;
|
|
|
|
/* XXX Always copying POLYINDEX, else tessellated data are no more valid! */
|
|
|
|
CustomData_MeshMasks append_mask = CD_MASK_BAREMESH_ORIGINDEX;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Clear errors before evaluation. */
|
2020-05-08 10:14:02 +02:00
|
|
|
BKE_modifiers_clear_errors(ob);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Apply all leading deform modifiers. */
|
2021-06-30 23:41:53 +02:00
|
|
|
if (use_deform) {
|
2019-03-28 11:42:53 +01:00
|
|
|
for (; md; md = md->next, md_datamask = md_datamask->next) {
|
2020-12-14 13:00:28 +01: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)) {
|
2015-07-02 08:20:22 +02:00
|
|
|
continue;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-30 19:29:41 +01:00
|
|
|
if (mti->type == eModifierTypeType_OnlyDeform && !sculpt_dyntopo) {
|
2019-03-28 11:42:53 +01:00
|
|
|
if (!deformed_verts) {
|
2019-08-21 22:28:35 +02:00
|
|
|
deformed_verts = BKE_mesh_vert_coords_alloc(mesh_input, &num_deformed_verts);
|
2019-03-18 15:37:46 +01:00
|
|
|
}
|
2019-03-28 11:42:53 +01:00
|
|
|
else if (isPrevDeform && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
|
2020-12-14 13:00:28 +01:00
|
|
|
if (mesh_final == nullptr) {
|
2019-03-28 11:42:53 +01:00
|
|
|
mesh_final = BKE_mesh_copy_for_eval(mesh_input, true);
|
|
|
|
ASSERT_IS_VALID_MESH(mesh_final);
|
2019-03-18 15:37:46 +01:00
|
|
|
}
|
2019-08-21 22:28:35 +02:00
|
|
|
BKE_mesh_vert_coords_apply(mesh_final, deformed_verts);
|
2019-03-18 15:37:46 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-05-08 10:14:02 +02:00
|
|
|
BKE_modifier_deform_verts(md, &mectx, mesh_final, deformed_verts, num_deformed_verts);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-18 15:37:46 +01:00
|
|
|
isPrevDeform = true;
|
2012-03-24 07:18:31 +01:00
|
|
|
}
|
|
|
|
else {
|
2005-07-19 22:14:17 +02:00
|
|
|
break;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2008-07-28 13:01:34 +02:00
|
|
|
/* grab modifiers until index i */
|
2019-04-22 01:39:35 +02:00
|
|
|
if ((index != -1) && (BLI_findindex(&ob->modifiers, md) >= index)) {
|
2020-12-14 13:00:28 +01:00
|
|
|
md = nullptr;
|
2008-07-28 13:01:34 +02:00
|
|
|
break;
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
2005-07-19 22:14:17 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2006-08-28 03:12:36 +02:00
|
|
|
/* Result of all leading deforming modifiers is cached for
|
|
|
|
* places that wish to use the original mesh but with deformed
|
2019-03-28 11:42:53 +01:00
|
|
|
* coordinates (like vertex paint). */
|
2018-10-10 06:00:37 +02:00
|
|
|
if (r_deform) {
|
2019-03-28 11:42:53 +01:00
|
|
|
mesh_deform = BKE_mesh_copy_for_eval(mesh_input, true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
if (deformed_verts) {
|
2019-08-21 22:28:35 +02:00
|
|
|
BKE_mesh_vert_coords_apply(mesh_deform, deformed_verts);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
}
|
2006-09-07 08:44:25 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Apply all remaining constructive and deforming modifiers. */
|
2019-11-13 11:29:19 +01:00
|
|
|
bool have_non_onlydeform_modifiers_appled = false;
|
2019-03-28 11:42:53 +01:00
|
|
|
for (; md; md = md->next, md_datamask = md_datamask->next) {
|
2020-12-14 13:00:28 +01: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)) {
|
2015-07-02 08:20:22 +02:00
|
|
|
continue;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-06-30 23:41:53 +02:00
|
|
|
if (mti->type == eModifierTypeType_OnlyDeform && !use_deform) {
|
2015-07-02 08:20:22 +02:00
|
|
|
continue;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-11-13 11:29:19 +01:00
|
|
|
if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) &&
|
|
|
|
have_non_onlydeform_modifiers_appled) {
|
2020-10-26 07:07:58 +01:00
|
|
|
BKE_modifier_set_error(ob, md, "Modifier requires original data, bad stack position");
|
- added eModifierTypeFlag_RequiresOriginalData for modifiers that
can only follow deform (for example, they store mesh vertex
indices)
- added ModifierType.foreachObjectLink for iterating over Object
links inside modifier data (used for file load, relinking, etc)
- switched various modifiers_ functions to take object argument
instead of ListBase
- added user editable name field to modifiers
- bug fix, duplicate and make single user didn't relink object
pointers in modifier data
- added modifiers to outliner, needs icon
- added armature, hook, and softbody modifiers (softbody doesn't
do anything atm). added conversion of old hooks to modifiers.
NOTE-THE-FIRST: User name field is not initialized on loading 2.38 files
so if you have saved stuff with a cvs blender you will see blank names.
NOTE-THE-SECOND: Since modifiers aren't evaluated yet for non-Mesh
objects, hooks for lattices and curves are broken. Don't updated if
you actually, say, *use* Blender.
NOTE-THE-THIRD: Old hooks used a quirky weighting system during
deformation which can't be extended to modifiers. On the upside,
I doubt anyone relied on the old quirky system and the new system
makes much more sense. (Although the way falloff works is still
quite stupid I think).
2005-08-11 00:05:52 +02:00
|
|
|
continue;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-05-09 10:29:21 +02:00
|
|
|
if (sculpt_mode && (!has_multires || multires_applied || sculpt_dyntopo)) {
|
2014-01-27 17:52:21 +01:00
|
|
|
bool unsupported = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-30 15:41:45 +02:00
|
|
|
if (md->type == eModifierType_Multires && ((MultiresModifierData *)md)->sculptlvl == 0) {
|
2013-06-03 10:26:12 +02:00
|
|
|
/* If multires is on level 0 skip it silently without warning message. */
|
2015-07-02 08:20:22 +02:00
|
|
|
if (!sculpt_dyntopo) {
|
2014-05-08 18:25:46 +02:00
|
|
|
continue;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2015-07-02 08:20:22 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 01:39:35 +02:00
|
|
|
if (sculpt_dyntopo) {
|
2014-01-27 17:52:21 +01:00
|
|
|
unsupported = true;
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 01:39:35 +02:00
|
|
|
if (scene->toolsettings->sculpt->flags & SCULPT_ONLY_DEFORM) {
|
2014-01-27 17:52:21 +01:00
|
|
|
unsupported |= (mti->type != eModifierTypeType_OnlyDeform);
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-12 21:18:02 +02:00
|
|
|
unsupported |= multires_applied;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 07:18:31 +01:00
|
|
|
if (unsupported) {
|
2019-04-22 01:39:35 +02:00
|
|
|
if (sculpt_dyntopo) {
|
2020-10-26 07:07:58 +01:00
|
|
|
BKE_modifier_set_error(ob, md, "Not supported in dyntopo");
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
|
|
|
else {
|
2020-10-26 07:07:58 +01:00
|
|
|
BKE_modifier_set_error(ob, md, "Not supported in sculpt mode");
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
2011-01-31 21:02:51 +01:00
|
|
|
continue;
|
|
|
|
}
|
2014-05-08 18:15:36 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-05-08 10:14:02 +02:00
|
|
|
if (need_mapping && !BKE_modifier_supports_mapping(md)) {
|
2015-07-02 08:20:22 +02:00
|
|
|
continue;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-06-10 15:42:15 +02:00
|
|
|
/* Add orco mesh as layer if needed by this modifier. */
|
|
|
|
if (mesh_final && mesh_orco && mti->requiredDataMask) {
|
2019-03-28 11:42:53 +01:00
|
|
|
CustomData_MeshMasks mask = {0};
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
mti->requiredDataMask(ob, md, &mask);
|
2019-03-28 11:42:53 +01:00
|
|
|
if (mask.vmask & CD_MASK_ORCO) {
|
2020-12-14 13:00:28 +01:00
|
|
|
add_orco_mesh(ob, nullptr, mesh_final, mesh_orco, CD_ORCO);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-03-28 11:42:53 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2006-08-28 03:12:36 +02:00
|
|
|
/* How to apply modifier depends on (a) what we already have as
|
2018-05-11 09:53:52 +02:00
|
|
|
* a result of previous modifiers (could be a Mesh or just
|
2019-03-28 11:42:53 +01:00
|
|
|
* deformed vertices) and (b) what type the modifier is. */
|
2012-03-24 07:18:31 +01:00
|
|
|
if (mti->type == eModifierTypeType_OnlyDeform) {
|
2006-08-28 03:12:36 +02:00
|
|
|
/* No existing verts to deform, need to build them. */
|
2019-03-28 11:42:53 +01:00
|
|
|
if (!deformed_verts) {
|
|
|
|
if (mesh_final) {
|
2018-05-11 09:53:52 +02:00
|
|
|
/* Deforming a mesh, read the vertex locations
|
2006-08-28 03:12:36 +02:00
|
|
|
* out of the mesh and deform them. Once done with this
|
2019-03-28 11:42:53 +01:00
|
|
|
* run of deformers verts will be written back. */
|
2019-08-21 22:28:35 +02:00
|
|
|
deformed_verts = BKE_mesh_vert_coords_alloc(mesh_final, &num_deformed_verts);
|
2012-03-24 07:18:31 +01:00
|
|
|
}
|
|
|
|
else {
|
2019-08-21 22:28:35 +02:00
|
|
|
deformed_verts = BKE_mesh_vert_coords_alloc(mesh_input, &num_deformed_verts);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2005-07-19 22:14:17 +02:00
|
|
|
}
|
2010-09-30 12:51:36 +02:00
|
|
|
/* if this is not the last modifier in the stack then recalculate the normals
|
2020-09-30 12:09:02 +02:00
|
|
|
* to avoid giving bogus normals to the next modifier see: T23673. */
|
2019-03-28 11:42:53 +01:00
|
|
|
else if (isPrevDeform && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
|
2020-12-14 13:00:28 +01:00
|
|
|
if (mesh_final == nullptr) {
|
2019-11-13 11:24:16 +01:00
|
|
|
mesh_final = BKE_mesh_copy_for_eval(mesh_input, true);
|
|
|
|
ASSERT_IS_VALID_MESH(mesh_final);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-11-13 11:24:16 +01:00
|
|
|
BKE_mesh_vert_coords_apply(mesh_final, deformed_verts);
|
2010-09-30 12:51:36 +02:00
|
|
|
}
|
2020-05-08 10:14:02 +02:00
|
|
|
BKE_modifier_deform_verts(md, &mectx, mesh_final, deformed_verts, num_deformed_verts);
|
2012-03-24 07:18:31 +01:00
|
|
|
}
|
|
|
|
else {
|
2020-09-23 07:09:53 +02:00
|
|
|
bool check_for_needs_mapping = false;
|
2018-05-11 09:53:52 +02:00
|
|
|
/* apply vertex coordinates or build a Mesh as necessary */
|
2020-12-14 13:00:28 +01:00
|
|
|
if (mesh_final != nullptr) {
|
2020-09-23 07:12:28 +02:00
|
|
|
if (have_non_onlydeform_modifiers_appled == false) {
|
|
|
|
/* If we only deformed, we won't have initialized #CD_ORIGINDEX.
|
|
|
|
* as this is the only part of the function that initializes mapping. */
|
|
|
|
check_for_needs_mapping = true;
|
|
|
|
}
|
2006-08-28 03:12:36 +02:00
|
|
|
}
|
2012-03-24 07:18:31 +01:00
|
|
|
else {
|
2019-03-28 11:42:53 +01:00
|
|
|
mesh_final = BKE_mesh_copy_for_eval(mesh_input, true);
|
|
|
|
ASSERT_IS_VALID_MESH(mesh_final);
|
2020-09-23 07:09:53 +02:00
|
|
|
check_for_needs_mapping = true;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-09-23 07:09:53 +02:00
|
|
|
if (deformed_verts) {
|
|
|
|
BKE_mesh_vert_coords_apply(mesh_final, deformed_verts);
|
|
|
|
}
|
|
|
|
|
|
|
|
have_non_onlydeform_modifiers_appled = true;
|
|
|
|
|
|
|
|
/* determine which data layers are needed by following modifiers */
|
|
|
|
CustomData_MeshMasks nextmask = md_datamask->next ? md_datamask->next->mask : final_datamask;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-09-23 07:09:53 +02:00
|
|
|
if (check_for_needs_mapping) {
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Initialize original indices the first time we evaluate a
|
|
|
|
* constructive modifier. Modifiers will then do mapping mostly
|
|
|
|
* automatic by copying them through CustomData_copy_data along
|
|
|
|
* with other data.
|
2010-10-21 03:08:12 +02:00
|
|
|
*
|
2019-03-28 11:42:53 +01:00
|
|
|
* These are created when either requested by evaluation, or if
|
|
|
|
* following modifiers requested them. */
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
if (need_mapping ||
|
|
|
|
((nextmask.vmask | nextmask.emask | nextmask.pmask) & CD_MASK_ORIGINDEX)) {
|
2010-10-21 03:08:12 +02:00
|
|
|
/* calc */
|
2019-03-28 11:42:53 +01:00
|
|
|
CustomData_add_layer(
|
2020-12-14 13:00:28 +01:00
|
|
|
&mesh_final->vdata, CD_ORIGINDEX, CD_CALLOC, nullptr, mesh_final->totvert);
|
2019-03-28 11:42:53 +01:00
|
|
|
CustomData_add_layer(
|
2020-12-14 13:00:28 +01:00
|
|
|
&mesh_final->edata, CD_ORIGINDEX, CD_CALLOC, nullptr, mesh_final->totedge);
|
2019-03-28 11:42:53 +01:00
|
|
|
CustomData_add_layer(
|
2020-12-14 13:00:28 +01:00
|
|
|
&mesh_final->pdata, CD_ORIGINDEX, CD_CALLOC, nullptr, mesh_final->totpoly);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-27 04:07:07 +02:00
|
|
|
/* Not worth parallelizing this,
|
|
|
|
* gives less than 0.1% overall speedup in best of best cases... */
|
2020-12-14 13:00:28 +01:00
|
|
|
range_vn_i((int *)CustomData_get_layer(&mesh_final->vdata, CD_ORIGINDEX),
|
|
|
|
mesh_final->totvert,
|
|
|
|
0);
|
|
|
|
range_vn_i((int *)CustomData_get_layer(&mesh_final->edata, CD_ORIGINDEX),
|
|
|
|
mesh_final->totedge,
|
|
|
|
0);
|
|
|
|
range_vn_i((int *)CustomData_get_layer(&mesh_final->pdata, CD_ORIGINDEX),
|
|
|
|
mesh_final->totpoly,
|
|
|
|
0);
|
2006-08-28 03:12:36 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
2018-05-11 09:53:52 +02:00
|
|
|
/* set the Mesh to only copy needed data */
|
2019-03-28 11:42:53 +01:00
|
|
|
CustomData_MeshMasks mask = md_datamask->mask;
|
2020-09-30 12:09:02 +02:00
|
|
|
/* needMapping check here fixes bug T28112, otherwise it's
|
2016-01-28 06:30:50 +01:00
|
|
|
* possible that it won't be copied */
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
CustomData_MeshMasks_update(&mask, &append_mask);
|
|
|
|
if (need_mapping) {
|
|
|
|
mask.vmask |= CD_MASK_ORIGINDEX;
|
|
|
|
mask.emask |= CD_MASK_ORIGINDEX;
|
|
|
|
mask.pmask |= CD_MASK_ORIGINDEX;
|
|
|
|
}
|
2019-03-28 11:42:53 +01:00
|
|
|
mesh_set_only_copy(mesh_final, &mask);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-01-28 06:30:50 +01:00
|
|
|
/* add cloth rest shape key if needed */
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
if (mask.vmask & CD_MASK_CLOTH_ORCO) {
|
2020-12-14 13:00:28 +01:00
|
|
|
add_orco_mesh(ob, nullptr, mesh_final, mesh_orco, CD_CLOTH_ORCO);
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2007-12-05 13:40:54 +01:00
|
|
|
/* add an origspace layer if needed */
|
2019-03-28 11:42:53 +01:00
|
|
|
if ((md_datamask->mask.lmask) & CD_MASK_ORIGSPACE_MLOOP) {
|
|
|
|
if (!CustomData_has_layer(&mesh_final->ldata, CD_ORIGSPACE_MLOOP)) {
|
|
|
|
CustomData_add_layer(
|
2020-12-14 13:00:28 +01:00
|
|
|
&mesh_final->ldata, CD_ORIGSPACE_MLOOP, CD_CALLOC, nullptr, mesh_final->totloop);
|
2019-03-28 11:42:53 +01:00
|
|
|
mesh_init_origspace(mesh_final);
|
2012-02-05 12:30:26 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
2020-12-15 12:42:10 +01:00
|
|
|
Mesh *mesh_next = modifier_modify_mesh_and_geometry_set(
|
2021-02-02 16:20:54 +01:00
|
|
|
md, mectx, mesh_final, geometry_set_final);
|
2019-03-28 11:42:53 +01:00
|
|
|
ASSERT_IS_VALID_MESH(mesh_next);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
if (mesh_next) {
|
2018-05-11 09:53:52 +02:00
|
|
|
/* if the modifier returned a new mesh, release the old one */
|
2019-03-28 11:42:53 +01:00
|
|
|
if (mesh_final != mesh_next) {
|
|
|
|
BLI_assert(mesh_final != mesh_input);
|
2020-12-14 13:00:28 +01:00
|
|
|
BKE_id_free(nullptr, mesh_final);
|
2018-05-11 09:53:52 +02:00
|
|
|
}
|
2019-03-28 11:42:53 +01:00
|
|
|
mesh_final = mesh_next;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
if (deformed_verts) {
|
|
|
|
MEM_freeN(deformed_verts);
|
2020-12-14 13:00:28 +01:00
|
|
|
deformed_verts = nullptr;
|
2005-07-19 22:14:17 +02:00
|
|
|
}
|
2012-04-01 17:02:19 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-11 09:53:52 +02:00
|
|
|
/* create an orco mesh in parallel */
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
if (nextmask.vmask & CD_MASK_ORCO) {
|
2019-03-28 11:42:53 +01:00
|
|
|
if (!mesh_orco) {
|
2020-12-14 13:00:28 +01:00
|
|
|
mesh_orco = create_orco_mesh(ob, mesh_input, nullptr, CD_ORCO);
|
2018-05-11 09:53:52 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
nextmask.vmask &= ~CD_MASK_ORCO;
|
2020-12-14 13:00:28 +01:00
|
|
|
CustomData_MeshMasks temp_cddata_masks = {0};
|
|
|
|
temp_cddata_masks.vmask = CD_MASK_ORIGINDEX;
|
|
|
|
temp_cddata_masks.emask = CD_MASK_ORIGINDEX;
|
|
|
|
temp_cddata_masks.fmask = CD_MASK_ORIGINDEX;
|
|
|
|
temp_cddata_masks.pmask = CD_MASK_ORIGINDEX;
|
|
|
|
|
|
|
|
if (mti->requiredDataMask != nullptr) {
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
mti->requiredDataMask(ob, md, &temp_cddata_masks);
|
|
|
|
}
|
|
|
|
CustomData_MeshMasks_update(&temp_cddata_masks, &nextmask);
|
2019-03-28 11:42:53 +01:00
|
|
|
mesh_set_only_copy(mesh_orco, &temp_cddata_masks);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-05-08 10:14:02 +02:00
|
|
|
mesh_next = BKE_modifier_modify_mesh(md, &mectx_orco, mesh_orco);
|
2019-03-28 11:42:53 +01:00
|
|
|
ASSERT_IS_VALID_MESH(mesh_next);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
if (mesh_next) {
|
2018-05-11 09:53:52 +02:00
|
|
|
/* if the modifier returned a new mesh, release the old one */
|
2019-03-28 11:42:53 +01:00
|
|
|
if (mesh_orco != mesh_next) {
|
|
|
|
BLI_assert(mesh_orco != mesh_input);
|
2020-12-14 13:00:28 +01:00
|
|
|
BKE_id_free(nullptr, mesh_orco);
|
2018-05-11 09:53:52 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
mesh_orco = mesh_next;
|
2010-03-30 13:49:07 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
2018-05-11 09:53:52 +02:00
|
|
|
/* create cloth orco mesh in parallel */
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
if (nextmask.vmask & CD_MASK_CLOTH_ORCO) {
|
2019-03-28 11:42:53 +01:00
|
|
|
if (!mesh_orco_cloth) {
|
2020-12-14 13:00:28 +01:00
|
|
|
mesh_orco_cloth = create_orco_mesh(ob, mesh_input, nullptr, CD_CLOTH_ORCO);
|
2018-05-16 17:35:54 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
nextmask.vmask &= ~CD_MASK_CLOTH_ORCO;
|
|
|
|
nextmask.vmask |= CD_MASK_ORIGINDEX;
|
|
|
|
nextmask.emask |= CD_MASK_ORIGINDEX;
|
|
|
|
nextmask.pmask |= CD_MASK_ORIGINDEX;
|
2019-03-28 11:42:53 +01:00
|
|
|
mesh_set_only_copy(mesh_orco_cloth, &nextmask);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-05-08 10:14:02 +02:00
|
|
|
mesh_next = BKE_modifier_modify_mesh(md, &mectx_orco, mesh_orco_cloth);
|
2019-03-28 11:42:53 +01:00
|
|
|
ASSERT_IS_VALID_MESH(mesh_next);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
if (mesh_next) {
|
2018-05-11 09:53:52 +02:00
|
|
|
/* if the modifier returned a new mesh, release the old one */
|
2019-03-28 11:42:53 +01:00
|
|
|
if (mesh_orco_cloth != mesh_next) {
|
|
|
|
BLI_assert(mesh_orco != mesh_input);
|
2020-12-14 13:00:28 +01:00
|
|
|
BKE_id_free(nullptr, mesh_orco_cloth);
|
2015-07-02 08:20:22 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
mesh_orco_cloth = mesh_next;
|
2010-03-30 13:49:07 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
2011-07-08 13:03:37 +02:00
|
|
|
/* in case of dynamic paint, make sure preview mask remains for following modifiers */
|
Add weight preview to WeightVG modifiers, and first, simple/basic refactor of how modifiers can generate preview.
User side:
* Preview for DynamicPaint should keep the same behavior (for now). Weight preview should be somawhat quicker, though.
* Preview for WeightVG modifiers is only active in WeightPaint mode, and if the affected vgroup is the active one.
* Last active preview modifier in stack wins!
Note: that modifier preview topic is yet to be further refined, quite raw/incomplete for now.
Dev side:
* In draw code, renamed DRAW_DYNAMIC_PAINT_PREVIEW flag to DRAW_MODIFIERS_PREVIEW
* Removed use of MOD_DPAINT_PREVIEW_READY in DynamicPaint code (seems unecessary, and if it was, should be of more general scope).
* Added eModifierTypeFlag_UsesPreview to ModifierTypeFlag, for modifiers that can generate some preview data.
* Added three new modifier funcs, to handle preview modifiers in draw code / mod stack.
* For weights preview: added the generic DM_update_weight_mcol func, which can update WEIGHT_MCOL layer with either a given array of weights (currently used by DynamicPaint only), or from current active vgroup(s).
So now, draw code is fully generic (i.e. no more modifier-type checking in it). Mod stack code is generic to some extent, but will need more work.
2012-01-22 18:54:23 +01:00
|
|
|
/* XXX Temp and hackish solution! */
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
if (md->type == eModifierType_DynamicPaint) {
|
|
|
|
append_mask.lmask |= CD_MASK_PREVIEW_MLOOPCOL;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
mesh_final->runtime.deformed_only = false;
|
2005-07-19 22:14:17 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-12 21:18:02 +02:00
|
|
|
isPrevDeform = (mti->type == eModifierTypeType_OnlyDeform);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2008-07-28 13:01:34 +02:00
|
|
|
/* grab modifiers until index i */
|
2019-04-22 01:39:35 +02:00
|
|
|
if ((index != -1) && (BLI_findindex(&ob->modifiers, md) >= index)) {
|
2008-07-28 13:01:34 +02:00
|
|
|
break;
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-27 17:52:21 +01:00
|
|
|
if (sculpt_mode && md->type == eModifierType_Multires) {
|
|
|
|
multires_applied = true;
|
|
|
|
}
|
2005-07-19 22:14:17 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-14 13:00:28 +01:00
|
|
|
BLI_linklist_free((LinkNode *)datamasks, nullptr);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 01:39:35 +02:00
|
|
|
for (md = firstmd; md; md = md->next) {
|
2020-05-08 10:14:02 +02:00
|
|
|
BKE_modifier_free_temporary_data(md);
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-08-05 18:04:40 +02:00
|
|
|
/* Yay, we are done. If we have a Mesh and deformed vertices,
|
|
|
|
* we need to apply these back onto the Mesh. If we have no
|
2019-03-28 11:42:53 +01:00
|
|
|
* Mesh then we need to build one. */
|
2020-12-14 13:00:28 +01:00
|
|
|
if (mesh_final == nullptr) {
|
2022-02-28 17:17:40 +01:00
|
|
|
if (deformed_verts == nullptr && allow_shared_mesh) {
|
2019-05-27 11:45:33 +02:00
|
|
|
mesh_final = mesh_input;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
mesh_final = BKE_mesh_copy_for_eval(mesh_input, true);
|
|
|
|
}
|
2012-03-24 07:18:31 +01:00
|
|
|
}
|
2019-03-28 11:42:53 +01:00
|
|
|
if (deformed_verts) {
|
2019-08-21 22:28:35 +02:00
|
|
|
BKE_mesh_vert_coords_apply(mesh_final, deformed_verts);
|
2019-03-28 11:42:53 +01:00
|
|
|
MEM_freeN(deformed_verts);
|
2020-12-14 13:00:28 +01:00
|
|
|
deformed_verts = nullptr;
|
2005-03-27 22:34:18 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-27 11:45:33 +02:00
|
|
|
/* Denotes whether the object which the modifier stack came from owns the mesh or whether the
|
|
|
|
* mesh is shared across multiple objects since there are no effective modifiers. */
|
|
|
|
const bool is_own_mesh = (mesh_final != mesh_input);
|
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Add orco coordinates to final and deformed mesh if requested. */
|
2019-06-10 15:42:15 +02:00
|
|
|
if (final_datamask.vmask & CD_MASK_ORCO) {
|
2019-05-27 11:45:33 +02:00
|
|
|
/* No need in ORCO layer if the mesh was not deformed or modified: undeformed mesh in this case
|
|
|
|
* matches input mesh. */
|
|
|
|
if (is_own_mesh) {
|
2020-12-14 13:00:28 +01:00
|
|
|
add_orco_mesh(ob, nullptr, mesh_final, mesh_orco, CD_ORCO);
|
2019-05-27 11:45:33 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 01:39:35 +02:00
|
|
|
if (mesh_deform) {
|
2020-12-14 13:00:28 +01:00
|
|
|
add_orco_mesh(ob, nullptr, mesh_deform, nullptr, CD_ORCO);
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
2008-01-09 15:40:25 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
if (mesh_orco) {
|
2020-12-14 13:00:28 +01:00
|
|
|
BKE_id_free(nullptr, mesh_orco);
|
2014-04-13 12:18:51 +02:00
|
|
|
}
|
2019-03-28 11:42:53 +01:00
|
|
|
if (mesh_orco_cloth) {
|
2020-12-14 13:00:28 +01:00
|
|
|
BKE_id_free(nullptr, mesh_orco_cloth);
|
2012-02-06 07:56:54 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Compute normals. */
|
2019-05-27 11:45:33 +02:00
|
|
|
if (is_own_mesh) {
|
2019-06-10 15:42:15 +02:00
|
|
|
mesh_calc_modifier_final_normals(mesh_input, &final_datamask, sculpt_dyntopo, mesh_final);
|
2022-04-06 20:02:04 +02:00
|
|
|
mesh_calc_finalize(mesh_input, mesh_final);
|
2019-05-27 11:45:33 +02:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
Mesh_Runtime *runtime = &mesh_input->runtime;
|
2020-12-14 13:00:28 +01:00
|
|
|
if (runtime->mesh_eval == nullptr) {
|
|
|
|
BLI_assert(runtime->eval_mutex != nullptr);
|
|
|
|
BLI_mutex_lock((ThreadMutex *)runtime->eval_mutex);
|
|
|
|
if (runtime->mesh_eval == nullptr) {
|
2022-04-06 20:29:28 +02:00
|
|
|
/* Not yet finalized by any instance, do it now
|
|
|
|
* Isolate since computing normals is multithreaded and we are holding a lock. */
|
2021-06-21 18:44:40 +02:00
|
|
|
blender::threading::isolate_task([&] {
|
|
|
|
mesh_final = BKE_mesh_copy_for_eval(mesh_input, true);
|
|
|
|
mesh_calc_modifier_final_normals(
|
|
|
|
mesh_input, &final_datamask, sculpt_dyntopo, mesh_final);
|
|
|
|
mesh_calc_finalize(mesh_input, mesh_final);
|
|
|
|
runtime->mesh_eval = mesh_final;
|
|
|
|
});
|
2019-05-27 11:45:33 +02:00
|
|
|
}
|
2022-04-06 20:29:28 +02:00
|
|
|
else {
|
|
|
|
/* Already finalized by another instance, reuse. */
|
|
|
|
mesh_final = runtime->mesh_eval;
|
|
|
|
}
|
2020-12-14 13:00:28 +01:00
|
|
|
BLI_mutex_unlock((ThreadMutex *)runtime->eval_mutex);
|
2019-05-27 11:45:33 +02:00
|
|
|
}
|
2022-04-06 20:29:28 +02:00
|
|
|
else if (!mesh_has_modifier_final_normals(mesh_input, &final_datamask, runtime->mesh_eval)) {
|
|
|
|
/* Modifier stack was (re-)evaluated with a request for additional normals
|
|
|
|
* different than the instanced mesh, can't instance anymore now. */
|
|
|
|
mesh_final = BKE_mesh_copy_for_eval(mesh_input, true);
|
|
|
|
mesh_calc_modifier_final_normals(mesh_input, &final_datamask, sculpt_dyntopo, mesh_final);
|
|
|
|
mesh_calc_finalize(mesh_input, mesh_final);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* Already finalized by another instance, reuse. */
|
|
|
|
mesh_final = runtime->mesh_eval;
|
|
|
|
}
|
2019-05-27 11:45:33 +02:00
|
|
|
}
|
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Return final mesh */
|
|
|
|
*r_final = mesh_final;
|
|
|
|
if (r_deform) {
|
|
|
|
*r_deform = mesh_deform;
|
2018-05-11 09:53:52 +02:00
|
|
|
}
|
2020-12-15 12:42:10 +01:00
|
|
|
if (r_geometry_set) {
|
|
|
|
*r_geometry_set = new GeometrySet(std::move(geometry_set_final));
|
|
|
|
}
|
2005-03-27 22:34:18 +02:00
|
|
|
}
|
|
|
|
|
2019-08-21 22:28:35 +02:00
|
|
|
float (*editbmesh_vert_coords_alloc(BMEditMesh *em, int *r_vert_len))[3]
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 09:37:15 +02:00
|
|
|
{
|
2009-05-16 18:18:08 +02:00
|
|
|
BMIter iter;
|
|
|
|
BMVert *eve;
|
2012-12-21 08:28:14 +01:00
|
|
|
float(*cos)[3];
|
|
|
|
int i;
|
|
|
|
|
2019-08-21 22:28:35 +02:00
|
|
|
*r_vert_len = em->bm->totvert;
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 09:37:15 +02:00
|
|
|
|
2020-12-14 13:00:28 +01:00
|
|
|
cos = (float(*)[3])MEM_malloc_arrayN(em->bm->totvert, sizeof(float[3]), "vertexcos");
|
2009-05-16 18:18:08 +02:00
|
|
|
|
2012-12-21 08:28:14 +01:00
|
|
|
BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
|
2011-11-06 16:39:20 +01:00
|
|
|
copy_v3_v3(cos[i], eve->co);
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 09:37:15 +02:00
|
|
|
}
|
|
|
|
|
2005-10-09 18:59:10 +02:00
|
|
|
return cos;
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 09:37:15 +02:00
|
|
|
}
|
|
|
|
|
2022-02-14 19:05:54 +01:00
|
|
|
bool editbmesh_modifier_is_enabled(const Scene *scene,
|
2020-10-26 07:07:58 +01:00
|
|
|
const Object *ob,
|
|
|
|
ModifierData *md,
|
|
|
|
bool has_prev_mesh)
|
2007-07-28 23:04:30 +02:00
|
|
|
{
|
2020-12-14 13:00:28 +01:00
|
|
|
const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type);
|
2015-07-02 08:20:22 +02:00
|
|
|
const int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
|
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)) {
|
2015-07-02 08:20:22 +02:00
|
|
|
return false;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-10-09 06:04:51 +02:00
|
|
|
if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) && has_prev_mesh) {
|
2020-10-26 07:07:58 +01:00
|
|
|
BKE_modifier_set_error(ob, md, "Modifier requires original data, bad stack position");
|
2014-12-01 17:11:18 +01:00
|
|
|
return false;
|
2007-07-28 23:04:30 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-12-01 17:11:18 +01:00
|
|
|
return true;
|
2007-07-28 23:04:30 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-05-25 12:16:42 +02:00
|
|
|
static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final,
|
|
|
|
const CustomData_MeshMasks *final_datamask)
|
2019-03-28 11:42:53 +01:00
|
|
|
{
|
2020-05-25 12:16:42 +02:00
|
|
|
if (mesh_final->runtime.wrapper_type != ME_WRAPPER_TYPE_MDATA) {
|
|
|
|
/* Generated at draw time. */
|
|
|
|
mesh_final->runtime.wrapper_type_finalize = (1 << mesh_final->runtime.wrapper_type);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const bool do_loop_normals = ((mesh_final->flag & ME_AUTOSMOOTH) != 0 ||
|
2019-06-10 15:42:15 +02:00
|
|
|
(final_datamask->lmask & CD_MASK_NORMAL) != 0);
|
2019-08-05 18:04:40 +02:00
|
|
|
|
|
|
|
if (do_loop_normals) {
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Compute loop normals */
|
|
|
|
BKE_mesh_calc_normals_split(mesh_final);
|
|
|
|
}
|
2022-04-06 20:02:04 +02:00
|
|
|
else {
|
|
|
|
/* Same as mesh_calc_modifiers. If using loop normals, poly nors have already been computed. */
|
2019-03-28 11:42:53 +01:00
|
|
|
BKE_mesh_ensure_normals_for_display(mesh_final);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-06-12 01:04:10 +02:00
|
|
|
/* Some modifiers, like data-transfer, may generate those data, we do not want to keep them,
|
2019-03-28 11:42:53 +01:00
|
|
|
* as they are used by display code when available (i.e. even if autosmooth is disabled). */
|
|
|
|
if (CustomData_has_layer(&mesh_final->ldata, CD_NORMAL)) {
|
|
|
|
CustomData_free_layers(&mesh_final->ldata, CD_NORMAL, mesh_final->totloop);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-03-28 11:42:53 +01:00
|
|
|
}
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-07-02 08:20:22 +02:00
|
|
|
static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
|
2022-02-14 19:05:54 +01:00
|
|
|
const Scene *scene,
|
2019-03-27 19:07:16 +01:00
|
|
|
Object *ob,
|
2019-03-28 11:42:53 +01:00
|
|
|
BMEditMesh *em_input,
|
2019-03-27 19:07:16 +01:00
|
|
|
const CustomData_MeshMasks *dataMask,
|
2015-07-02 08:20:22 +02:00
|
|
|
/* return args */
|
2019-03-27 19:07:16 +01:00
|
|
|
Mesh **r_cage,
|
2020-12-15 12:42:10 +01:00
|
|
|
Mesh **r_final,
|
|
|
|
GeometrySet **r_geometry_set)
|
2013-07-05 02:13:14 +02:00
|
|
|
{
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Input and final mesh. Final mesh is only created the moment the first
|
|
|
|
* constructive modifier is executed, or a deform modifier needs normals
|
|
|
|
* or certain data layers. */
|
2020-12-14 13:00:28 +01:00
|
|
|
Mesh *mesh_input = (Mesh *)ob->data;
|
|
|
|
Mesh *mesh_final = nullptr;
|
|
|
|
Mesh *mesh_cage = nullptr;
|
2020-12-15 12:42:10 +01:00
|
|
|
/* This geometry set contains the non-mesh data that might be generated by modifiers. */
|
|
|
|
GeometrySet geometry_set_final;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Deformed vertex locations array. Deform only modifier need this type of
|
|
|
|
* float array rather than MVert*. Tracked along with mesh_final as an
|
|
|
|
* optimization to avoid copying coordinates back and forth if there are
|
|
|
|
* multiple sequential deform only modifiers. */
|
2020-12-14 13:00:28 +01:00
|
|
|
float(*deformed_verts)[3] = nullptr;
|
2019-03-28 11:42:53 +01:00
|
|
|
int num_deformed_verts = 0;
|
2019-03-18 15:37:46 +01:00
|
|
|
bool isPrevDeform = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Mesh with constructive modifiers but no deformation applied. Tracked
|
|
|
|
* along with final mesh if undeformed / orco coordinates are requested
|
|
|
|
* for texturing. */
|
2020-12-14 13:00:28 +01:00
|
|
|
Mesh *mesh_orco = nullptr;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Modifier evaluation modes. */
|
|
|
|
const int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-15 09:32:13 +02:00
|
|
|
const bool use_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Modifier evaluation contexts for different types of modifiers. */
|
2020-12-14 13:00:28 +01:00
|
|
|
ModifierApplyFlag apply_render = use_render ? MOD_APPLY_RENDER : (ModifierApplyFlag)0;
|
|
|
|
const ModifierEvalContext mectx = {
|
|
|
|
depsgraph, ob, (ModifierApplyFlag)(MOD_APPLY_USECACHE | apply_render)};
|
2019-03-28 11:42:53 +01:00
|
|
|
const ModifierEvalContext mectx_orco = {depsgraph, ob, MOD_APPLY_ORCO};
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Get effective list of modifiers to execute. Some effects like shape keys
|
|
|
|
* are added as virtual modifiers before the user created modifiers. */
|
|
|
|
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
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Compute accumulated datamasks needed by each modifier. It helps to do
|
|
|
|
* this fine grained so that for example vertex groups are preserved up to
|
|
|
|
* an armature modifier, but not through a following subsurf modifier where
|
|
|
|
* subdividing them is expensive. */
|
2019-06-10 15:42:15 +02:00
|
|
|
CustomData_MeshMasks final_datamask = *dataMask;
|
2020-05-08 10:14:02 +02:00
|
|
|
CDMaskLink *datamasks = BKE_modifier_calc_data_masks(
|
2020-12-14 13:00:28 +01:00
|
|
|
scene, ob, md, &final_datamask, required_mode, nullptr, nullptr);
|
2019-03-28 11:42:53 +01:00
|
|
|
CDMaskLink *md_datamask = datamasks;
|
|
|
|
CustomData_MeshMasks append_mask = CD_MASK_BAREMESH;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-06-10 15:42:15 +02:00
|
|
|
/* Evaluate modifiers up to certain index to get the mesh cage. */
|
2020-12-14 13:00:28 +01:00
|
|
|
int cageIndex = BKE_modifiers_get_cage_index(scene, ob, nullptr, true);
|
2019-06-10 15:42:15 +02:00
|
|
|
if (r_cage && cageIndex == -1) {
|
2020-05-25 12:16:42 +02:00
|
|
|
mesh_cage = BKE_mesh_wrapper_from_editmesh_with_coords(
|
2020-12-14 13:00:28 +01:00
|
|
|
em_input, &final_datamask, nullptr, mesh_input);
|
2019-06-10 15:42:15 +02:00
|
|
|
}
|
|
|
|
|
Mesh: Avoid creating incorrect original index layers
Currently, whenever any BMesh is converted to a Mesh (except for edit
mode switching), original index (`CD_ORIGINDEX`) layers are added.
This is incorrect, because many operations just convert some Mesh into
a BMesh and then back, but they shouldn't make any assumption about
where their input mesh came from. It might even come from a primitive
in geometry nodes, where there are no original indices at all.
Conceptually, mesh original indices should be filled by the modifier
stack when first creating the evaluated mesh. So that's where they're
moved in this patch. A separate function now fills the indices with their
default (0,1,2,3...) values. The way the mesh wrapper system defers
the BMesh to Mesh conversion makes this a bit less obvious though.
The old behavior is incorrect, but it's also slower, because three
arrays the size of the mesh's vertices, edges, and faces had to be
allocated and filled during the BMesh to Mesh conversion, which just
ends up putting more pressure on the cache. In the many cases where
original indices aren't used, I measured an **8% speedup** for the
conversion (from 76.5ms to 70.7ms).
Generally there is an assumption that BMesh is "original" and Mesh is
"evaluated". After this patch, that assumption isn't quite as strong,
but it still exists for two reasons. First, original indices are added
whenever converting a BMesh "wrapper" to a Mesh. Second, original
indices are not added to the BMesh at the beginning of evaluation,
which assumes that every BMesh in the viewport is original and doesn't
need the mapping.
Differential Revision: https://developer.blender.org/D14018
2022-02-18 17:51:00 +01:00
|
|
|
/* The mesh from edit mode should not have any original index layers already, since those
|
|
|
|
* are added during evaluation when necessary and are redundant on an original mesh. */
|
|
|
|
BLI_assert(CustomData_get_layer(&em_input->bm->pdata, CD_ORIGINDEX) == nullptr &&
|
|
|
|
CustomData_get_layer(&em_input->bm->edata, CD_ORIGINDEX) == nullptr &&
|
|
|
|
CustomData_get_layer(&em_input->bm->pdata, CD_ORIGINDEX) == nullptr);
|
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Clear errors before evaluation. */
|
2020-05-08 10:14:02 +02:00
|
|
|
BKE_modifiers_clear_errors(ob);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
for (int i = 0; md; i++, md = md->next, md_datamask = md_datamask->next) {
|
2020-12-14 13:00:28 +01:00
|
|
|
const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-14 13:00:28 +01:00
|
|
|
if (!editbmesh_modifier_is_enabled(scene, ob, md, mesh_final != nullptr)) {
|
- added eModifierTypeFlag_RequiresOriginalData for modifiers that
can only follow deform (for example, they store mesh vertex
indices)
- added ModifierType.foreachObjectLink for iterating over Object
links inside modifier data (used for file load, relinking, etc)
- switched various modifiers_ functions to take object argument
instead of ListBase
- added user editable name field to modifiers
- bug fix, duplicate and make single user didn't relink object
pointers in modifier data
- added modifiers to outliner, needs icon
- added armature, hook, and softbody modifiers (softbody doesn't
do anything atm). added conversion of old hooks to modifiers.
NOTE-THE-FIRST: User name field is not initialized on loading 2.38 files
so if you have saved stuff with a cvs blender you will see blank names.
NOTE-THE-SECOND: Since modifiers aren't evaluated yet for non-Mesh
objects, hooks for lattices and curves are broken. Don't updated if
you actually, say, *use* Blender.
NOTE-THE-THIRD: Old hooks used a quirky weighting system during
deformation which can't be extended to modifiers. On the upside,
I doubt anyone relied on the old quirky system and the new system
makes much more sense. (Although the way falloff works is still
quite stupid I think).
2005-08-11 00:05:52 +02:00
|
|
|
continue;
|
2015-07-02 08:20:22 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-06-10 15:42:15 +02:00
|
|
|
/* Add an orco mesh as layer if needed by this modifier. */
|
|
|
|
if (mesh_final && mesh_orco && mti->requiredDataMask) {
|
2019-03-28 11:42:53 +01:00
|
|
|
CustomData_MeshMasks mask = {0};
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
mti->requiredDataMask(ob, md, &mask);
|
|
|
|
if (mask.vmask & CD_MASK_ORCO) {
|
2019-03-28 11:42:53 +01:00
|
|
|
add_orco_mesh(ob, em_input, mesh_final, mesh_orco, CD_ORCO);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-10-09 06:04:51 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2006-08-28 03:12:36 +02:00
|
|
|
/* How to apply modifier depends on (a) what we already have as
|
2019-03-28 11:42:53 +01:00
|
|
|
* a result of previous modifiers (could be a mesh or just
|
|
|
|
* deformed vertices) and (b) what type the modifier is. */
|
2012-03-24 07:18:31 +01:00
|
|
|
if (mti->type == eModifierTypeType_OnlyDeform) {
|
2006-08-28 03:12:36 +02:00
|
|
|
/* No existing verts to deform, need to build them. */
|
2019-03-28 11:42:53 +01:00
|
|
|
if (!deformed_verts) {
|
|
|
|
if (mesh_final) {
|
2006-08-28 03:12:36 +02:00
|
|
|
/* Deforming a derived mesh, read the vertex locations
|
|
|
|
* out of the mesh and deform them. Once done with this
|
2019-03-28 11:42:53 +01:00
|
|
|
* run of deformers verts will be written back. */
|
2019-08-21 22:28:35 +02:00
|
|
|
deformed_verts = BKE_mesh_vert_coords_alloc(mesh_final, &num_deformed_verts);
|
2012-03-24 07:18:31 +01:00
|
|
|
}
|
|
|
|
else {
|
2019-08-21 22:28:35 +02:00
|
|
|
deformed_verts = editbmesh_vert_coords_alloc(em_input, &num_deformed_verts);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 09:37:15 +02:00
|
|
|
}
|
2019-03-28 11:42:53 +01:00
|
|
|
else if (isPrevDeform && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
|
2020-12-14 13:00:28 +01:00
|
|
|
if (mesh_final == nullptr) {
|
|
|
|
mesh_final = BKE_mesh_from_bmesh_for_eval_nomain(em_input->bm, nullptr, mesh_input);
|
Mesh: Avoid creating incorrect original index layers
Currently, whenever any BMesh is converted to a Mesh (except for edit
mode switching), original index (`CD_ORIGINDEX`) layers are added.
This is incorrect, because many operations just convert some Mesh into
a BMesh and then back, but they shouldn't make any assumption about
where their input mesh came from. It might even come from a primitive
in geometry nodes, where there are no original indices at all.
Conceptually, mesh original indices should be filled by the modifier
stack when first creating the evaluated mesh. So that's where they're
moved in this patch. A separate function now fills the indices with their
default (0,1,2,3...) values. The way the mesh wrapper system defers
the BMesh to Mesh conversion makes this a bit less obvious though.
The old behavior is incorrect, but it's also slower, because three
arrays the size of the mesh's vertices, edges, and faces had to be
allocated and filled during the BMesh to Mesh conversion, which just
ends up putting more pressure on the cache. In the many cases where
original indices aren't used, I measured an **8% speedup** for the
conversion (from 76.5ms to 70.7ms).
Generally there is an assumption that BMesh is "original" and Mesh is
"evaluated". After this patch, that assumption isn't quite as strong,
but it still exists for two reasons. First, original indices are added
whenever converting a BMesh "wrapper" to a Mesh. Second, original
indices are not added to the BMesh at the beginning of evaluation,
which assumes that every BMesh in the viewport is original and doesn't
need the mapping.
Differential Revision: https://developer.blender.org/D14018
2022-02-18 17:51:00 +01:00
|
|
|
BKE_mesh_ensure_default_orig_index_customdata(mesh_final);
|
2019-03-28 11:42:53 +01:00
|
|
|
ASSERT_IS_VALID_MESH(mesh_final);
|
2019-03-18 15:37:46 +01:00
|
|
|
}
|
2020-12-14 13:00:28 +01:00
|
|
|
BLI_assert(deformed_verts != nullptr);
|
2019-08-21 22:28:35 +02:00
|
|
|
BKE_mesh_vert_coords_apply(mesh_final, deformed_verts);
|
2019-03-18 15:37:46 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 01:39:35 +02:00
|
|
|
if (mti->deformVertsEM) {
|
2020-05-08 10:14:02 +02:00
|
|
|
BKE_modifier_deform_vertsEM(
|
2019-03-28 11:42:53 +01:00
|
|
|
md, &mectx, em_input, mesh_final, deformed_verts, num_deformed_verts);
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
|
|
|
else {
|
2020-05-08 10:14:02 +02:00
|
|
|
BKE_modifier_deform_verts(md, &mectx, mesh_final, deformed_verts, num_deformed_verts);
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
2012-03-24 07:18:31 +01:00
|
|
|
}
|
|
|
|
else {
|
2006-08-28 03:12:36 +02:00
|
|
|
/* apply vertex coordinates or build a DerivedMesh as necessary */
|
2019-03-28 11:42:53 +01:00
|
|
|
if (mesh_final) {
|
|
|
|
if (deformed_verts) {
|
|
|
|
Mesh *mesh_tmp = BKE_mesh_copy_for_eval(mesh_final, false);
|
|
|
|
if (mesh_final != mesh_cage) {
|
2020-12-14 13:00:28 +01:00
|
|
|
BKE_id_free(nullptr, mesh_final);
|
2018-10-09 06:04:51 +02:00
|
|
|
}
|
2019-03-28 11:42:53 +01:00
|
|
|
mesh_final = mesh_tmp;
|
2019-08-21 22:28:35 +02:00
|
|
|
BKE_mesh_vert_coords_apply(mesh_final, deformed_verts);
|
2012-03-24 07:18:31 +01:00
|
|
|
}
|
2019-03-28 11:42:53 +01:00
|
|
|
else if (mesh_final == mesh_cage) {
|
2018-10-09 06:04:51 +02:00
|
|
|
/* 'me' may be changed by this modifier, so we need to copy it. */
|
2019-03-28 11:42:53 +01:00
|
|
|
mesh_final = BKE_mesh_copy_for_eval(mesh_final, false);
|
2006-08-28 03:12:36 +02:00
|
|
|
}
|
2012-03-24 07:18:31 +01:00
|
|
|
}
|
|
|
|
else {
|
2020-05-25 12:16:42 +02:00
|
|
|
mesh_final = BKE_mesh_wrapper_from_editmesh_with_coords(
|
2020-12-14 13:00:28 +01:00
|
|
|
em_input, nullptr, deformed_verts, mesh_input);
|
|
|
|
deformed_verts = nullptr;
|
2006-08-28 03:12:36 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 22:51:28 +02:00
|
|
|
/* create an orco derivedmesh in parallel */
|
2019-03-28 11:42:53 +01:00
|
|
|
CustomData_MeshMasks mask = md_datamask->mask;
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
if (mask.vmask & CD_MASK_ORCO) {
|
2019-03-28 11:42:53 +01:00
|
|
|
if (!mesh_orco) {
|
|
|
|
mesh_orco = create_orco_mesh(ob, mesh_input, em_input, CD_ORCO);
|
2018-10-09 06:04:51 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
mask.vmask &= ~CD_MASK_ORCO;
|
|
|
|
mask.vmask |= CD_MASK_ORIGINDEX;
|
|
|
|
mask.emask |= CD_MASK_ORIGINDEX;
|
|
|
|
mask.pmask |= CD_MASK_ORIGINDEX;
|
2019-03-28 11:42:53 +01:00
|
|
|
mesh_set_only_copy(mesh_orco, &mask);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-05-08 10:14:02 +02:00
|
|
|
Mesh *mesh_next = BKE_modifier_modify_mesh(md, &mectx_orco, mesh_orco);
|
2019-03-28 11:42:53 +01:00
|
|
|
ASSERT_IS_VALID_MESH(mesh_next);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
if (mesh_next) {
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 22:51:28 +02:00
|
|
|
/* if the modifier returned a new dm, release the old one */
|
2019-03-28 11:42:53 +01:00
|
|
|
if (mesh_orco && mesh_orco != mesh_next) {
|
2020-12-14 13:00:28 +01:00
|
|
|
BKE_id_free(nullptr, mesh_orco);
|
2018-10-09 06:04:51 +02:00
|
|
|
}
|
2019-03-28 11:42:53 +01:00
|
|
|
mesh_orco = mesh_next;
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 22:51:28 +02:00
|
|
|
}
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2006-12-05 18:42:03 +01:00
|
|
|
/* set the DerivedMesh to only copy needed data */
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
CustomData_MeshMasks_update(&mask, &append_mask);
|
2022-03-07 17:25:50 +01:00
|
|
|
/* XXX WHAT? overwrites mask ??? */
|
2019-04-16 17:55:11 +02:00
|
|
|
/* CD_MASK_ORCO may have been cleared above */
|
|
|
|
mask = md_datamask->mask;
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
mask.vmask |= CD_MASK_ORIGINDEX;
|
|
|
|
mask.emask |= CD_MASK_ORIGINDEX;
|
|
|
|
mask.pmask |= CD_MASK_ORIGINDEX;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
mesh_set_only_copy(mesh_final, &mask);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
if (mask.lmask & CD_MASK_ORIGSPACE_MLOOP) {
|
2019-03-28 11:42:53 +01:00
|
|
|
if (!CustomData_has_layer(&mesh_final->ldata, CD_ORIGSPACE_MLOOP)) {
|
|
|
|
CustomData_add_layer(
|
2020-12-14 13:00:28 +01:00
|
|
|
&mesh_final->ldata, CD_ORIGSPACE_MLOOP, CD_CALLOC, nullptr, mesh_final->totloop);
|
2019-03-28 11:42:53 +01:00
|
|
|
mesh_init_origspace(mesh_final);
|
2012-02-05 12:30:26 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
2020-12-15 12:42:10 +01:00
|
|
|
Mesh *mesh_next = modifier_modify_mesh_and_geometry_set(
|
2021-02-02 16:20:54 +01:00
|
|
|
md, mectx, mesh_final, geometry_set_final);
|
2019-03-28 11:42:53 +01:00
|
|
|
ASSERT_IS_VALID_MESH(mesh_next);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
if (mesh_next) {
|
|
|
|
if (mesh_final && mesh_final != mesh_next) {
|
2020-12-14 13:00:28 +01:00
|
|
|
BKE_id_free(nullptr, mesh_final);
|
2018-10-09 06:04:51 +02:00
|
|
|
}
|
2019-03-28 11:42:53 +01:00
|
|
|
mesh_final = mesh_next;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
if (deformed_verts) {
|
|
|
|
MEM_freeN(deformed_verts);
|
2020-12-14 13:00:28 +01:00
|
|
|
deformed_verts = nullptr;
|
2005-08-03 06:04:05 +02:00
|
|
|
}
|
|
|
|
}
|
2019-03-28 11:42:53 +01:00
|
|
|
mesh_final->runtime.deformed_only = false;
|
2005-08-03 06:04:05 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-07-02 08:20:22 +02:00
|
|
|
if (r_cage && i == cageIndex) {
|
2019-03-28 11:42:53 +01:00
|
|
|
if (mesh_final && deformed_verts) {
|
|
|
|
mesh_cage = BKE_mesh_copy_for_eval(mesh_final, false);
|
2019-08-21 22:28:35 +02:00
|
|
|
BKE_mesh_vert_coords_apply(mesh_cage, deformed_verts);
|
2012-03-24 07:18:31 +01:00
|
|
|
}
|
2019-03-28 11:42:53 +01:00
|
|
|
else if (mesh_final) {
|
|
|
|
mesh_cage = mesh_final;
|
2012-03-24 07:18:31 +01:00
|
|
|
}
|
|
|
|
else {
|
2019-03-28 11:42:53 +01:00
|
|
|
Mesh *me_orig = mesh_input;
|
2022-02-24 14:15:38 +01:00
|
|
|
/* Modifying the input mesh is weak, however as there can only be one object in edit mode
|
|
|
|
* even if multiple are sharing the same mesh this should be thread safe. */
|
|
|
|
if ((me_orig->id.tag & LIB_TAG_COPIED_ON_WRITE) && (ob->mode & OB_MODE_EDIT)) {
|
2020-06-24 14:09:40 +02:00
|
|
|
if (!BKE_mesh_runtime_ensure_edit_data(me_orig)) {
|
|
|
|
BKE_mesh_runtime_reset_edit_data(me_orig);
|
|
|
|
}
|
2021-01-04 01:41:18 +01:00
|
|
|
me_orig->runtime.edit_data->vertexCos = (const float(*)[3])MEM_dupallocN(deformed_verts);
|
2018-04-19 11:03:58 +02:00
|
|
|
}
|
2020-05-25 12:16:42 +02:00
|
|
|
mesh_cage = BKE_mesh_wrapper_from_editmesh_with_coords(
|
2019-09-16 10:45:49 +02:00
|
|
|
em_input,
|
|
|
|
&final_datamask,
|
2021-01-04 01:41:18 +01:00
|
|
|
deformed_verts ? (const float(*)[3])MEM_dupallocN(deformed_verts) : nullptr,
|
2019-09-16 10:45:49 +02:00
|
|
|
mesh_input);
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 09:37:15 +02:00
|
|
|
}
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-18 15:37:46 +01:00
|
|
|
isPrevDeform = (mti->type == eModifierTypeType_OnlyDeform);
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 09:37:15 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-14 13:00:28 +01:00
|
|
|
BLI_linklist_free((LinkNode *)datamasks, nullptr);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2006-08-28 03:12:36 +02:00
|
|
|
/* Yay, we are done. If we have a DerivedMesh and deformed vertices need
|
|
|
|
* to apply these back onto the DerivedMesh. If we have no DerivedMesh
|
2019-03-28 11:42:53 +01:00
|
|
|
* then we need to build one. */
|
|
|
|
if (mesh_final) {
|
|
|
|
if (deformed_verts) {
|
|
|
|
Mesh *mesh_tmp = BKE_mesh_copy_for_eval(mesh_final, false);
|
|
|
|
if (mesh_final != mesh_cage) {
|
2020-12-14 13:00:28 +01:00
|
|
|
BKE_id_free(nullptr, mesh_final);
|
2019-03-28 11:42:53 +01:00
|
|
|
}
|
|
|
|
mesh_final = mesh_tmp;
|
2019-08-21 22:28:35 +02:00
|
|
|
BKE_mesh_vert_coords_apply(mesh_final, deformed_verts);
|
2015-07-02 08:20:22 +02:00
|
|
|
}
|
2012-02-28 11:22:21 +01:00
|
|
|
}
|
2019-03-28 11:42:53 +01:00
|
|
|
else if (!deformed_verts && mesh_cage) {
|
2012-02-28 11:22:21 +01:00
|
|
|
/* cage should already have up to date normals */
|
2019-03-28 11:42:53 +01:00
|
|
|
mesh_final = mesh_cage;
|
2012-02-28 11:22:21 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* this is just a copy of the editmesh, no need to calc normals */
|
2020-05-25 12:16:42 +02:00
|
|
|
mesh_final = BKE_mesh_wrapper_from_editmesh_with_coords(
|
2019-09-16 10:45:49 +02:00
|
|
|
em_input, &final_datamask, deformed_verts, mesh_input);
|
2020-12-14 13:00:28 +01:00
|
|
|
deformed_verts = nullptr;
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 09:37:15 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
if (deformed_verts) {
|
|
|
|
MEM_freeN(deformed_verts);
|
2014-04-13 12:18:51 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Add orco coordinates to final and deformed mesh if requested. */
|
2019-06-10 15:42:15 +02:00
|
|
|
if (final_datamask.vmask & CD_MASK_ORCO) {
|
2020-05-25 12:16:42 +02:00
|
|
|
/* FIXME(Campbell): avoid the need to convert to mesh data just to add an orco layer. */
|
|
|
|
BKE_mesh_wrapper_ensure_mdata(mesh_final);
|
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
add_orco_mesh(ob, em_input, mesh_final, mesh_orco, CD_ORCO);
|
2012-02-28 11:22:21 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
if (mesh_orco) {
|
2020-12-14 13:00:28 +01:00
|
|
|
BKE_id_free(nullptr, mesh_orco);
|
2014-04-13 12:18:51 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Compute normals. */
|
2020-05-25 12:16:42 +02:00
|
|
|
editbmesh_calc_modifier_final_normals(mesh_final, &final_datamask);
|
2019-03-28 11:42:53 +01:00
|
|
|
if (mesh_cage && (mesh_cage != mesh_final)) {
|
2020-05-25 12:16:42 +02:00
|
|
|
editbmesh_calc_modifier_final_normals(mesh_cage, &final_datamask);
|
2018-10-09 06:04:51 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-28 11:42:53 +01:00
|
|
|
/* Return final mesh. */
|
|
|
|
*r_final = mesh_final;
|
|
|
|
if (r_cage) {
|
|
|
|
*r_cage = mesh_cage;
|
2018-10-09 06:04:51 +02:00
|
|
|
}
|
2020-12-15 12:42:10 +01:00
|
|
|
if (r_geometry_set) {
|
|
|
|
*r_geometry_set = new GeometrySet(std::move(geometry_set_final));
|
|
|
|
}
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 09:37:15 +02:00
|
|
|
}
|
|
|
|
|
2020-02-27 11:23:15 +01:00
|
|
|
static void mesh_build_extra_data(struct Depsgraph *depsgraph, Object *ob, Mesh *mesh_eval)
|
Shrinkwrap: new mode that projects along the target normal.
The Nearest Surface Point shrink method, while fast, is neither
smooth nor continuous: as the source point moves, the projected
point can both stop and jump. This causes distortions in the
deformation of the shrinkwrap modifier, and the motion of an
animated object with a shrinkwrap constraint.
This patch implements a new mode, which, instead of using the simple
nearest point search, iteratively solves an equation for each triangle
to find a point which has its interpolated normal point to or from the
original vertex. Non-manifold boundary edges are treated as infinitely
thin cylinders that cast normals in all perpendicular directions.
Since this is useful for the constraint, and having multiple
objects with constraints targeting the same guide mesh is a quite
reasonable use case, rather than calculating the mesh boundary edge
data over and over again, it is precomputed and cached in the mesh.
Reviewers: mont29
Differential Revision: https://developer.blender.org/D3836
2018-11-06 19:04:53 +01:00
|
|
|
{
|
|
|
|
uint32_t eval_flags = DEG_get_eval_flags_for_id(depsgraph, &ob->id);
|
|
|
|
|
|
|
|
if (eval_flags & DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY) {
|
2020-02-27 11:23:15 +01:00
|
|
|
BKE_shrinkwrap_compute_boundary_data(mesh_eval);
|
Shrinkwrap: new mode that projects along the target normal.
The Nearest Surface Point shrink method, while fast, is neither
smooth nor continuous: as the source point moves, the projected
point can both stop and jump. This causes distortions in the
deformation of the shrinkwrap modifier, and the motion of an
animated object with a shrinkwrap constraint.
This patch implements a new mode, which, instead of using the simple
nearest point search, iteratively solves an equation for each triangle
to find a point which has its interpolated normal point to or from the
original vertex. Non-manifold boundary edges are treated as infinitely
thin cylinders that cast normals in all perpendicular directions.
Since this is useful for the constraint, and having multiple
objects with constraints targeting the same guide mesh is a quite
reasonable use case, rather than calculating the mesh boundary edge
data over and over again, it is precomputed and cached in the mesh.
Reviewers: mont29
Differential Revision: https://developer.blender.org/D3836
2018-11-06 19:04:53 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
static void mesh_build_data(struct Depsgraph *depsgraph,
|
2022-02-14 19:05:54 +01:00
|
|
|
const Scene *scene,
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
Object *ob,
|
|
|
|
const CustomData_MeshMasks *dataMask,
|
2019-03-27 19:07:16 +01:00
|
|
|
const bool need_mapping)
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 22:30:33 +02:00
|
|
|
{
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
#if 0 /* XXX This is already taken care of in mesh_calc_modifiers()... */
|
2018-12-01 10:12:18 +01:00
|
|
|
if (need_mapping) {
|
|
|
|
/* Also add the flag so that it is recorded in lastDataMask. */
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
dataMask->vmask |= CD_MASK_ORIGINDEX;
|
|
|
|
dataMask->emask |= CD_MASK_ORIGINDEX;
|
|
|
|
dataMask->pmask |= CD_MASK_ORIGINDEX;
|
2018-12-01 10:12:18 +01:00
|
|
|
}
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
#endif
|
2018-12-01 10:12:18 +01:00
|
|
|
|
2020-12-14 13:00:28 +01:00
|
|
|
Mesh *mesh_eval = nullptr, *mesh_deform_eval = nullptr;
|
2020-12-15 12:42:10 +01:00
|
|
|
GeometrySet *geometry_set_eval = nullptr;
|
2018-05-30 12:56:20 +02:00
|
|
|
mesh_calc_modifiers(depsgraph,
|
2019-03-27 19:07:16 +01:00
|
|
|
scene,
|
|
|
|
ob,
|
2021-07-01 02:08:24 +02:00
|
|
|
true,
|
2019-03-27 19:07:16 +01:00
|
|
|
need_mapping,
|
|
|
|
dataMask,
|
|
|
|
-1,
|
|
|
|
true,
|
2019-05-31 10:05:56 +02:00
|
|
|
true,
|
2020-02-27 11:23:15 +01:00
|
|
|
&mesh_deform_eval,
|
2020-12-15 12:42:10 +01:00
|
|
|
&mesh_eval,
|
|
|
|
&geometry_set_eval);
|
2018-11-25 18:39:57 +01:00
|
|
|
|
2020-02-27 11:23:15 +01:00
|
|
|
/* The modifier stack evaluation is storing result in mesh->runtime.mesh_eval, but this result
|
|
|
|
* is not guaranteed to be owned by object.
|
|
|
|
*
|
|
|
|
* Check ownership now, since later on we can not go to a mesh owned by someone else via
|
|
|
|
* object's runtime: this could cause access freed data on depsgraph destruction (mesh who owns
|
|
|
|
* the final result might be freed prior to object). */
|
2020-12-14 13:00:28 +01:00
|
|
|
Mesh *mesh = (Mesh *)ob->data;
|
2020-02-27 11:23:15 +01:00
|
|
|
const bool is_mesh_eval_owned = (mesh_eval != mesh->runtime.mesh_eval);
|
|
|
|
BKE_object_eval_assign_data(ob, &mesh_eval->id, is_mesh_eval_owned);
|
|
|
|
|
2021-11-05 17:51:34 +01:00
|
|
|
/* Add the final mesh as a non-owning component to the geometry set. */
|
2020-12-15 12:42:10 +01:00
|
|
|
MeshComponent &mesh_component = geometry_set_eval->get_component_for_write<MeshComponent>();
|
2021-11-05 17:51:34 +01:00
|
|
|
mesh_component.replace(mesh_eval, GeometryOwnershipType::Editable);
|
2020-12-15 12:42:10 +01:00
|
|
|
ob->runtime.geometry_set_eval = geometry_set_eval;
|
|
|
|
|
2020-02-27 11:23:15 +01:00
|
|
|
ob->runtime.mesh_deform_eval = mesh_deform_eval;
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
ob->runtime.last_data_mask = *dataMask;
|
2018-12-03 16:09:45 +01:00
|
|
|
ob->runtime.last_need_mapping = need_mapping;
|
2012-03-14 07:30:55 +01:00
|
|
|
|
2020-02-27 11:23:15 +01:00
|
|
|
BKE_object_boundbox_calc_from_mesh(ob, mesh_eval);
|
|
|
|
|
2020-08-13 12:53:21 +02:00
|
|
|
/* Make sure that drivers can target shapekey properties.
|
|
|
|
* Note that this causes a potential inconsistency, as the shapekey may have a
|
|
|
|
* different topology than the evaluated mesh. */
|
2020-12-14 13:00:28 +01:00
|
|
|
BLI_assert(mesh->key == nullptr || DEG_is_evaluated_id(&mesh->key->id));
|
2020-08-13 12:53:21 +02:00
|
|
|
mesh_eval->key = mesh->key;
|
|
|
|
|
2018-04-05 18:20:27 +02:00
|
|
|
if ((ob->mode & OB_MODE_ALL_SCULPT) && ob->sculpt) {
|
2019-05-31 12:50:15 +02:00
|
|
|
if (DEG_is_active(depsgraph)) {
|
|
|
|
BKE_sculpt_update_object_after_eval(depsgraph, ob);
|
|
|
|
}
|
2012-03-14 07:30:55 +01:00
|
|
|
}
|
2013-05-30 19:36:43 +02:00
|
|
|
|
2020-02-27 11:23:15 +01:00
|
|
|
mesh_build_extra_data(depsgraph, ob, mesh_eval);
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 22:30:33 +02:00
|
|
|
}
|
|
|
|
|
2017-08-16 04:45:11 +02:00
|
|
|
static void editbmesh_build_data(struct Depsgraph *depsgraph,
|
2022-02-14 19:05:54 +01:00
|
|
|
const Scene *scene,
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
Object *obedit,
|
|
|
|
BMEditMesh *em,
|
|
|
|
CustomData_MeshMasks *dataMask)
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 22:30:33 +02:00
|
|
|
{
|
2022-01-11 15:42:07 +01:00
|
|
|
Mesh *mesh = static_cast<Mesh *>(obedit->data);
|
2018-10-09 06:04:51 +02:00
|
|
|
Mesh *me_cage;
|
|
|
|
Mesh *me_final;
|
2020-12-15 12:42:10 +01:00
|
|
|
GeometrySet *non_mesh_components;
|
2018-10-09 06:04:51 +02:00
|
|
|
|
2020-12-15 12:42:10 +01:00
|
|
|
editbmesh_calc_modifiers(
|
|
|
|
depsgraph, scene, obedit, em, dataMask, &me_cage, &me_final, &non_mesh_components);
|
2018-10-09 06:04:51 +02:00
|
|
|
|
2022-01-11 15:42:07 +01:00
|
|
|
/* The modifier stack result is expected to share edit mesh pointer with the input.
|
|
|
|
* This is similar `mesh_calc_finalize()`. */
|
|
|
|
BKE_mesh_free_editmesh(me_final);
|
|
|
|
BKE_mesh_free_editmesh(me_cage);
|
|
|
|
me_final->edit_mesh = me_cage->edit_mesh = em;
|
|
|
|
|
|
|
|
/* Object has edit_mesh but is not in edit mode (object shares mesh datablock with another object
|
|
|
|
* with is in edit mode).
|
|
|
|
* Convert edit mesh to mesh until the draw manager can draw mesh wrapper which is not in the
|
|
|
|
* edit mode. */
|
|
|
|
if (!(obedit->mode & OB_MODE_EDIT)) {
|
|
|
|
BKE_mesh_wrapper_ensure_mdata(me_final);
|
|
|
|
if (me_final != me_cage) {
|
|
|
|
BKE_mesh_wrapper_ensure_mdata(me_cage);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const bool is_mesh_eval_owned = (me_final != mesh->runtime.mesh_eval);
|
|
|
|
BKE_object_eval_assign_data(obedit, &me_final->id, is_mesh_eval_owned);
|
|
|
|
|
|
|
|
obedit->runtime.editmesh_eval_cage = me_cage;
|
|
|
|
|
2020-12-15 12:42:10 +01:00
|
|
|
obedit->runtime.geometry_set_eval = non_mesh_components;
|
2015-07-02 08:20:22 +02:00
|
|
|
|
2022-01-11 15:42:07 +01:00
|
|
|
BKE_object_boundbox_calc_from_mesh(obedit, me_final);
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 05:28:02 +01:00
|
|
|
|
2022-01-11 15:42:07 +01:00
|
|
|
obedit->runtime.last_data_mask = *dataMask;
|
2005-07-19 04:36:21 +02:00
|
|
|
}
|
|
|
|
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
static void object_get_datamask(const Depsgraph *depsgraph,
|
|
|
|
Object *ob,
|
|
|
|
CustomData_MeshMasks *r_mask,
|
|
|
|
bool *r_need_mapping)
|
2013-05-01 16:34:12 +02:00
|
|
|
{
|
2018-04-06 12:07:27 +02:00
|
|
|
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
|
|
|
|
DEG_get_customdata_mask_for_object(depsgraph, ob, r_mask);
|
2015-06-04 17:39:43 +02:00
|
|
|
|
2015-07-02 08:20:22 +02:00
|
|
|
if (r_need_mapping) {
|
|
|
|
*r_need_mapping = false;
|
|
|
|
}
|
2013-05-01 16:34:12 +02:00
|
|
|
|
2019-05-24 10:48:19 +02:00
|
|
|
/* Must never access original objects when dependency graph is not active: it might be already
|
|
|
|
* freed. */
|
2019-05-27 12:39:26 +02:00
|
|
|
if (!DEG_is_active(depsgraph)) {
|
2019-05-24 10:48:19 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-12-14 13:00:28 +01:00
|
|
|
Object *actob = view_layer->basact ? DEG_get_original_object(view_layer->basact->object) :
|
|
|
|
nullptr;
|
2018-06-19 18:29:40 +02:00
|
|
|
if (DEG_get_original_object(ob) == actob) {
|
2018-12-01 10:12:18 +01:00
|
|
|
bool editing = BKE_paint_select_face_test(actob);
|
2015-06-04 17:39:43 +02:00
|
|
|
|
|
|
|
/* weight paint and face select need original indices because of selection buffer drawing */
|
2015-07-02 08:20:22 +02:00
|
|
|
if (r_need_mapping) {
|
2018-04-05 18:20:27 +02:00
|
|
|
*r_need_mapping = (editing || (ob->mode & (OB_MODE_WEIGHT_PAINT | OB_MODE_VERTEX_PAINT)));
|
2015-07-02 08:20:22 +02:00
|
|
|
}
|
2015-06-04 17:39:43 +02:00
|
|
|
|
2013-05-01 16:34:12 +02:00
|
|
|
/* check if we need tfaces & mcols due to face select or texture paint */
|
2018-04-05 18:20:27 +02:00
|
|
|
if ((ob->mode & OB_MODE_TEXTURE_PAINT) || editing) {
|
2022-04-20 16:10:10 +02:00
|
|
|
r_mask->lmask |= CD_MASK_MLOOPUV | CD_MASK_PROP_BYTE_COLOR;
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
r_mask->fmask |= CD_MASK_MTFACE;
|
2013-05-01 16:34:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* check if we need mcols due to vertex paint or weightpaint */
|
2018-04-05 18:20:27 +02:00
|
|
|
if (ob->mode & OB_MODE_VERTEX_PAINT) {
|
2022-04-20 16:10:10 +02:00
|
|
|
r_mask->lmask |= CD_MASK_PROP_BYTE_COLOR;
|
2013-05-01 16:34:12 +02:00
|
|
|
}
|
|
|
|
|
2018-10-09 13:21:23 +02:00
|
|
|
if (ob->mode & OB_MODE_WEIGHT_PAINT) {
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
r_mask->vmask |= CD_MASK_MDEFORMVERT;
|
2018-10-09 13:21:23 +02:00
|
|
|
}
|
|
|
|
|
2019-04-22 01:39:35 +02:00
|
|
|
if (ob->mode & OB_MODE_EDIT) {
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
r_mask->vmask |= CD_MASK_MVERT_SKIN;
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
2013-05-01 16:34:12 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-06 12:07:27 +02:00
|
|
|
void makeDerivedMesh(struct Depsgraph *depsgraph,
|
2022-02-14 19:05:54 +01:00
|
|
|
const Scene *scene,
|
2018-04-06 12:07:27 +02:00
|
|
|
Object *ob,
|
2019-03-27 19:07:16 +01:00
|
|
|
const CustomData_MeshMasks *dataMask)
|
2005-07-19 04:36:21 +02:00
|
|
|
{
|
2022-01-11 15:42:07 +01:00
|
|
|
BLI_assert(ob->type == OB_MESH);
|
|
|
|
|
|
|
|
/* Evaluated meshes aren't supposed to be created on original instances. If you do,
|
|
|
|
* they aren't cleaned up properly on mode switch, causing crashes, e.g T58150. */
|
|
|
|
BLI_assert(ob->id.tag & LIB_TAG_COPIED_ON_WRITE);
|
|
|
|
|
|
|
|
BKE_object_free_derived_caches(ob);
|
|
|
|
if (DEG_is_active(depsgraph)) {
|
|
|
|
BKE_sculpt_update_object_before_eval(ob);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* NOTE: Access the `edit_mesh` after freeing the derived caches, so that `ob->data` is restored
|
|
|
|
* to the pre-evaluated state. This is because the evaluated state is not necessarily sharing the
|
|
|
|
* `edit_mesh` pointer with the input. For example, if the object is first evaluated in the
|
|
|
|
* object mode, and then user in another scene moves object to edit mode. */
|
|
|
|
BMEditMesh *em = ((Mesh *)ob->data)->edit_mesh;
|
|
|
|
|
2015-07-02 08:20:22 +02:00
|
|
|
bool need_mapping;
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
CustomData_MeshMasks cddata_masks = *dataMask;
|
|
|
|
object_get_datamask(depsgraph, ob, &cddata_masks, &need_mapping);
|
2013-05-01 16:34:12 +02:00
|
|
|
|
2008-12-31 18:11:42 +01:00
|
|
|
if (em) {
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
editbmesh_build_data(depsgraph, scene, ob, em, &cddata_masks);
|
2012-03-24 07:18:31 +01:00
|
|
|
}
|
|
|
|
else {
|
2019-03-27 19:07:16 +01:00
|
|
|
mesh_build_data(depsgraph, scene, ob, &cddata_masks, need_mapping);
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 22:30:33 +02:00
|
|
|
}
|
2005-07-19 04:36:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/***/
|
|
|
|
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
Mesh *mesh_get_eval_final(struct Depsgraph *depsgraph,
|
2022-02-14 19:05:54 +01:00
|
|
|
const Scene *scene,
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
Object *ob,
|
|
|
|
const CustomData_MeshMasks *dataMask)
|
2018-06-01 12:34:50 +02:00
|
|
|
{
|
2018-12-03 13:22:19 +01:00
|
|
|
/* This function isn't thread-safe and can't be used during evaluation. */
|
2019-10-10 11:03:58 +02:00
|
|
|
BLI_assert(DEG_is_evaluating(depsgraph) == false);
|
2018-12-03 13:22:19 +01:00
|
|
|
|
|
|
|
/* Evaluated meshes aren't supposed to be created on original instances. If you do,
|
|
|
|
* they aren't cleaned up properly on mode switch, causing crashes, e.g T58150. */
|
|
|
|
BLI_assert(ob->id.tag & LIB_TAG_COPIED_ON_WRITE);
|
|
|
|
|
2018-06-01 12:34:50 +02:00
|
|
|
/* if there's no evaluated mesh or the last data mask used doesn't include
|
|
|
|
* the data we need, rebuild the derived mesh
|
|
|
|
*/
|
|
|
|
bool need_mapping;
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
CustomData_MeshMasks cddata_masks = *dataMask;
|
|
|
|
object_get_datamask(depsgraph, ob, &cddata_masks, &need_mapping);
|
2018-06-01 12:34:50 +02:00
|
|
|
|
2020-02-27 11:23:15 +01:00
|
|
|
Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
|
2020-12-14 13:00:28 +01:00
|
|
|
if ((mesh_eval == nullptr) ||
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
!CustomData_MeshMasks_are_matching(&(ob->runtime.last_data_mask), &cddata_masks) ||
|
2018-12-03 16:09:45 +01:00
|
|
|
(need_mapping && !ob->runtime.last_need_mapping)) {
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
CustomData_MeshMasks_update(&cddata_masks, &ob->runtime.last_data_mask);
|
2022-01-11 15:42:07 +01:00
|
|
|
|
|
|
|
makeDerivedMesh(depsgraph, scene, ob, dataMask);
|
|
|
|
|
2020-02-27 11:23:15 +01:00
|
|
|
mesh_eval = BKE_object_get_evaluated_mesh(ob);
|
2018-06-01 12:34:50 +02:00
|
|
|
}
|
|
|
|
|
2022-02-18 20:21:36 +01:00
|
|
|
BKE_mesh_assert_normals_dirty_or_calculated(mesh_eval);
|
|
|
|
|
2020-02-27 11:23:15 +01:00
|
|
|
return mesh_eval;
|
2018-06-01 12:34:50 +02:00
|
|
|
}
|
2005-07-19 02:21:01 +02:00
|
|
|
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
Mesh *mesh_get_eval_deform(struct Depsgraph *depsgraph,
|
2022-02-14 19:05:54 +01:00
|
|
|
const Scene *scene,
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
Object *ob,
|
|
|
|
const CustomData_MeshMasks *dataMask)
|
2018-06-01 12:34:50 +02:00
|
|
|
{
|
2022-01-11 15:42:07 +01:00
|
|
|
BMEditMesh *em = ((Mesh *)ob->data)->edit_mesh;
|
|
|
|
if (em != nullptr) {
|
|
|
|
/* There is no such a concept as deformed mesh in edit mode.
|
|
|
|
* Explicitly disallow this request so that the evaluated result is not modified with evaluated
|
|
|
|
* result from the wrong mode. */
|
|
|
|
BLI_assert_msg(0, "Request of derformed mesh of object which is in edit mode");
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2018-12-03 13:22:19 +01:00
|
|
|
/* This function isn't thread-safe and can't be used during evaluation. */
|
2019-10-10 11:03:58 +02:00
|
|
|
BLI_assert(DEG_is_evaluating(depsgraph) == false);
|
2018-12-03 13:22:19 +01:00
|
|
|
|
|
|
|
/* Evaluated meshes aren't supposed to be created on original instances. If you do,
|
|
|
|
* they aren't cleaned up properly on mode switch, causing crashes, e.g T58150. */
|
|
|
|
BLI_assert(ob->id.tag & LIB_TAG_COPIED_ON_WRITE);
|
|
|
|
|
2018-06-01 12:34:50 +02:00
|
|
|
/* if there's no derived mesh or the last data mask used doesn't include
|
|
|
|
* the data we need, rebuild the derived mesh
|
|
|
|
*/
|
|
|
|
bool need_mapping;
|
|
|
|
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
CustomData_MeshMasks cddata_masks = *dataMask;
|
|
|
|
object_get_datamask(depsgraph, ob, &cddata_masks, &need_mapping);
|
2018-06-01 12:34:50 +02:00
|
|
|
|
|
|
|
if (!ob->runtime.mesh_deform_eval ||
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
!CustomData_MeshMasks_are_matching(&(ob->runtime.last_data_mask), &cddata_masks) ||
|
2018-12-03 16:09:45 +01:00
|
|
|
(need_mapping && !ob->runtime.last_need_mapping)) {
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
CustomData_MeshMasks_update(&cddata_masks, &ob->runtime.last_data_mask);
|
|
|
|
mesh_build_data(
|
2019-03-27 19:07:16 +01:00
|
|
|
depsgraph, scene, ob, &cddata_masks, need_mapping || ob->runtime.last_need_mapping);
|
2018-06-01 12:34:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return ob->runtime.mesh_deform_eval;
|
|
|
|
}
|
|
|
|
|
2020-08-18 12:58:48 +02:00
|
|
|
Mesh *mesh_create_eval_final(Depsgraph *depsgraph,
|
2022-02-14 19:05:54 +01:00
|
|
|
const Scene *scene,
|
2020-08-20 08:09:48 +02:00
|
|
|
Object *ob,
|
|
|
|
const CustomData_MeshMasks *dataMask)
|
2018-10-12 09:05:26 +02:00
|
|
|
{
|
2021-12-02 17:20:22 +01:00
|
|
|
Mesh *result;
|
2020-12-15 12:42:10 +01:00
|
|
|
mesh_calc_modifiers(
|
2021-12-02 17:20:22 +01:00
|
|
|
depsgraph, scene, ob, true, false, dataMask, -1, false, false, nullptr, &result, nullptr);
|
|
|
|
return result;
|
2018-10-12 09:05:26 +02:00
|
|
|
}
|
2008-07-28 13:01:34 +02:00
|
|
|
|
2018-12-04 23:47:13 +01:00
|
|
|
Mesh *mesh_create_eval_no_deform(Depsgraph *depsgraph,
|
2022-02-14 19:05:54 +01:00
|
|
|
const Scene *scene,
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
Object *ob,
|
2019-03-27 19:07:16 +01:00
|
|
|
const CustomData_MeshMasks *dataMask)
|
2005-07-17 03:18:59 +02:00
|
|
|
{
|
2021-12-02 17:20:22 +01:00
|
|
|
Mesh *result;
|
2020-12-15 12:42:10 +01:00
|
|
|
mesh_calc_modifiers(
|
2021-12-02 17:20:22 +01:00
|
|
|
depsgraph, scene, ob, false, false, dataMask, -1, false, false, nullptr, &result, nullptr);
|
|
|
|
return result;
|
2018-12-04 23:47:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Mesh *mesh_create_eval_no_deform_render(Depsgraph *depsgraph,
|
2022-02-14 19:05:54 +01:00
|
|
|
const Scene *scene,
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
Object *ob,
|
2019-03-27 19:07:16 +01:00
|
|
|
const CustomData_MeshMasks *dataMask)
|
2018-12-04 23:47:13 +01:00
|
|
|
{
|
2021-12-02 17:20:22 +01:00
|
|
|
Mesh *result;
|
2020-12-15 12:42:10 +01:00
|
|
|
mesh_calc_modifiers(
|
2021-12-02 17:20:22 +01:00
|
|
|
depsgraph, scene, ob, false, false, dataMask, -1, false, false, nullptr, &result, nullptr);
|
|
|
|
return result;
|
2005-07-19 02:21:01 +02:00
|
|
|
}
|
2005-04-04 05:38:21 +02:00
|
|
|
|
2005-07-19 02:21:01 +02:00
|
|
|
/***/
|
|
|
|
|
2018-04-06 12:07:27 +02:00
|
|
|
Mesh *editbmesh_get_eval_cage(struct Depsgraph *depsgraph,
|
2022-02-14 19:05:54 +01:00
|
|
|
const Scene *scene,
|
2018-04-06 12:07:27 +02:00
|
|
|
Object *obedit,
|
|
|
|
BMEditMesh *em,
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
const CustomData_MeshMasks *dataMask)
|
2005-03-28 07:58:43 +02:00
|
|
|
{
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
CustomData_MeshMasks cddata_masks = *dataMask;
|
|
|
|
|
2006-12-05 18:42:03 +01:00
|
|
|
/* if there's no derived mesh or the last data mask used doesn't include
|
|
|
|
* the data we need, rebuild the derived mesh
|
|
|
|
*/
|
2020-12-14 13:00:28 +01:00
|
|
|
object_get_datamask(depsgraph, obedit, &cddata_masks, nullptr);
|
2013-05-01 16:34:12 +02:00
|
|
|
|
2022-01-11 15:42:07 +01:00
|
|
|
if (!obedit->runtime.editmesh_eval_cage ||
|
|
|
|
!CustomData_MeshMasks_are_matching(&(obedit->runtime.last_data_mask), &cddata_masks)) {
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
editbmesh_build_data(depsgraph, scene, obedit, em, &cddata_masks);
|
2012-04-28 08:31:57 +02:00
|
|
|
}
|
2005-03-28 07:58:43 +02:00
|
|
|
|
2022-01-11 15:42:07 +01:00
|
|
|
return obedit->runtime.editmesh_eval_cage;
|
2005-03-28 07:58:43 +02:00
|
|
|
}
|
2005-08-06 22:44:59 +02:00
|
|
|
|
2018-12-05 23:38:08 +01:00
|
|
|
Mesh *editbmesh_get_eval_cage_from_orig(struct Depsgraph *depsgraph,
|
2022-02-14 19:05:54 +01:00
|
|
|
const Scene *scene,
|
2018-12-05 23:38:08 +01:00
|
|
|
Object *obedit,
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
const CustomData_MeshMasks *dataMask)
|
2018-12-05 23:38:08 +01:00
|
|
|
{
|
|
|
|
BLI_assert((obedit->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0);
|
2022-02-14 19:05:54 +01:00
|
|
|
const Scene *scene_eval = (const Scene *)DEG_get_evaluated_id(depsgraph, (ID *)&scene->id);
|
2018-12-05 23:38:08 +01:00
|
|
|
Object *obedit_eval = (Object *)DEG_get_evaluated_id(depsgraph, &obedit->id);
|
|
|
|
BMEditMesh *em_eval = BKE_editmesh_from_object(obedit_eval);
|
|
|
|
return editbmesh_get_eval_cage(depsgraph, scene_eval, obedit_eval, em_eval, dataMask);
|
|
|
|
}
|
|
|
|
|
2014-08-01 15:42:17 +02:00
|
|
|
/***/
|
|
|
|
|
2014-09-04 09:53:10 +02:00
|
|
|
/* same as above but for vert coords */
|
2020-12-14 13:00:28 +01:00
|
|
|
struct MappedUserData {
|
2014-09-04 09:53:10 +02:00
|
|
|
float (*vertexcos)[3];
|
|
|
|
BLI_bitmap *vertex_visit;
|
2020-12-14 13:00:28 +01:00
|
|
|
};
|
2014-09-04 09:53:10 +02:00
|
|
|
|
2015-07-02 08:20:22 +02:00
|
|
|
static void make_vertexcos__mapFunc(void *userData,
|
|
|
|
int index,
|
|
|
|
const float co[3],
|
Refactor: Move normals out of MVert, lazy calculation
As described in T91186, this commit moves mesh vertex normals into a
contiguous array of float vectors in a custom data layer, how face
normals are currently stored.
The main interface is documented in `BKE_mesh.h`. Vertex and face
normals are now calculated on-demand and cached, retrieved with an
"ensure" function. Since the logical state of a mesh is now "has
normals when necessary", they can be retrieved from a `const` mesh.
The goal is to use on-demand calculation for all derived data, but
leave room for eager calculation for performance purposes (modifier
evaluation is threaded, but viewport data generation is not).
**Benefits**
This moves us closer to a SoA approach rather than the current AoS
paradigm. Accessing a contiguous `float3` is much more efficient than
retrieving data from a larger struct. The memory requirements for
accessing only normals or vertex locations are smaller, and at the
cost of more memory usage for just normals, they now don't have to
be converted between float and short, which also simplifies code
In the future, the remaining items can be removed from `MVert`,
leaving only `float3`, which has similar benefits (see T93602).
Removing the combination of derived and original data makes it
conceptually simpler to only calculate normals when necessary.
This is especially important now that we have more opportunities
for temporary meshes in geometry nodes.
**Performance**
In addition to the theoretical future performance improvements by
making `MVert == float3`, I've done some basic performance testing
on this patch directly. The data is fairly rough, but it gives an idea
about where things stand generally.
- Mesh line primitive 4m Verts: 1.16x faster (36 -> 31 ms),
showing that accessing just `MVert` is now more efficient.
- Spring Splash Screen: 1.03-1.06 -> 1.06-1.11 FPS, a very slight
change that at least shows there is no regression.
- Sprite Fright Snail Smoosh: 3.30-3.40 -> 3.42-3.50 FPS, a small
but observable speedup.
- Set Position Node with Scaled Normal: 1.36x faster (53 -> 39 ms),
shows that using normals in geometry nodes is faster.
- Normal Calculation 1.6m Vert Cube: 1.19x faster (25 -> 21 ms),
shows that calculating normals is slightly faster now.
- File Size of 1.6m Vert Cube: 1.03x smaller (214.7 -> 208.4 MB),
Normals are not saved in files, which can help with large meshes.
As for memory usage, it may be slightly more in some cases, but
I didn't observe any difference in the production files I tested.
**Tests**
Some modifiers and cycles test results need to be updated with this
commit, for two reasons:
- The subdivision surface modifier is not responsible for calculating
normals anymore. In master, the modifier creates different normals
than the result of the `Mesh` normal calculation, so this is a bug
fix.
- There are small differences in the results of some modifiers that
use normals because they are not converted to and from `short`
anymore.
**Future improvements**
- Remove `ModifierTypeInfo::dependsOnNormals`. Code in each modifier
already retrieves normals if they are needed anyway.
- Copy normals as part of a better CoW system for attributes.
- Make more areas use lazy instead of eager normal calculation.
- Remove `BKE_mesh_normals_tag_dirty` in more places since that is
now the default state of a new mesh.
- Possibly apply a similar change to derived face corner normals.
Differential Revision: https://developer.blender.org/D12770
2022-01-13 21:37:58 +01:00
|
|
|
const float UNUSED(no[3]))
|
2014-09-04 09:53:10 +02:00
|
|
|
{
|
|
|
|
MappedUserData *mappedData = (MappedUserData *)userData;
|
|
|
|
|
|
|
|
if (BLI_BITMAP_TEST(mappedData->vertex_visit, index) == 0) {
|
|
|
|
/* we need coord from prototype vertex, not from copies,
|
|
|
|
* assume they stored in the beginning of vertex array stored in DM
|
|
|
|
* (mirror modifier for eg does this) */
|
|
|
|
copy_v3_v3(mappedData->vertexcos[index], co);
|
|
|
|
BLI_BITMAP_ENABLE(mappedData->vertex_visit, index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-09 07:52:46 +02:00
|
|
|
void mesh_get_mapped_verts_coords(Mesh *me_eval, float (*r_cos)[3], const int totcos)
|
2014-09-04 09:53:10 +02:00
|
|
|
{
|
2018-10-09 07:52:46 +02:00
|
|
|
if (me_eval->runtime.deformed_only == false) {
|
2014-09-04 09:53:10 +02:00
|
|
|
MappedUserData userData;
|
2014-09-14 10:50:59 +02:00
|
|
|
memset(r_cos, 0, sizeof(*r_cos) * totcos);
|
2014-09-04 09:53:10 +02:00
|
|
|
userData.vertexcos = r_cos;
|
|
|
|
userData.vertex_visit = BLI_BITMAP_NEW(totcos, "vertexcos flags");
|
2018-10-09 07:52:46 +02:00
|
|
|
BKE_mesh_foreach_mapped_vert(me_eval, make_vertexcos__mapFunc, &userData, MESH_FOREACH_NOP);
|
2014-09-04 09:53:10 +02:00
|
|
|
MEM_freeN(userData.vertex_visit);
|
|
|
|
}
|
|
|
|
else {
|
2018-10-09 07:52:46 +02:00
|
|
|
MVert *mv = me_eval->mvert;
|
|
|
|
for (int i = 0; i < totcos; i++, mv++) {
|
|
|
|
copy_v3_v3(r_cos[i], mv->co);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2014-09-04 09:53:10 +02:00
|
|
|
}
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-11 09:53:52 +02:00
|
|
|
static void mesh_init_origspace(Mesh *mesh)
|
|
|
|
{
|
|
|
|
const float default_osf[4][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-14 13:00:28 +01:00
|
|
|
OrigSpaceLoop *lof_array = (OrigSpaceLoop *)CustomData_get_layer(&mesh->ldata,
|
|
|
|
CD_ORIGSPACE_MLOOP);
|
2018-05-11 09:53:52 +02:00
|
|
|
const int numpoly = mesh->totpoly;
|
|
|
|
// const int numloop = mesh->totloop;
|
|
|
|
MVert *mv = mesh->mvert;
|
|
|
|
MLoop *ml = mesh->mloop;
|
|
|
|
MPoly *mp = mesh->mpoly;
|
|
|
|
int i, j, k;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-14 13:00:28 +01:00
|
|
|
blender::Vector<blender::float2, 64> vcos_2d;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-11 09:53:52 +02:00
|
|
|
for (i = 0; i < numpoly; i++, mp++) {
|
|
|
|
OrigSpaceLoop *lof = lof_array + mp->loopstart;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-06 02:30:59 +01:00
|
|
|
if (ELEM(mp->totloop, 3, 4)) {
|
2018-05-11 09:53:52 +02:00
|
|
|
for (j = 0; j < mp->totloop; j++, lof++) {
|
|
|
|
copy_v2_v2(lof->uv, default_osf[j]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
MLoop *l = &ml[mp->loopstart];
|
|
|
|
float p_nor[3], co[3];
|
|
|
|
float mat[3][3];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-11 09:53:52 +02:00
|
|
|
float min[2] = {FLT_MAX, FLT_MAX}, max[2] = {-FLT_MAX, -FLT_MAX};
|
|
|
|
float translate[2], scale[2];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-11 09:53:52 +02:00
|
|
|
BKE_mesh_calc_poly_normal(mp, l, mv, p_nor);
|
|
|
|
axis_dominant_v3_to_m3(mat, p_nor);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-14 13:00:28 +01:00
|
|
|
vcos_2d.resize(mp->totloop);
|
2018-05-11 09:53:52 +02:00
|
|
|
for (j = 0; j < mp->totloop; j++, l++) {
|
|
|
|
mul_v3_m3v3(co, mat, mv[l->v].co);
|
|
|
|
copy_v2_v2(vcos_2d[j], co);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-11 09:53:52 +02:00
|
|
|
for (k = 0; k < 2; k++) {
|
2019-04-22 01:39:35 +02:00
|
|
|
if (co[k] > max[k]) {
|
2018-05-11 09:53:52 +02:00
|
|
|
max[k] = co[k];
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
|
|
|
else if (co[k] < min[k]) {
|
2018-05-11 09:53:52 +02:00
|
|
|
min[k] = co[k];
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
2018-05-11 09:53:52 +02:00
|
|
|
}
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-11 09:53:52 +02:00
|
|
|
/* Brings min to (0, 0). */
|
|
|
|
negate_v2_v2(translate, min);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-11 09:53:52 +02:00
|
|
|
/* Scale will bring max to (1, 1). */
|
|
|
|
sub_v2_v2v2(scale, max, min);
|
2019-04-22 01:39:35 +02:00
|
|
|
if (scale[0] == 0.0f) {
|
2018-05-11 09:53:52 +02:00
|
|
|
scale[0] = 1e-9f;
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
|
|
|
if (scale[1] == 0.0f) {
|
2018-05-11 09:53:52 +02:00
|
|
|
scale[1] = 1e-9f;
|
2019-04-22 01:39:35 +02:00
|
|
|
}
|
2018-05-11 09:53:52 +02:00
|
|
|
invert_v2(scale);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-27 04:07:07 +02:00
|
|
|
/* Finally, transform all vcos_2d into ((0, 0), (1, 1))
|
|
|
|
* square and assign them as origspace. */
|
2018-05-11 09:53:52 +02:00
|
|
|
for (j = 0; j < mp->totloop; j++, lof++) {
|
|
|
|
add_v2_v2v2(lof->uv, vcos_2d[j], translate);
|
|
|
|
mul_v2_v2(lof->uv, scale);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-22 17:53:18 +02:00
|
|
|
BKE_mesh_tessface_clear(mesh);
|
2018-05-11 09:53:52 +02:00
|
|
|
}
|