Blender V5.0
subdiv_disabler.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
5
6#include "BLI_listbase.h"
7
8#include "DEG_depsgraph.hh"
10
11#include "DNA_layer_types.h"
12#include "DNA_mesh_types.h"
13#include "DNA_modifier_types.h"
14#include "DNA_object_types.h"
15
16#include "BKE_layer.hh"
17#include "BKE_modifier.hh"
18
19namespace blender::io {
20
22 const Object *ob,
23 ModifierMode mode)
24{
25 /* Returns the last subdiv modifier associated with an object,
26 * if that modifier should be disabled.
27 * We do not disable the subdiv modifier if other modifiers are
28 * applied after it, with the sole exception of particle modifiers,
29 * which are allowed.
30 * Returns nullptr if there is not any subdiv modifier to disable.
31 */
32
33 ModifierData *md = static_cast<ModifierData *>(ob->modifiers.last);
34
35 for (; md; md = md->prev) {
36 /* Ignore disabled modifiers. */
37 if (!BKE_modifier_is_enabled(scene, md, mode)) {
38 continue;
39 }
40
41 if (md->type == eModifierType_Subsurf) {
42 SubsurfModifierData *smd = reinterpret_cast<SubsurfModifierData *>(md);
43
44 if (smd->subdivType == ME_CC_SUBSURF) {
45 /* This is a Catmull-Clark modifier. */
46 return md;
47 }
48
49 /* Not Catmull-Clark, so ignore it. */
50 return nullptr;
51 }
52
53 /* If any modifier other than a particle system exists after the
54 * subdiv modifier, then abort. */
56 return nullptr;
57 }
58 }
59
60 return nullptr;
61}
62
64
66{
67 /* Enable previously disabled modifiers. */
68 for (ModifierData *modifier : disabled_modifiers_) {
70 }
71
72 /* Update object to render with restored modifiers in the viewport. */
73 for (Object *object : modified_objects_) {
75 }
76}
77
79{
80 eEvaluationMode eval_mode = DEG_get_mode(depsgraph_);
81 const ModifierMode mode = eval_mode == DAG_EVAL_VIEWPORT ? eModifierMode_Realtime :
83
84 Scene *scene = DEG_get_input_scene(depsgraph_);
85 ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph_);
86
87 BKE_view_layer_synced_ensure(scene, view_layer);
89 Object *object = base->object;
90
91 if (object->type != OB_MESH) {
92 continue;
93 }
94
95 /* Check if a subdiv modifier exists, and should be disabled. */
96 ModifierData *mod = get_subdiv_modifier(scene, object, mode);
97 if (!mod) {
98 continue;
99 }
100
101 /* This might disable more modifiers than necessary, as it doesn't take restrictions like
102 * "export selected objects only" into account. However, with the subdivisions disabled,
103 * moving to a different frame is also going to be faster, so in the end this is probably
104 * a good thing to do. */
105 disable_modifier(mod);
106 modified_objects_.append(object);
108 }
109}
110
111void SubdivModifierDisabler::disable_modifier(ModifierData *mod)
112{
114 disabled_modifiers_.append(mod);
115}
116
117} // namespace blender::io
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
ListBase * BKE_view_layer_object_bases_get(ViewLayer *view_layer)
bool BKE_modifier_is_enabled(const Scene *scene, ModifierData *md, int required_mode)
#define LISTBASE_FOREACH(type, var, list)
void DEG_id_tag_update(ID *id, unsigned int flags)
eEvaluationMode
@ DAG_EVAL_VIEWPORT
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
ViewLayer * DEG_get_input_view_layer(const Depsgraph *graph)
Scene * DEG_get_input_scene(const Depsgraph *graph)
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1074
@ ME_CC_SUBSURF
@ eModifierMode_Render
@ eModifierMode_DisableTemporary
@ eModifierMode_Realtime
@ eModifierType_ParticleSystem
@ eModifierType_Subsurf
Object is a sort of wrapper for general info.
@ OB_MESH
BPy_StructRNA * depsgraph
void append(const T &value)
SubdivModifierDisabler(Depsgraph *depsgraph)
static ModifierData * get_subdiv_modifier(Scene *scene, const Object *ob, ModifierMode mode)
VecBase< float, D > constexpr mod(VecOp< float, D >, VecOp< float, D >) RET
void * last
struct ModifierData * prev
ListBase modifiers