Files
test/source/blender/blenkernel/intern/object_dupli.cc

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

1631 lines
49 KiB
C++
Raw Normal View History

/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2001-2002 NaN Holding BV. All rights reserved. */
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
/** \file
* \ingroup bke
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
*/
#include <climits>
#include <cstddef>
#include <cstdlib>
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
#include "MEM_guardedalloc.h"
#include "BLI_listbase.h"
#include "BLI_string_utf8.h"
#include "BLI_array.hh"
#include "BLI_float4x4.hh"
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +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"
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
#include "BLI_rand.h"
#include "BLI_span.hh"
#include "BLI_vector.hh"
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
#include "DNA_anim_types.h"
#include "DNA_collection_types.h"
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_pointcloud_types.h"
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
#include "DNA_scene_types.h"
#include "DNA_vfont_types.h"
Collections and groups unification OVERVIEW * In 2.7 terminology, all layers and groups are now collection datablocks. * These collections are nestable, linkable, instanceable, overrideable, .. which opens up new ways to set up scenes and link + override data. * Viewport/render visibility and selectability are now a part of the collection and shared across all view layers and linkable. * View layers define which subset of the scene collection hierarchy is excluded for each. For many workflows one view layer can be used, these are more of an advanced feature now. OUTLINER * The outliner now has a "View Layer" display mode instead of "Collections", which can display the collections and/or objects in the view layer. * In this display mode, collections can be excluded with the right click menu. These will then be greyed out and their objects will be excluded. * To view collections not linked to any scene, the "Blender File" display mode can be used, with the new filtering option to just see Colleciton datablocks. * The outliner right click menus for collections and objects were reorganized. * Drag and drop still needs to be improved. Like before, dragging the icon or text gives different results, we'll unify this later. LINKING AND OVERRIDES * Collections can now be linked into the scene without creating an instance, with the link/append operator or from the collections view in the outliner. * Collections can get static overrides with the right click menu in the outliner, but this is rather unreliable and not clearly communicated at the moment. * We still need to improve the make override operator to turn collection instances into collections with overrides directly in the scene. PERFORMANCE * We tried to make performance not worse than before and improve it in some cases. The main thing that's still a bit slower is multiple scenes, we have to change the layer syncing to only updated affected scenes. * Collections keep a list of their parent collections for faster incremental updates in syncing and caching. * View layer bases are now in a object -> base hash to avoid quadratic time lookups internally and in API functions like visible_get(). VERSIONING * Compatibility with 2.7 files should be improved due to the new visibility controls. Of course users may not want to set up their scenes differently now to avoid having separate layers and groups. * Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero files. There's a few things which are know to be not quite compatible, like nested layer collections inside groups. * The versioning code for 2.8 files is quite complicated, and isolated behind #ifdef so it can be removed at the end of the release cycle. KNOWN ISSUES * The G-key group operators in the 3D viewport were left mostly as is, they need to be modified still to fit better. * Same for the groups panel in the object properties. This needs to be updated still, or perhaps replaced by something better. * Collections must all have a unique name. Less restrictive namespacing is to be done later, we'll have to see how important this is as all objects within the collections must also have a unique name anyway. * Full scene copy and delete scene are exactly doing the right thing yet. Differential Revision: https://developer.blender.org/D3383 https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
#include "BKE_collection.h"
#include "BKE_duplilist.h"
#include "BKE_editmesh.h"
#include "BKE_editmesh_cache.h"
Geometry Nodes: initial scattering and geometry nodes This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix
2020-12-02 13:25:25 +01:00
#include "BKE_geometry_set.h"
#include "BKE_geometry_set.hh"
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
#include "BKE_global.h"
#include "BKE_idprop.h"
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
#include "BKE_lattice.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_mesh_iterators.h"
#include "BKE_mesh_runtime.h"
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
#include "BKE_object.h"
#include "BKE_particle.h"
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
#include "BKE_scene.h"
#include "BKE_vfont.h"
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
#include "BLI_hash.h"
#include "BLI_strict_flags.h"
using blender::Array;
using blender::float3;
using blender::float4x4;
using blender::Span;
using blender::Vector;
/* -------------------------------------------------------------------- */
/** \name Internal Duplicate Context
* \{ */
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
struct DupliContext {
Depsgraph *depsgraph;
/** XXX child objects are selected from this group if set, could be nicer. */
Collection *collection;
/** Only to check if the object is in edit-mode. */
Object *obedit;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
Scene *scene;
Object *object;
float space_mat[4][4];
/**
* A stack that contains all the "parent" objects of a particular instance when recursive
* instancing is used. This is used to prevent objects from instancing themselves accidentally.
* Use a vector instead of a stack because we want to use the #contains method.
*/
Vector<Object *> *instance_stack;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
int persistent_id[MAX_DUPLI_RECUR];
int level;
const struct DupliGenerator *gen;
/** Result containers. */
ListBase *duplilist; /* Legacy doubly-linked list. */
};
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
struct DupliGenerator {
short type; /* Dupli Type, see members of #OB_DUPLI. */
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
void (*make_duplis)(const DupliContext *ctx);
};
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
static const DupliGenerator *get_dupli_generator(const DupliContext *ctx);
/**
* Create initial context for root object.
*/
2019-09-14 08:10:50 +10:00
static void init_context(DupliContext *r_ctx,
Depsgraph *depsgraph,
Scene *scene,
Object *ob,
const float space_mat[4][4],
Vector<Object *> &instance_stack)
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
{
r_ctx->depsgraph = depsgraph;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
r_ctx->scene = scene;
r_ctx->collection = nullptr;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
r_ctx->object = ob;
r_ctx->obedit = OBEDIT_FROM_OBACT(ob);
r_ctx->instance_stack = &instance_stack;
if (space_mat) {
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
copy_m4_m4(r_ctx->space_mat, space_mat);
}
else {
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
unit_m4(r_ctx->space_mat);
}
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
r_ctx->level = 0;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
r_ctx->gen = get_dupli_generator(r_ctx);
r_ctx->duplilist = nullptr;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
/**
* Create sub-context for recursive duplis.
*/
static bool copy_dupli_context(
2019-09-14 08:10:50 +10:00
DupliContext *r_ctx, const DupliContext *ctx, Object *ob, const float mat[4][4], int index)
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
{
*r_ctx = *ctx;
2018-06-17 17:05:51 +02:00
/* XXX annoying, previously was done by passing an ID* argument,
* this at least is more explicit. */
if (ctx->gen->type == OB_DUPLICOLLECTION) {
r_ctx->collection = ctx->object->instance_collection;
}
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
r_ctx->object = ob;
r_ctx->instance_stack = ctx->instance_stack;
if (mat) {
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
mul_m4_m4m4(r_ctx->space_mat, (float(*)[4])ctx->space_mat, mat);
}
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
r_ctx->persistent_id[r_ctx->level] = index;
++r_ctx->level;
if (r_ctx->level == MAX_DUPLI_RECUR - 1) {
std::cerr << "Warning: Maximum instance recursion level reached.\n";
return false;
}
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
r_ctx->gen = get_dupli_generator(r_ctx);
return true;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
/**
* Generate a dupli instance.
*
* \param mat: is transform of the object relative to current context (including #Object.obmat).
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
*/
static DupliObject *make_dupli(const DupliContext *ctx,
Object *ob,
const float mat[4][4],
int index)
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
{
DupliObject *dob;
int i;
/* Add a #DupliObject instance to the result container. */
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
if (ctx->duplilist) {
dob = MEM_cnew<DupliObject>("dupli object");
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
BLI_addtail(ctx->duplilist, dob);
}
else {
return nullptr;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
dob->ob = ob;
Geometry Nodes: support for geometry instancing Previously, the Point Instance node in geometry nodes could only instance existing objects or collections. The reason was that large parts of Blender worked under the assumption that objects are the main unit of instancing. Now we also want to instance geometry within an object, so a slightly larger refactor was necessary. This should not affect files that do not use the new kind of instances. The main change is a redefinition of what "instanced data" is. Now, an instances is a cow-object + object-data (the geometry). This can be nicely seen in `struct DupliObject`. This allows the same object to generate multiple geometries of different types which can be instanced individually. A nice side effect of this refactor is that having multiple geometry components is not a special case in the depsgraph object iterator anymore, because those components are integrated with the `DupliObject` system. Unfortunately, different systems that work with instances in Blender (e.g. render engines and exporters) often work under the assumption that objects are the main unit of instancing. So those have to be updated as well to be able to handle the new instances. This patch updates Cycles, EEVEE and other viewport engines. Exporters have not been updated yet. Some minimal (not master-ready) changes to update the obj and alembic exporters can be found in P2336 and P2335. Different file formats may want to handle these new instances in different ways. For users, the only thing that changed is that the Point Instance node now has a geometry mode. This also fixes T88454. Differential Revision: https://developer.blender.org/D11841
2021-09-06 18:22:24 +02:00
dob->ob_data = (ID *)ob->data;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
mul_m4_m4m4(dob->mat, (float(*)[4])ctx->space_mat, mat);
dob->type = ctx->gen->type;
/* Set persistent id, which is an array with a persistent index for each level
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
* (particle number, vertex number, ..). by comparing this we can find the same
* dupli-object between frames, which is needed for motion blur.
* The last level is ordered first in the array. */
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
dob->persistent_id[0] = index;
for (i = 1; i < ctx->level + 1; i++) {
dob->persistent_id[i] = ctx->persistent_id[ctx->level - i];
}
/* Fill rest of values with #INT_MAX which index will never have as value. */
for (; i < MAX_DUPLI_RECUR; i++) {
dob->persistent_id[i] = INT_MAX;
}
/* Meta-balls never draw in duplis, they are instead merged into one by the basis
* meta-ball outside of the group. this does mean that if that meta-ball is not in the
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
* scene, they will not show up at all, limitation that should be solved once. */
if (ob->type == OB_MBALL) {
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
dob->no_draw = true;
}
/* Random number.
* The logic here is designed to match Cycles. */
dob->random_id = BLI_hash_string(dob->ob->id.name + 2);
if (dob->persistent_id[0] != INT_MAX) {
for (i = 0; i < MAX_DUPLI_RECUR; i++) {
dob->random_id = BLI_hash_int_2d(dob->random_id, (unsigned int)dob->persistent_id[i]);
2017-04-24 21:58:28 +10:00
}
}
else {
dob->random_id = BLI_hash_int_2d(dob->random_id, 0);
}
if (ctx->object != ob) {
dob->random_id ^= BLI_hash_int(BLI_hash_string(ctx->object->id.name + 2));
}
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
return dob;
}
/**
* Recursive dupli-objects.
*
* \param space_mat: is the local dupli-space (excluding dupli #Object.obmat).
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
*/
static void make_recursive_duplis(const DupliContext *ctx,
Object *ob,
2019-09-14 08:10:50 +10:00
const float space_mat[4][4],
int index)
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
{
if (ctx->instance_stack->contains(ob)) {
/* Avoid recursive instances. */
printf("Warning: '%s' object is trying to instance itself.\n", ob->id.name + 2);
return;
}
/* Simple preventing of too deep nested collections with #MAX_DUPLI_RECUR. */
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
if (ctx->level < MAX_DUPLI_RECUR) {
DupliContext rctx;
if (!copy_dupli_context(&rctx, ctx, ob, space_mat, index)) {
return;
}
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
if (rctx.gen) {
ctx->instance_stack->append(ob);
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
rctx.gen->make_duplis(&rctx);
ctx->instance_stack->remove_last();
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Internal Child Duplicates (Used by Other Functions)
* \{ */
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
using MakeChildDuplisFunc = void (*)(const DupliContext *ctx, void *userdata, Object *child);
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
static bool is_child(const Object *ob, const Object *parent)
{
const Object *ob_parent = ob->parent;
while (ob_parent) {
if (ob_parent == parent) {
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
return true;
}
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
ob_parent = ob_parent->parent;
}
return false;
}
/**
* Create duplis from every child in scene or collection.
*/
static void make_child_duplis(const DupliContext *ctx,
void *userdata,
MakeChildDuplisFunc make_child_duplis_cb)
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
{
Object *parent = ctx->object;
Collections and groups unification OVERVIEW * In 2.7 terminology, all layers and groups are now collection datablocks. * These collections are nestable, linkable, instanceable, overrideable, .. which opens up new ways to set up scenes and link + override data. * Viewport/render visibility and selectability are now a part of the collection and shared across all view layers and linkable. * View layers define which subset of the scene collection hierarchy is excluded for each. For many workflows one view layer can be used, these are more of an advanced feature now. OUTLINER * The outliner now has a "View Layer" display mode instead of "Collections", which can display the collections and/or objects in the view layer. * In this display mode, collections can be excluded with the right click menu. These will then be greyed out and their objects will be excluded. * To view collections not linked to any scene, the "Blender File" display mode can be used, with the new filtering option to just see Colleciton datablocks. * The outliner right click menus for collections and objects were reorganized. * Drag and drop still needs to be improved. Like before, dragging the icon or text gives different results, we'll unify this later. LINKING AND OVERRIDES * Collections can now be linked into the scene without creating an instance, with the link/append operator or from the collections view in the outliner. * Collections can get static overrides with the right click menu in the outliner, but this is rather unreliable and not clearly communicated at the moment. * We still need to improve the make override operator to turn collection instances into collections with overrides directly in the scene. PERFORMANCE * We tried to make performance not worse than before and improve it in some cases. The main thing that's still a bit slower is multiple scenes, we have to change the layer syncing to only updated affected scenes. * Collections keep a list of their parent collections for faster incremental updates in syncing and caching. * View layer bases are now in a object -> base hash to avoid quadratic time lookups internally and in API functions like visible_get(). VERSIONING * Compatibility with 2.7 files should be improved due to the new visibility controls. Of course users may not want to set up their scenes differently now to avoid having separate layers and groups. * Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero files. There's a few things which are know to be not quite compatible, like nested layer collections inside groups. * The versioning code for 2.8 files is quite complicated, and isolated behind #ifdef so it can be removed at the end of the release cycle. KNOWN ISSUES * The G-key group operators in the 3D viewport were left mostly as is, they need to be modified still to fit better. * Same for the groups panel in the object properties. This needs to be updated still, or perhaps replaced by something better. * Collections must all have a unique name. Less restrictive namespacing is to be done later, we'll have to see how important this is as all objects within the collections must also have a unique name anyway. * Full scene copy and delete scene are exactly doing the right thing yet. Differential Revision: https://developer.blender.org/D3383 https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
if (ctx->collection) {
eEvaluationMode mode = DEG_get_mode(ctx->depsgraph);
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (ctx->collection, ob, mode) {
if ((ob != ctx->obedit) && is_child(ob, parent)) {
DupliContext pctx;
if (copy_dupli_context(&pctx, ctx, ctx->object, nullptr, _base_id)) {
/* Meta-balls have a different dupli handling. */
if (ob->type != OB_MBALL) {
ob->flag |= OB_DONE; /* Doesn't render. */
}
make_child_duplis_cb(&pctx, userdata, ob);
}
}
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
else {
/* FIXME: using a mere counter to generate a 'persistent' dupli id is very weak. One possible
* better solution could be to use `session_uuid` of ID's instead? */
int persistent_dupli_id = 0;
/* NOTE: this set of flags ensure we only iterate over objects that have a base in either the
* current scene, or the set (background) scene. */
int deg_objects_visibility_flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET;
DEG_OBJECT_ITER_BEGIN (ctx->depsgraph, ob, deg_objects_visibility_flags) {
if ((ob != ctx->obedit) && is_child(ob, parent)) {
DupliContext pctx;
if (copy_dupli_context(&pctx, ctx, ctx->object, nullptr, persistent_dupli_id)) {
/* Meta-balls have a different dupli-handling. */
if (ob->type != OB_MBALL) {
ob->flag |= OB_DONE; /* Doesn't render. */
}
make_child_duplis_cb(&pctx, userdata, ob);
}
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
persistent_dupli_id++;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
DEG_OBJECT_ITER_END;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Internal Data Access Utilities
* \{ */
static const Mesh *mesh_data_from_duplicator_object(Object *ob,
BMEditMesh **r_em,
const float (**r_vert_coords)[3],
const float (**r_vert_normals)[3])
{
/* Gather mesh info. */
BMEditMesh *em = BKE_editmesh_from_object(ob);
const Mesh *me_eval;
*r_em = nullptr;
*r_vert_coords = nullptr;
if (r_vert_normals != nullptr) {
*r_vert_normals = nullptr;
}
/* We do not need any render-specific handling anymore, depsgraph takes care of that. */
/* NOTE: Do direct access to the evaluated mesh: this function is used
* during meta balls evaluation. But even without those all the objects
* which are needed for correct instancing are already evaluated. */
if (em != nullptr) {
/* Note that this will only show deformation if #eModifierMode_OnCage is enabled.
* We could change this but it matches 2.7x behavior. */
Fix depsgraphs sharing IDs via evaluated edit mesh The evaluated mesh is a result of evaluated modifiers, and referencing other evaluated IDs such as materials. It can not be stored in the EditMesh structure which is intended to be re-used by many areas. Such sharing was causing ownership errors causing bugs like T93855: Cycles crash with edit mode and simultaneous viewport and final render The proposed solution is to store the evaluated edit mesh and its cage in the object's runtime field. The motivation goes as following: - It allows to avoid ownership problems like the ones in the linked report. - Object level is chosen over mesh level is because the evaluated mesh is affected by modifiers, which are on the object level. This patch allows to have modifier stack of an object which shares mesh with an object which is in edit mode to be properly taken into account (before the change the modifier stack from the active object will be used for all objects which share the mesh). There is a change in the way how copy-on-write is handled in the edit mode to allow proper state update when changing active scene (or having two windows with different scenes). Previously, the copt-on-write would have been ignored by skipping tagging CoW component. Now it is ignored from within the CoW operation callback. This allows to update edit pointers for objects which are not from the current depsgraph and where the edit_mesh was never assigned in the case when the depsgraph was evaluated prior the active depsgraph. There is no user level changes changes expected with the CoW handling changes: should not affect on neither performance, nor memory consumption. Tested scenarios: - Various modifiers configurations of objects sharing mesh and be part of the same scene. - Steps from the reports: T93855, T82952, T77359 This also fixes T76609, T72733 and perhaps other reports. Differential Revision: https://developer.blender.org/D13824
2022-01-11 15:42:07 +01:00
me_eval = BKE_object_get_editmesh_eval_cage(ob);
if ((me_eval == nullptr) || (me_eval->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH)) {
EditMeshData *emd = me_eval ? me_eval->runtime.edit_data : nullptr;
/* Only assign edit-mesh in the case we can't use `me_eval`. */
*r_em = em;
me_eval = nullptr;
if ((emd != nullptr) && (emd->vertexCos != nullptr)) {
*r_vert_coords = emd->vertexCos;
if (r_vert_normals != nullptr) {
BKE_editmesh_cache_ensure_vert_normals(em, emd);
*r_vert_normals = emd->vertexNos;
}
}
}
}
else {
me_eval = BKE_object_get_evaluated_mesh(ob);
}
return me_eval;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Dupli-Collection Implementation (#OB_DUPLICOLLECTION)
* \{ */
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
Collections and groups unification OVERVIEW * In 2.7 terminology, all layers and groups are now collection datablocks. * These collections are nestable, linkable, instanceable, overrideable, .. which opens up new ways to set up scenes and link + override data. * Viewport/render visibility and selectability are now a part of the collection and shared across all view layers and linkable. * View layers define which subset of the scene collection hierarchy is excluded for each. For many workflows one view layer can be used, these are more of an advanced feature now. OUTLINER * The outliner now has a "View Layer" display mode instead of "Collections", which can display the collections and/or objects in the view layer. * In this display mode, collections can be excluded with the right click menu. These will then be greyed out and their objects will be excluded. * To view collections not linked to any scene, the "Blender File" display mode can be used, with the new filtering option to just see Colleciton datablocks. * The outliner right click menus for collections and objects were reorganized. * Drag and drop still needs to be improved. Like before, dragging the icon or text gives different results, we'll unify this later. LINKING AND OVERRIDES * Collections can now be linked into the scene without creating an instance, with the link/append operator or from the collections view in the outliner. * Collections can get static overrides with the right click menu in the outliner, but this is rather unreliable and not clearly communicated at the moment. * We still need to improve the make override operator to turn collection instances into collections with overrides directly in the scene. PERFORMANCE * We tried to make performance not worse than before and improve it in some cases. The main thing that's still a bit slower is multiple scenes, we have to change the layer syncing to only updated affected scenes. * Collections keep a list of their parent collections for faster incremental updates in syncing and caching. * View layer bases are now in a object -> base hash to avoid quadratic time lookups internally and in API functions like visible_get(). VERSIONING * Compatibility with 2.7 files should be improved due to the new visibility controls. Of course users may not want to set up their scenes differently now to avoid having separate layers and groups. * Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero files. There's a few things which are know to be not quite compatible, like nested layer collections inside groups. * The versioning code for 2.8 files is quite complicated, and isolated behind #ifdef so it can be removed at the end of the release cycle. KNOWN ISSUES * The G-key group operators in the 3D viewport were left mostly as is, they need to be modified still to fit better. * Same for the groups panel in the object properties. This needs to be updated still, or perhaps replaced by something better. * Collections must all have a unique name. Less restrictive namespacing is to be done later, we'll have to see how important this is as all objects within the collections must also have a unique name anyway. * Full scene copy and delete scene are exactly doing the right thing yet. Differential Revision: https://developer.blender.org/D3383 https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
static void make_duplis_collection(const DupliContext *ctx)
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
{
Object *ob = ctx->object;
Collections and groups unification OVERVIEW * In 2.7 terminology, all layers and groups are now collection datablocks. * These collections are nestable, linkable, instanceable, overrideable, .. which opens up new ways to set up scenes and link + override data. * Viewport/render visibility and selectability are now a part of the collection and shared across all view layers and linkable. * View layers define which subset of the scene collection hierarchy is excluded for each. For many workflows one view layer can be used, these are more of an advanced feature now. OUTLINER * The outliner now has a "View Layer" display mode instead of "Collections", which can display the collections and/or objects in the view layer. * In this display mode, collections can be excluded with the right click menu. These will then be greyed out and their objects will be excluded. * To view collections not linked to any scene, the "Blender File" display mode can be used, with the new filtering option to just see Colleciton datablocks. * The outliner right click menus for collections and objects were reorganized. * Drag and drop still needs to be improved. Like before, dragging the icon or text gives different results, we'll unify this later. LINKING AND OVERRIDES * Collections can now be linked into the scene without creating an instance, with the link/append operator or from the collections view in the outliner. * Collections can get static overrides with the right click menu in the outliner, but this is rather unreliable and not clearly communicated at the moment. * We still need to improve the make override operator to turn collection instances into collections with overrides directly in the scene. PERFORMANCE * We tried to make performance not worse than before and improve it in some cases. The main thing that's still a bit slower is multiple scenes, we have to change the layer syncing to only updated affected scenes. * Collections keep a list of their parent collections for faster incremental updates in syncing and caching. * View layer bases are now in a object -> base hash to avoid quadratic time lookups internally and in API functions like visible_get(). VERSIONING * Compatibility with 2.7 files should be improved due to the new visibility controls. Of course users may not want to set up their scenes differently now to avoid having separate layers and groups. * Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero files. There's a few things which are know to be not quite compatible, like nested layer collections inside groups. * The versioning code for 2.8 files is quite complicated, and isolated behind #ifdef so it can be removed at the end of the release cycle. KNOWN ISSUES * The G-key group operators in the 3D viewport were left mostly as is, they need to be modified still to fit better. * Same for the groups panel in the object properties. This needs to be updated still, or perhaps replaced by something better. * Collections must all have a unique name. Less restrictive namespacing is to be done later, we'll have to see how important this is as all objects within the collections must also have a unique name anyway. * Full scene copy and delete scene are exactly doing the right thing yet. Differential Revision: https://developer.blender.org/D3383 https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
Collection *collection;
float collection_mat[4][4];
if (ob->instance_collection == nullptr) {
return;
}
collection = ob->instance_collection;
/* Combine collection offset and `obmat`. */
Collections and groups unification OVERVIEW * In 2.7 terminology, all layers and groups are now collection datablocks. * These collections are nestable, linkable, instanceable, overrideable, .. which opens up new ways to set up scenes and link + override data. * Viewport/render visibility and selectability are now a part of the collection and shared across all view layers and linkable. * View layers define which subset of the scene collection hierarchy is excluded for each. For many workflows one view layer can be used, these are more of an advanced feature now. OUTLINER * The outliner now has a "View Layer" display mode instead of "Collections", which can display the collections and/or objects in the view layer. * In this display mode, collections can be excluded with the right click menu. These will then be greyed out and their objects will be excluded. * To view collections not linked to any scene, the "Blender File" display mode can be used, with the new filtering option to just see Colleciton datablocks. * The outliner right click menus for collections and objects were reorganized. * Drag and drop still needs to be improved. Like before, dragging the icon or text gives different results, we'll unify this later. LINKING AND OVERRIDES * Collections can now be linked into the scene without creating an instance, with the link/append operator or from the collections view in the outliner. * Collections can get static overrides with the right click menu in the outliner, but this is rather unreliable and not clearly communicated at the moment. * We still need to improve the make override operator to turn collection instances into collections with overrides directly in the scene. PERFORMANCE * We tried to make performance not worse than before and improve it in some cases. The main thing that's still a bit slower is multiple scenes, we have to change the layer syncing to only updated affected scenes. * Collections keep a list of their parent collections for faster incremental updates in syncing and caching. * View layer bases are now in a object -> base hash to avoid quadratic time lookups internally and in API functions like visible_get(). VERSIONING * Compatibility with 2.7 files should be improved due to the new visibility controls. Of course users may not want to set up their scenes differently now to avoid having separate layers and groups. * Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero files. There's a few things which are know to be not quite compatible, like nested layer collections inside groups. * The versioning code for 2.8 files is quite complicated, and isolated behind #ifdef so it can be removed at the end of the release cycle. KNOWN ISSUES * The G-key group operators in the 3D viewport were left mostly as is, they need to be modified still to fit better. * Same for the groups panel in the object properties. This needs to be updated still, or perhaps replaced by something better. * Collections must all have a unique name. Less restrictive namespacing is to be done later, we'll have to see how important this is as all objects within the collections must also have a unique name anyway. * Full scene copy and delete scene are exactly doing the right thing yet. Differential Revision: https://developer.blender.org/D3383 https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
unit_m4(collection_mat);
sub_v3_v3(collection_mat[3], collection->instance_offset);
Collections and groups unification OVERVIEW * In 2.7 terminology, all layers and groups are now collection datablocks. * These collections are nestable, linkable, instanceable, overrideable, .. which opens up new ways to set up scenes and link + override data. * Viewport/render visibility and selectability are now a part of the collection and shared across all view layers and linkable. * View layers define which subset of the scene collection hierarchy is excluded for each. For many workflows one view layer can be used, these are more of an advanced feature now. OUTLINER * The outliner now has a "View Layer" display mode instead of "Collections", which can display the collections and/or objects in the view layer. * In this display mode, collections can be excluded with the right click menu. These will then be greyed out and their objects will be excluded. * To view collections not linked to any scene, the "Blender File" display mode can be used, with the new filtering option to just see Colleciton datablocks. * The outliner right click menus for collections and objects were reorganized. * Drag and drop still needs to be improved. Like before, dragging the icon or text gives different results, we'll unify this later. LINKING AND OVERRIDES * Collections can now be linked into the scene without creating an instance, with the link/append operator or from the collections view in the outliner. * Collections can get static overrides with the right click menu in the outliner, but this is rather unreliable and not clearly communicated at the moment. * We still need to improve the make override operator to turn collection instances into collections with overrides directly in the scene. PERFORMANCE * We tried to make performance not worse than before and improve it in some cases. The main thing that's still a bit slower is multiple scenes, we have to change the layer syncing to only updated affected scenes. * Collections keep a list of their parent collections for faster incremental updates in syncing and caching. * View layer bases are now in a object -> base hash to avoid quadratic time lookups internally and in API functions like visible_get(). VERSIONING * Compatibility with 2.7 files should be improved due to the new visibility controls. Of course users may not want to set up their scenes differently now to avoid having separate layers and groups. * Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero files. There's a few things which are know to be not quite compatible, like nested layer collections inside groups. * The versioning code for 2.8 files is quite complicated, and isolated behind #ifdef so it can be removed at the end of the release cycle. KNOWN ISSUES * The G-key group operators in the 3D viewport were left mostly as is, they need to be modified still to fit better. * Same for the groups panel in the object properties. This needs to be updated still, or perhaps replaced by something better. * Collections must all have a unique name. Less restrictive namespacing is to be done later, we'll have to see how important this is as all objects within the collections must also have a unique name anyway. * Full scene copy and delete scene are exactly doing the right thing yet. Differential Revision: https://developer.blender.org/D3383 https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
mul_m4_m4m4(collection_mat, ob->obmat, collection_mat);
/* Don't access 'ob->obmat' from now on. */
eEvaluationMode mode = DEG_get_mode(ctx->depsgraph);
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (collection, cob, mode) {
if (cob != ob) {
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
float mat[4][4];
/* Collection dupli-offset, should apply after everything else. */
mul_m4_m4m4(mat, collection_mat, cob->obmat);
make_dupli(ctx, cob, mat, _base_id);
/* Recursion. */
make_recursive_duplis(ctx, cob, collection_mat, _base_id);
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
}
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
Collections and groups unification OVERVIEW * In 2.7 terminology, all layers and groups are now collection datablocks. * These collections are nestable, linkable, instanceable, overrideable, .. which opens up new ways to set up scenes and link + override data. * Viewport/render visibility and selectability are now a part of the collection and shared across all view layers and linkable. * View layers define which subset of the scene collection hierarchy is excluded for each. For many workflows one view layer can be used, these are more of an advanced feature now. OUTLINER * The outliner now has a "View Layer" display mode instead of "Collections", which can display the collections and/or objects in the view layer. * In this display mode, collections can be excluded with the right click menu. These will then be greyed out and their objects will be excluded. * To view collections not linked to any scene, the "Blender File" display mode can be used, with the new filtering option to just see Colleciton datablocks. * The outliner right click menus for collections and objects were reorganized. * Drag and drop still needs to be improved. Like before, dragging the icon or text gives different results, we'll unify this later. LINKING AND OVERRIDES * Collections can now be linked into the scene without creating an instance, with the link/append operator or from the collections view in the outliner. * Collections can get static overrides with the right click menu in the outliner, but this is rather unreliable and not clearly communicated at the moment. * We still need to improve the make override operator to turn collection instances into collections with overrides directly in the scene. PERFORMANCE * We tried to make performance not worse than before and improve it in some cases. The main thing that's still a bit slower is multiple scenes, we have to change the layer syncing to only updated affected scenes. * Collections keep a list of their parent collections for faster incremental updates in syncing and caching. * View layer bases are now in a object -> base hash to avoid quadratic time lookups internally and in API functions like visible_get(). VERSIONING * Compatibility with 2.7 files should be improved due to the new visibility controls. Of course users may not want to set up their scenes differently now to avoid having separate layers and groups. * Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero files. There's a few things which are know to be not quite compatible, like nested layer collections inside groups. * The versioning code for 2.8 files is quite complicated, and isolated behind #ifdef so it can be removed at the end of the release cycle. KNOWN ISSUES * The G-key group operators in the 3D viewport were left mostly as is, they need to be modified still to fit better. * Same for the groups panel in the object properties. This needs to be updated still, or perhaps replaced by something better. * Collections must all have a unique name. Less restrictive namespacing is to be done later, we'll have to see how important this is as all objects within the collections must also have a unique name anyway. * Full scene copy and delete scene are exactly doing the right thing yet. Differential Revision: https://developer.blender.org/D3383 https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
static const DupliGenerator gen_dupli_collection = {
OB_DUPLICOLLECTION, /* type */
make_duplis_collection /* make_duplis */
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
};
/** \} */
/* -------------------------------------------------------------------- */
/** \name Dupli-Vertices Implementation (#OB_DUPLIVERTS for Geometry)
* \{ */
/** Values shared between different mesh types. */
struct VertexDupliData_Params {
/**
* It's important we use this context instead of the `ctx` passed into #make_child_duplis
* since these won't match in the case of recursion.
*/
const DupliContext *ctx;
bool use_rotation;
};
struct VertexDupliData_Mesh {
VertexDupliData_Params params;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
int totvert;
const MVert *mvert;
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 14:37:58 -06:00
const float (*vert_normals)[3];
const float (*orco)[3];
};
struct VertexDupliData_EditMesh {
VertexDupliData_Params params;
BMEditMesh *em;
/* Can be nullptr. */
const float (*vert_coords)[3];
const float (*vert_normals)[3];
/**
* \note The edit-mesh may assign #DupliObject.orco in cases when a regular mesh wouldn't.
* For edit-meshes we only check for deformation, for regular meshes we check if #CD_ORCO exists.
*
* At the moment this isn't a meaningful difference since requesting #CD_ORCO causes the
* edit-mesh to be converted into a mesh.
*/
bool has_orco;
};
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
/**
* \param no: The direction,
* currently this is copied from a `short[3]` normal without division.
* Can be null when \a use_rotation is false.
*/
static void get_duplivert_transform(const float co[3],
const float no[3],
const bool use_rotation,
const short axis,
const short upflag,
float r_mat[4][4])
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
{
float quat[4];
const float size[3] = {1.0f, 1.0f, 1.0f};
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
if (use_rotation) {
/* Construct rotation matrix from normals. */
float no_flip[3];
negate_v3_v3(no_flip, no);
vec_to_quat(quat, no_flip, axis, upflag);
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
else {
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
unit_qt(quat);
}
loc_quat_size_to_mat4(r_mat, co, quat, size);
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
static DupliObject *vertex_dupli(const DupliContext *ctx,
Object *inst_ob,
const float child_imat[4][4],
int index,
const float co[3],
const float no[3],
const bool use_rotation)
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
{
/* `obmat` is transform to vertex. */
float obmat[4][4];
get_duplivert_transform(co, no, use_rotation, inst_ob->trackflag, inst_ob->upflag, obmat);
float space_mat[4][4];
/* Make offset relative to inst_ob using relative child transform. */
mul_mat3_m4_v3(child_imat, obmat[3]);
/* Apply `obmat` _after_ the local vertex transform. */
mul_m4_m4m4(obmat, inst_ob->obmat, obmat);
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
/* Space matrix is constructed by removing `obmat` transform,
* this yields the world-space transform for recursive duplis. */
mul_m4_m4m4(space_mat, obmat, inst_ob->imat);
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
DupliObject *dob = make_dupli(ctx, inst_ob, obmat, index);
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
/* Recursion. */
make_recursive_duplis(ctx, inst_ob, space_mat, index);
return dob;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
static void make_child_duplis_verts_from_mesh(const DupliContext *ctx,
void *userdata,
Object *inst_ob)
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
{
VertexDupliData_Mesh *vdd = (VertexDupliData_Mesh *)userdata;
const bool use_rotation = vdd->params.use_rotation;
const MVert *mvert = vdd->mvert;
const int totvert = vdd->totvert;
invert_m4_m4(inst_ob->imat, inst_ob->obmat);
/* Relative transform from parent to child space. */
float child_imat[4][4];
mul_m4_m4m4(child_imat, inst_ob->imat, ctx->object->obmat);
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 14:37:58 -06:00
for (int i = 0; i < totvert; i++) {
DupliObject *dob = vertex_dupli(
vdd->params.ctx, inst_ob, child_imat, i, mvert[i].co, vdd->vert_normals[i], use_rotation);
if (vdd->orco) {
copy_v3_v3(dob->orco, vdd->orco[i]);
}
}
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
static void make_child_duplis_verts_from_editmesh(const DupliContext *ctx,
void *userdata,
Object *inst_ob)
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
{
VertexDupliData_EditMesh *vdd = (VertexDupliData_EditMesh *)userdata;
BMEditMesh *em = vdd->em;
const bool use_rotation = vdd->params.use_rotation;
invert_m4_m4(inst_ob->imat, inst_ob->obmat);
/* Relative transform from parent to child space. */
float child_imat[4][4];
mul_m4_m4m4(child_imat, inst_ob->imat, ctx->object->obmat);
BMVert *v;
BMIter iter;
int i;
const float(*vert_coords)[3] = vdd->vert_coords;
const float(*vert_normals)[3] = vdd->vert_normals;
BM_ITER_MESH_INDEX (v, &iter, em->bm, BM_VERTS_OF_MESH, i) {
const float *co, *no;
if (vert_coords != nullptr) {
co = vert_coords[i];
no = vert_normals ? vert_normals[i] : nullptr;
}
else {
co = v->co;
no = v->no;
}
DupliObject *dob = vertex_dupli(vdd->params.ctx, inst_ob, child_imat, i, co, no, use_rotation);
if (vdd->has_orco) {
copy_v3_v3(dob->orco, v->co);
}
}
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
static void make_duplis_verts(const DupliContext *ctx)
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
{
Object *parent = ctx->object;
const bool use_rotation = parent->transflag & OB_DUPLIROT;
/* Gather mesh info. */
BMEditMesh *em = nullptr;
const float(*vert_coords)[3] = nullptr;
const float(*vert_normals)[3] = nullptr;
const Mesh *me_eval = mesh_data_from_duplicator_object(
parent, &em, &vert_coords, use_rotation ? &vert_normals : nullptr);
if (em == nullptr && me_eval == nullptr) {
return;
}
VertexDupliData_Params vdd_params{ctx, use_rotation};
if (em != nullptr) {
VertexDupliData_EditMesh vdd{};
vdd.params = vdd_params;
vdd.em = em;
vdd.vert_coords = vert_coords;
vdd.vert_normals = vert_normals;
vdd.has_orco = (vert_coords != nullptr);
make_child_duplis(ctx, &vdd, make_child_duplis_verts_from_editmesh);
}
else {
VertexDupliData_Mesh vdd{};
vdd.params = vdd_params;
vdd.totvert = me_eval->totvert;
vdd.mvert = me_eval->mvert;
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 14:37:58 -06:00
vdd.vert_normals = BKE_mesh_vertex_normals_ensure(me_eval);
vdd.orco = (const float(*)[3])CustomData_get_layer(&me_eval->vdata, CD_ORCO);
make_child_duplis(ctx, &vdd, make_child_duplis_verts_from_mesh);
}
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
static const DupliGenerator gen_dupli_verts = {
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
OB_DUPLIVERTS, /* type */
make_duplis_verts /* make_duplis */
};
/** \} */
/* -------------------------------------------------------------------- */
/** \name Dupli-Vertices Implementation (#OB_DUPLIVERTS for 3D Text)
* \{ */
static Object *find_family_object(
Main *bmain, const char *family, size_t family_len, unsigned int ch, GHash *family_gh)
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
{
void *ch_key = POINTER_FROM_UINT(ch);
Object **ob_pt;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
if ((ob_pt = (Object **)BLI_ghash_lookup_p(family_gh, ch_key))) {
return *ob_pt;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
char ch_utf8[BLI_UTF8_MAX + 1];
size_t ch_utf8_len;
ch_utf8_len = BLI_str_utf8_from_unicode(ch, ch_utf8, sizeof(ch_utf8) - 1);
ch_utf8[ch_utf8_len] = '\0';
ch_utf8_len += 1; /* Compare with null terminator. */
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
if (STREQLEN(ob->id.name + 2 + family_len, ch_utf8, ch_utf8_len)) {
if (STREQLEN(ob->id.name + 2, family, family_len)) {
/* Inserted value can be nullptr, just to save searches in future. */
BLI_ghash_insert(family_gh, ch_key, ob);
return ob;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
}
}
return nullptr;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
static void make_duplis_font(const DupliContext *ctx)
{
Object *par = ctx->object;
GHash *family_gh;
Object *ob;
Curve *cu;
struct CharTrans *ct, *chartransdata = nullptr;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
float vec[3], obmat[4][4], pmat[4][4], fsize, xof, yof;
int text_len, a;
size_t family_len;
const char32_t *text = nullptr;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
bool text_free = false;
/* Font dupli-verts not supported inside collections. */
if (ctx->collection) {
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
return;
}
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
copy_m4_m4(pmat, par->obmat);
/* In `par` the family name is stored, use this to find the other objects. */
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
BKE_vfont_to_curve_ex(
par, (Curve *)par->data, FO_DUPLI, nullptr, &text, &text_len, &text_free, &chartransdata);
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
if (text == nullptr || chartransdata == nullptr) {
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
return;
}
cu = (Curve *)par->data;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
fsize = cu->fsize;
xof = cu->xof;
yof = cu->yof;
ct = chartransdata;
/* Cache result. */
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
family_len = strlen(cu->family);
family_gh = BLI_ghash_int_new_ex(__func__, 256);
/* Safety check even if it might fail badly when called for original object. */
const bool is_eval_curve = DEG_is_evaluated_id(&cu->id);
/* Advance matching BLI_str_utf8_as_utf32. */
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
for (a = 0; a < text_len; a++, ct++) {
/* XXX That G.main is *really* ugly, but not sure what to do here.
* Definitively don't think it would be safe to put back `Main *bmain` pointer
* in #DupliContext as done in 2.7x? */
ob = find_family_object(G.main, cu->family, family_len, (unsigned int)text[a], family_gh);
if (is_eval_curve) {
/* Workaround for the above hack. */
ob = DEG_get_evaluated_object(ctx->depsgraph, ob);
}
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
if (ob) {
vec[0] = fsize * (ct->xof - xof);
vec[1] = fsize * (ct->yof - yof);
vec[2] = 0.0;
mul_m4_v3(pmat, vec);
copy_m4_m4(obmat, par->obmat);
if (UNLIKELY(ct->rot != 0.0f)) {
float rmat[4][4];
zero_v3(obmat[3]);
axis_angle_to_mat4_single(rmat, 'Z', -ct->rot);
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
mul_m4_m4m4(obmat, obmat, rmat);
}
copy_v3_v3(obmat[3], vec);
make_dupli(ctx, ob, obmat, a);
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
}
if (text_free) {
MEM_freeN((void *)text);
}
BLI_ghash_free(family_gh, nullptr, nullptr);
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
MEM_freeN(chartransdata);
}
static const DupliGenerator gen_dupli_verts_font = {
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
OB_DUPLIVERTS, /* type */
make_duplis_font /* make_duplis */
};
/** \} */
Geometry Nodes: initial scattering and geometry nodes This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix
2020-12-02 13:25:25 +01:00
/* -------------------------------------------------------------------- */
/** \name Instances Geometry Component Implementation
* \{ */
Geometry Nodes: support for geometry instancing Previously, the Point Instance node in geometry nodes could only instance existing objects or collections. The reason was that large parts of Blender worked under the assumption that objects are the main unit of instancing. Now we also want to instance geometry within an object, so a slightly larger refactor was necessary. This should not affect files that do not use the new kind of instances. The main change is a redefinition of what "instanced data" is. Now, an instances is a cow-object + object-data (the geometry). This can be nicely seen in `struct DupliObject`. This allows the same object to generate multiple geometries of different types which can be instanced individually. A nice side effect of this refactor is that having multiple geometry components is not a special case in the depsgraph object iterator anymore, because those components are integrated with the `DupliObject` system. Unfortunately, different systems that work with instances in Blender (e.g. render engines and exporters) often work under the assumption that objects are the main unit of instancing. So those have to be updated as well to be able to handle the new instances. This patch updates Cycles, EEVEE and other viewport engines. Exporters have not been updated yet. Some minimal (not master-ready) changes to update the obj and alembic exporters can be found in P2336 and P2335. Different file formats may want to handle these new instances in different ways. For users, the only thing that changed is that the Point Instance node now has a geometry mode. This also fixes T88454. Differential Revision: https://developer.blender.org/D11841
2021-09-06 18:22:24 +02:00
static void make_duplis_geometry_set_impl(const DupliContext *ctx,
const GeometrySet &geometry_set,
const float parent_transform[4][4],
bool geometry_set_is_instance)
Geometry Nodes: initial scattering and geometry nodes This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix
2020-12-02 13:25:25 +01:00
{
Geometry Nodes: support for geometry instancing Previously, the Point Instance node in geometry nodes could only instance existing objects or collections. The reason was that large parts of Blender worked under the assumption that objects are the main unit of instancing. Now we also want to instance geometry within an object, so a slightly larger refactor was necessary. This should not affect files that do not use the new kind of instances. The main change is a redefinition of what "instanced data" is. Now, an instances is a cow-object + object-data (the geometry). This can be nicely seen in `struct DupliObject`. This allows the same object to generate multiple geometries of different types which can be instanced individually. A nice side effect of this refactor is that having multiple geometry components is not a special case in the depsgraph object iterator anymore, because those components are integrated with the `DupliObject` system. Unfortunately, different systems that work with instances in Blender (e.g. render engines and exporters) often work under the assumption that objects are the main unit of instancing. So those have to be updated as well to be able to handle the new instances. This patch updates Cycles, EEVEE and other viewport engines. Exporters have not been updated yet. Some minimal (not master-ready) changes to update the obj and alembic exporters can be found in P2336 and P2335. Different file formats may want to handle these new instances in different ways. For users, the only thing that changed is that the Point Instance node now has a geometry mode. This also fixes T88454. Differential Revision: https://developer.blender.org/D11841
2021-09-06 18:22:24 +02:00
int component_index = 0;
if (ctx->object->type != OB_MESH || geometry_set_is_instance) {
if (const Mesh *mesh = geometry_set.get_mesh_for_read()) {
Geometry Nodes: support for geometry instancing Previously, the Point Instance node in geometry nodes could only instance existing objects or collections. The reason was that large parts of Blender worked under the assumption that objects are the main unit of instancing. Now we also want to instance geometry within an object, so a slightly larger refactor was necessary. This should not affect files that do not use the new kind of instances. The main change is a redefinition of what "instanced data" is. Now, an instances is a cow-object + object-data (the geometry). This can be nicely seen in `struct DupliObject`. This allows the same object to generate multiple geometries of different types which can be instanced individually. A nice side effect of this refactor is that having multiple geometry components is not a special case in the depsgraph object iterator anymore, because those components are integrated with the `DupliObject` system. Unfortunately, different systems that work with instances in Blender (e.g. render engines and exporters) often work under the assumption that objects are the main unit of instancing. So those have to be updated as well to be able to handle the new instances. This patch updates Cycles, EEVEE and other viewport engines. Exporters have not been updated yet. Some minimal (not master-ready) changes to update the obj and alembic exporters can be found in P2336 and P2335. Different file formats may want to handle these new instances in different ways. For users, the only thing that changed is that the Point Instance node now has a geometry mode. This also fixes T88454. Differential Revision: https://developer.blender.org/D11841
2021-09-06 18:22:24 +02:00
DupliObject *dupli = make_dupli(ctx, ctx->object, parent_transform, component_index++);
dupli->ob_data = (ID *)mesh;
}
}
if (ctx->object->type != OB_VOLUME || geometry_set_is_instance) {
if (const Volume *volume = geometry_set.get_volume_for_read()) {
Geometry Nodes: support for geometry instancing Previously, the Point Instance node in geometry nodes could only instance existing objects or collections. The reason was that large parts of Blender worked under the assumption that objects are the main unit of instancing. Now we also want to instance geometry within an object, so a slightly larger refactor was necessary. This should not affect files that do not use the new kind of instances. The main change is a redefinition of what "instanced data" is. Now, an instances is a cow-object + object-data (the geometry). This can be nicely seen in `struct DupliObject`. This allows the same object to generate multiple geometries of different types which can be instanced individually. A nice side effect of this refactor is that having multiple geometry components is not a special case in the depsgraph object iterator anymore, because those components are integrated with the `DupliObject` system. Unfortunately, different systems that work with instances in Blender (e.g. render engines and exporters) often work under the assumption that objects are the main unit of instancing. So those have to be updated as well to be able to handle the new instances. This patch updates Cycles, EEVEE and other viewport engines. Exporters have not been updated yet. Some minimal (not master-ready) changes to update the obj and alembic exporters can be found in P2336 and P2335. Different file formats may want to handle these new instances in different ways. For users, the only thing that changed is that the Point Instance node now has a geometry mode. This also fixes T88454. Differential Revision: https://developer.blender.org/D11841
2021-09-06 18:22:24 +02:00
DupliObject *dupli = make_dupli(ctx, ctx->object, parent_transform, component_index++);
dupli->ob_data = (ID *)volume;
}
}
if (!ELEM(ctx->object->type, OB_CURVES_LEGACY, OB_FONT, OB_CURVES) || geometry_set_is_instance) {
if (const CurveComponent *component = geometry_set.get_component_for_read<CurveComponent>()) {
if (const Curve *curve = component->get_curve_for_render()) {
Geometry Nodes: support for geometry instancing Previously, the Point Instance node in geometry nodes could only instance existing objects or collections. The reason was that large parts of Blender worked under the assumption that objects are the main unit of instancing. Now we also want to instance geometry within an object, so a slightly larger refactor was necessary. This should not affect files that do not use the new kind of instances. The main change is a redefinition of what "instanced data" is. Now, an instances is a cow-object + object-data (the geometry). This can be nicely seen in `struct DupliObject`. This allows the same object to generate multiple geometries of different types which can be instanced individually. A nice side effect of this refactor is that having multiple geometry components is not a special case in the depsgraph object iterator anymore, because those components are integrated with the `DupliObject` system. Unfortunately, different systems that work with instances in Blender (e.g. render engines and exporters) often work under the assumption that objects are the main unit of instancing. So those have to be updated as well to be able to handle the new instances. This patch updates Cycles, EEVEE and other viewport engines. Exporters have not been updated yet. Some minimal (not master-ready) changes to update the obj and alembic exporters can be found in P2336 and P2335. Different file formats may want to handle these new instances in different ways. For users, the only thing that changed is that the Point Instance node now has a geometry mode. This also fixes T88454. Differential Revision: https://developer.blender.org/D11841
2021-09-06 18:22:24 +02:00
DupliObject *dupli = make_dupli(ctx, ctx->object, parent_transform, component_index++);
dupli->ob_data = (ID *)curve;
}
}
}
if (ctx->object->type != OB_POINTCLOUD || geometry_set_is_instance) {
if (const PointCloud *pointcloud = geometry_set.get_pointcloud_for_read()) {
Geometry Nodes: support for geometry instancing Previously, the Point Instance node in geometry nodes could only instance existing objects or collections. The reason was that large parts of Blender worked under the assumption that objects are the main unit of instancing. Now we also want to instance geometry within an object, so a slightly larger refactor was necessary. This should not affect files that do not use the new kind of instances. The main change is a redefinition of what "instanced data" is. Now, an instances is a cow-object + object-data (the geometry). This can be nicely seen in `struct DupliObject`. This allows the same object to generate multiple geometries of different types which can be instanced individually. A nice side effect of this refactor is that having multiple geometry components is not a special case in the depsgraph object iterator anymore, because those components are integrated with the `DupliObject` system. Unfortunately, different systems that work with instances in Blender (e.g. render engines and exporters) often work under the assumption that objects are the main unit of instancing. So those have to be updated as well to be able to handle the new instances. This patch updates Cycles, EEVEE and other viewport engines. Exporters have not been updated yet. Some minimal (not master-ready) changes to update the obj and alembic exporters can be found in P2336 and P2335. Different file formats may want to handle these new instances in different ways. For users, the only thing that changed is that the Point Instance node now has a geometry mode. This also fixes T88454. Differential Revision: https://developer.blender.org/D11841
2021-09-06 18:22:24 +02:00
DupliObject *dupli = make_dupli(ctx, ctx->object, parent_transform, component_index++);
dupli->ob_data = (ID *)pointcloud;
}
}
const bool creates_duplis_for_components = component_index >= 1;
const InstancesComponent *component = geometry_set.get_component_for_read<InstancesComponent>();
if (component == nullptr) {
return;
}
Geometry Nodes: initial scattering and geometry nodes This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix
2020-12-02 13:25:25 +01:00
Geometry Nodes: support for geometry instancing Previously, the Point Instance node in geometry nodes could only instance existing objects or collections. The reason was that large parts of Blender worked under the assumption that objects are the main unit of instancing. Now we also want to instance geometry within an object, so a slightly larger refactor was necessary. This should not affect files that do not use the new kind of instances. The main change is a redefinition of what "instanced data" is. Now, an instances is a cow-object + object-data (the geometry). This can be nicely seen in `struct DupliObject`. This allows the same object to generate multiple geometries of different types which can be instanced individually. A nice side effect of this refactor is that having multiple geometry components is not a special case in the depsgraph object iterator anymore, because those components are integrated with the `DupliObject` system. Unfortunately, different systems that work with instances in Blender (e.g. render engines and exporters) often work under the assumption that objects are the main unit of instancing. So those have to be updated as well to be able to handle the new instances. This patch updates Cycles, EEVEE and other viewport engines. Exporters have not been updated yet. Some minimal (not master-ready) changes to update the obj and alembic exporters can be found in P2336 and P2335. Different file formats may want to handle these new instances in different ways. For users, the only thing that changed is that the Point Instance node now has a geometry mode. This also fixes T88454. Differential Revision: https://developer.blender.org/D11841
2021-09-06 18:22:24 +02:00
const DupliContext *instances_ctx = ctx;
/* Create a sub-context if some duplis were created above. This is to avoid dupli id collisions
* between the instances component below and the other components above. */
DupliContext new_instances_ctx;
if (creates_duplis_for_components) {
if (!copy_dupli_context(&new_instances_ctx, ctx, ctx->object, nullptr, component_index)) {
return;
}
Geometry Nodes: support for geometry instancing Previously, the Point Instance node in geometry nodes could only instance existing objects or collections. The reason was that large parts of Blender worked under the assumption that objects are the main unit of instancing. Now we also want to instance geometry within an object, so a slightly larger refactor was necessary. This should not affect files that do not use the new kind of instances. The main change is a redefinition of what "instanced data" is. Now, an instances is a cow-object + object-data (the geometry). This can be nicely seen in `struct DupliObject`. This allows the same object to generate multiple geometries of different types which can be instanced individually. A nice side effect of this refactor is that having multiple geometry components is not a special case in the depsgraph object iterator anymore, because those components are integrated with the `DupliObject` system. Unfortunately, different systems that work with instances in Blender (e.g. render engines and exporters) often work under the assumption that objects are the main unit of instancing. So those have to be updated as well to be able to handle the new instances. This patch updates Cycles, EEVEE and other viewport engines. Exporters have not been updated yet. Some minimal (not master-ready) changes to update the obj and alembic exporters can be found in P2336 and P2335. Different file formats may want to handle these new instances in different ways. For users, the only thing that changed is that the Point Instance node now has a geometry mode. This also fixes T88454. Differential Revision: https://developer.blender.org/D11841
2021-09-06 18:22:24 +02:00
instances_ctx = &new_instances_ctx;
}
Span<float4x4> instance_offset_matrices = component->instance_transforms();
Span<int> instance_reference_handles = component->instance_reference_handles();
Span<int> almost_unique_ids = component->almost_unique_ids();
Span<InstanceReference> references = component->references();
for (int64_t i : instance_offset_matrices.index_range()) {
const InstanceReference &reference = references[instance_reference_handles[i]];
const int id = almost_unique_ids[i];
switch (reference.type()) {
case InstanceReference::Type::Object: {
Object &object = reference.object();
float matrix[4][4];
Geometry Nodes: support for geometry instancing Previously, the Point Instance node in geometry nodes could only instance existing objects or collections. The reason was that large parts of Blender worked under the assumption that objects are the main unit of instancing. Now we also want to instance geometry within an object, so a slightly larger refactor was necessary. This should not affect files that do not use the new kind of instances. The main change is a redefinition of what "instanced data" is. Now, an instances is a cow-object + object-data (the geometry). This can be nicely seen in `struct DupliObject`. This allows the same object to generate multiple geometries of different types which can be instanced individually. A nice side effect of this refactor is that having multiple geometry components is not a special case in the depsgraph object iterator anymore, because those components are integrated with the `DupliObject` system. Unfortunately, different systems that work with instances in Blender (e.g. render engines and exporters) often work under the assumption that objects are the main unit of instancing. So those have to be updated as well to be able to handle the new instances. This patch updates Cycles, EEVEE and other viewport engines. Exporters have not been updated yet. Some minimal (not master-ready) changes to update the obj and alembic exporters can be found in P2336 and P2335. Different file formats may want to handle these new instances in different ways. For users, the only thing that changed is that the Point Instance node now has a geometry mode. This also fixes T88454. Differential Revision: https://developer.blender.org/D11841
2021-09-06 18:22:24 +02:00
mul_m4_m4m4(matrix, parent_transform, instance_offset_matrices[i].values);
make_dupli(instances_ctx, &object, matrix, id);
float space_matrix[4][4];
mul_m4_m4m4(space_matrix, instance_offset_matrices[i].values, object.imat);
Geometry Nodes: support for geometry instancing Previously, the Point Instance node in geometry nodes could only instance existing objects or collections. The reason was that large parts of Blender worked under the assumption that objects are the main unit of instancing. Now we also want to instance geometry within an object, so a slightly larger refactor was necessary. This should not affect files that do not use the new kind of instances. The main change is a redefinition of what "instanced data" is. Now, an instances is a cow-object + object-data (the geometry). This can be nicely seen in `struct DupliObject`. This allows the same object to generate multiple geometries of different types which can be instanced individually. A nice side effect of this refactor is that having multiple geometry components is not a special case in the depsgraph object iterator anymore, because those components are integrated with the `DupliObject` system. Unfortunately, different systems that work with instances in Blender (e.g. render engines and exporters) often work under the assumption that objects are the main unit of instancing. So those have to be updated as well to be able to handle the new instances. This patch updates Cycles, EEVEE and other viewport engines. Exporters have not been updated yet. Some minimal (not master-ready) changes to update the obj and alembic exporters can be found in P2336 and P2335. Different file formats may want to handle these new instances in different ways. For users, the only thing that changed is that the Point Instance node now has a geometry mode. This also fixes T88454. Differential Revision: https://developer.blender.org/D11841
2021-09-06 18:22:24 +02:00
mul_m4_m4_pre(space_matrix, parent_transform);
make_recursive_duplis(instances_ctx, &object, space_matrix, id);
break;
}
case InstanceReference::Type::Collection: {
Collection &collection = reference.collection();
float collection_matrix[4][4];
unit_m4(collection_matrix);
sub_v3_v3(collection_matrix[3], collection.instance_offset);
mul_m4_m4_pre(collection_matrix, instance_offset_matrices[i].values);
Geometry Nodes: support for geometry instancing Previously, the Point Instance node in geometry nodes could only instance existing objects or collections. The reason was that large parts of Blender worked under the assumption that objects are the main unit of instancing. Now we also want to instance geometry within an object, so a slightly larger refactor was necessary. This should not affect files that do not use the new kind of instances. The main change is a redefinition of what "instanced data" is. Now, an instances is a cow-object + object-data (the geometry). This can be nicely seen in `struct DupliObject`. This allows the same object to generate multiple geometries of different types which can be instanced individually. A nice side effect of this refactor is that having multiple geometry components is not a special case in the depsgraph object iterator anymore, because those components are integrated with the `DupliObject` system. Unfortunately, different systems that work with instances in Blender (e.g. render engines and exporters) often work under the assumption that objects are the main unit of instancing. So those have to be updated as well to be able to handle the new instances. This patch updates Cycles, EEVEE and other viewport engines. Exporters have not been updated yet. Some minimal (not master-ready) changes to update the obj and alembic exporters can be found in P2336 and P2335. Different file formats may want to handle these new instances in different ways. For users, the only thing that changed is that the Point Instance node now has a geometry mode. This also fixes T88454. Differential Revision: https://developer.blender.org/D11841
2021-09-06 18:22:24 +02:00
mul_m4_m4_pre(collection_matrix, parent_transform);
DupliContext sub_ctx;
if (!copy_dupli_context(&sub_ctx, instances_ctx, instances_ctx->object, nullptr, id)) {
break;
}
Geometry Nodes: support for geometry instancing Previously, the Point Instance node in geometry nodes could only instance existing objects or collections. The reason was that large parts of Blender worked under the assumption that objects are the main unit of instancing. Now we also want to instance geometry within an object, so a slightly larger refactor was necessary. This should not affect files that do not use the new kind of instances. The main change is a redefinition of what "instanced data" is. Now, an instances is a cow-object + object-data (the geometry). This can be nicely seen in `struct DupliObject`. This allows the same object to generate multiple geometries of different types which can be instanced individually. A nice side effect of this refactor is that having multiple geometry components is not a special case in the depsgraph object iterator anymore, because those components are integrated with the `DupliObject` system. Unfortunately, different systems that work with instances in Blender (e.g. render engines and exporters) often work under the assumption that objects are the main unit of instancing. So those have to be updated as well to be able to handle the new instances. This patch updates Cycles, EEVEE and other viewport engines. Exporters have not been updated yet. Some minimal (not master-ready) changes to update the obj and alembic exporters can be found in P2336 and P2335. Different file formats may want to handle these new instances in different ways. For users, the only thing that changed is that the Point Instance node now has a geometry mode. This also fixes T88454. Differential Revision: https://developer.blender.org/D11841
2021-09-06 18:22:24 +02:00
eEvaluationMode mode = DEG_get_mode(instances_ctx->depsgraph);
int object_id = 0;
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (&collection, object, mode) {
Geometry Nodes: support for geometry instancing Previously, the Point Instance node in geometry nodes could only instance existing objects or collections. The reason was that large parts of Blender worked under the assumption that objects are the main unit of instancing. Now we also want to instance geometry within an object, so a slightly larger refactor was necessary. This should not affect files that do not use the new kind of instances. The main change is a redefinition of what "instanced data" is. Now, an instances is a cow-object + object-data (the geometry). This can be nicely seen in `struct DupliObject`. This allows the same object to generate multiple geometries of different types which can be instanced individually. A nice side effect of this refactor is that having multiple geometry components is not a special case in the depsgraph object iterator anymore, because those components are integrated with the `DupliObject` system. Unfortunately, different systems that work with instances in Blender (e.g. render engines and exporters) often work under the assumption that objects are the main unit of instancing. So those have to be updated as well to be able to handle the new instances. This patch updates Cycles, EEVEE and other viewport engines. Exporters have not been updated yet. Some minimal (not master-ready) changes to update the obj and alembic exporters can be found in P2336 and P2335. Different file formats may want to handle these new instances in different ways. For users, the only thing that changed is that the Point Instance node now has a geometry mode. This also fixes T88454. Differential Revision: https://developer.blender.org/D11841
2021-09-06 18:22:24 +02:00
if (object == instances_ctx->object) {
continue;
}
float instance_matrix[4][4];
mul_m4_m4m4(instance_matrix, collection_matrix, object->obmat);
Geometry Nodes: support for geometry instancing Previously, the Point Instance node in geometry nodes could only instance existing objects or collections. The reason was that large parts of Blender worked under the assumption that objects are the main unit of instancing. Now we also want to instance geometry within an object, so a slightly larger refactor was necessary. This should not affect files that do not use the new kind of instances. The main change is a redefinition of what "instanced data" is. Now, an instances is a cow-object + object-data (the geometry). This can be nicely seen in `struct DupliObject`. This allows the same object to generate multiple geometries of different types which can be instanced individually. A nice side effect of this refactor is that having multiple geometry components is not a special case in the depsgraph object iterator anymore, because those components are integrated with the `DupliObject` system. Unfortunately, different systems that work with instances in Blender (e.g. render engines and exporters) often work under the assumption that objects are the main unit of instancing. So those have to be updated as well to be able to handle the new instances. This patch updates Cycles, EEVEE and other viewport engines. Exporters have not been updated yet. Some minimal (not master-ready) changes to update the obj and alembic exporters can be found in P2336 and P2335. Different file formats may want to handle these new instances in different ways. For users, the only thing that changed is that the Point Instance node now has a geometry mode. This also fixes T88454. Differential Revision: https://developer.blender.org/D11841
2021-09-06 18:22:24 +02:00
make_dupli(&sub_ctx, object, instance_matrix, object_id++);
make_recursive_duplis(&sub_ctx, object, collection_matrix, object_id++);
}
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
break;
}
Geometry Nodes: support for geometry instancing Previously, the Point Instance node in geometry nodes could only instance existing objects or collections. The reason was that large parts of Blender worked under the assumption that objects are the main unit of instancing. Now we also want to instance geometry within an object, so a slightly larger refactor was necessary. This should not affect files that do not use the new kind of instances. The main change is a redefinition of what "instanced data" is. Now, an instances is a cow-object + object-data (the geometry). This can be nicely seen in `struct DupliObject`. This allows the same object to generate multiple geometries of different types which can be instanced individually. A nice side effect of this refactor is that having multiple geometry components is not a special case in the depsgraph object iterator anymore, because those components are integrated with the `DupliObject` system. Unfortunately, different systems that work with instances in Blender (e.g. render engines and exporters) often work under the assumption that objects are the main unit of instancing. So those have to be updated as well to be able to handle the new instances. This patch updates Cycles, EEVEE and other viewport engines. Exporters have not been updated yet. Some minimal (not master-ready) changes to update the obj and alembic exporters can be found in P2336 and P2335. Different file formats may want to handle these new instances in different ways. For users, the only thing that changed is that the Point Instance node now has a geometry mode. This also fixes T88454. Differential Revision: https://developer.blender.org/D11841
2021-09-06 18:22:24 +02:00
case InstanceReference::Type::GeometrySet: {
float new_transform[4][4];
mul_m4_m4m4(new_transform, parent_transform, instance_offset_matrices[i].values);
DupliContext sub_ctx;
if (copy_dupli_context(&sub_ctx, instances_ctx, instances_ctx->object, nullptr, id)) {
make_duplis_geometry_set_impl(&sub_ctx, reference.geometry_set(), new_transform, true);
}
Geometry Nodes: support for geometry instancing Previously, the Point Instance node in geometry nodes could only instance existing objects or collections. The reason was that large parts of Blender worked under the assumption that objects are the main unit of instancing. Now we also want to instance geometry within an object, so a slightly larger refactor was necessary. This should not affect files that do not use the new kind of instances. The main change is a redefinition of what "instanced data" is. Now, an instances is a cow-object + object-data (the geometry). This can be nicely seen in `struct DupliObject`. This allows the same object to generate multiple geometries of different types which can be instanced individually. A nice side effect of this refactor is that having multiple geometry components is not a special case in the depsgraph object iterator anymore, because those components are integrated with the `DupliObject` system. Unfortunately, different systems that work with instances in Blender (e.g. render engines and exporters) often work under the assumption that objects are the main unit of instancing. So those have to be updated as well to be able to handle the new instances. This patch updates Cycles, EEVEE and other viewport engines. Exporters have not been updated yet. Some minimal (not master-ready) changes to update the obj and alembic exporters can be found in P2336 and P2335. Different file formats may want to handle these new instances in different ways. For users, the only thing that changed is that the Point Instance node now has a geometry mode. This also fixes T88454. Differential Revision: https://developer.blender.org/D11841
2021-09-06 18:22:24 +02:00
break;
}
case InstanceReference::Type::None: {
break;
}
}
Geometry Nodes: initial scattering and geometry nodes This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix
2020-12-02 13:25:25 +01:00
}
}
Geometry Nodes: support for geometry instancing Previously, the Point Instance node in geometry nodes could only instance existing objects or collections. The reason was that large parts of Blender worked under the assumption that objects are the main unit of instancing. Now we also want to instance geometry within an object, so a slightly larger refactor was necessary. This should not affect files that do not use the new kind of instances. The main change is a redefinition of what "instanced data" is. Now, an instances is a cow-object + object-data (the geometry). This can be nicely seen in `struct DupliObject`. This allows the same object to generate multiple geometries of different types which can be instanced individually. A nice side effect of this refactor is that having multiple geometry components is not a special case in the depsgraph object iterator anymore, because those components are integrated with the `DupliObject` system. Unfortunately, different systems that work with instances in Blender (e.g. render engines and exporters) often work under the assumption that objects are the main unit of instancing. So those have to be updated as well to be able to handle the new instances. This patch updates Cycles, EEVEE and other viewport engines. Exporters have not been updated yet. Some minimal (not master-ready) changes to update the obj and alembic exporters can be found in P2336 and P2335. Different file formats may want to handle these new instances in different ways. For users, the only thing that changed is that the Point Instance node now has a geometry mode. This also fixes T88454. Differential Revision: https://developer.blender.org/D11841
2021-09-06 18:22:24 +02:00
static void make_duplis_geometry_set(const DupliContext *ctx)
{
const GeometrySet *geometry_set = ctx->object->runtime.geometry_set_eval;
make_duplis_geometry_set_impl(ctx, *geometry_set, ctx->object->obmat, false);
}
static const DupliGenerator gen_dupli_geometry_set = {
Geometry Nodes: initial scattering and geometry nodes This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix
2020-12-02 13:25:25 +01:00
0,
Geometry Nodes: support for geometry instancing Previously, the Point Instance node in geometry nodes could only instance existing objects or collections. The reason was that large parts of Blender worked under the assumption that objects are the main unit of instancing. Now we also want to instance geometry within an object, so a slightly larger refactor was necessary. This should not affect files that do not use the new kind of instances. The main change is a redefinition of what "instanced data" is. Now, an instances is a cow-object + object-data (the geometry). This can be nicely seen in `struct DupliObject`. This allows the same object to generate multiple geometries of different types which can be instanced individually. A nice side effect of this refactor is that having multiple geometry components is not a special case in the depsgraph object iterator anymore, because those components are integrated with the `DupliObject` system. Unfortunately, different systems that work with instances in Blender (e.g. render engines and exporters) often work under the assumption that objects are the main unit of instancing. So those have to be updated as well to be able to handle the new instances. This patch updates Cycles, EEVEE and other viewport engines. Exporters have not been updated yet. Some minimal (not master-ready) changes to update the obj and alembic exporters can be found in P2336 and P2335. Different file formats may want to handle these new instances in different ways. For users, the only thing that changed is that the Point Instance node now has a geometry mode. This also fixes T88454. Differential Revision: https://developer.blender.org/D11841
2021-09-06 18:22:24 +02:00
make_duplis_geometry_set,
Geometry Nodes: initial scattering and geometry nodes This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix
2020-12-02 13:25:25 +01:00
};
/** \} */
/* -------------------------------------------------------------------- */
/** \name Dupli-Faces Implementation (#OB_DUPLIFACES)
* \{ */
/** Values shared between different mesh types. */
struct FaceDupliData_Params {
/**
* It's important we use this context instead of the `ctx` passed into #make_child_duplis
* since these won't match in the case of recursion.
*/
const DupliContext *ctx;
bool use_scale;
};
struct FaceDupliData_Mesh {
FaceDupliData_Params params;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
int totface;
const MPoly *mpoly;
const MLoop *mloop;
const MVert *mvert;
const float (*orco)[3];
const MLoopUV *mloopuv;
};
struct FaceDupliData_EditMesh {
FaceDupliData_Params params;
BMEditMesh *em;
bool has_orco, has_uvs;
int cd_loop_uv_offset;
/* Can be nullptr. */
const float (*vert_coords)[3];
};
static void get_dupliface_transform_from_coords(Span<float3> coords,
const bool use_scale,
const float scale_fac,
float r_mat[4][4])
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
{
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
using namespace blender::math;
/* Location. */
float3 location(0);
for (const float3 &coord : coords) {
location += coord;
}
location *= 1.0f / (float)coords.size();
/* Rotation. */
float quat[4];
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
float3 f_no = normalize(cross_poly(coords));
tri_to_quat_ex(quat, coords[0], coords[1], coords[2], f_no);
/* Scale. */
float scale;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
if (use_scale) {
const float area = area_poly_v3((const float(*)[3])coords.data(), (uint)coords.size());
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
scale = sqrtf(area) * scale_fac;
}
else {
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
scale = 1.0f;
}
loc_quat_size_to_mat4(r_mat, location, quat, float3(scale));
}
static DupliObject *face_dupli(const DupliContext *ctx,
Object *inst_ob,
const float child_imat[4][4],
const int index,
const bool use_scale,
const float scale_fac,
Span<float3> coords)
{
float obmat[4][4];
float space_mat[4][4];
/* `obmat` is transform to face. */
get_dupliface_transform_from_coords(coords, use_scale, scale_fac, obmat);
/* Make offset relative to inst_ob using relative child transform. */
mul_mat3_m4_v3(child_imat, obmat[3]);
/* XXX ugly hack to ensure same behavior as in master.
* This should not be needed, #Object.parentinv is not consistent outside of parenting. */
{
float imat[3][3];
copy_m3_m4(imat, inst_ob->parentinv);
mul_m4_m3m4(obmat, imat, obmat);
}
/* Apply `obmat` _after_ the local face transform. */
mul_m4_m4m4(obmat, inst_ob->obmat, obmat);
/* Space matrix is constructed by removing `obmat` transform,
* this yields the world-space transform for recursive duplis. */
mul_m4_m4m4(space_mat, obmat, inst_ob->imat);
DupliObject *dob = make_dupli(ctx, inst_ob, obmat, index);
/* Recursion. */
make_recursive_duplis(ctx, inst_ob, space_mat, index);
return dob;
}
static DupliObject *face_dupli_from_mesh(const DupliContext *ctx,
Object *inst_ob,
const float child_imat[4][4],
const int index,
const bool use_scale,
const float scale_fac,
/* Mesh variables. */
const MPoly *mpoly,
const MLoop *mloopstart,
const MVert *mvert)
{
const int coords_len = mpoly->totloop;
Array<float3, 64> coords(coords_len);
const MLoop *ml = mloopstart;
for (int i = 0; i < coords_len; i++, ml++) {
coords[i] = float3(mvert[ml->v].co);
}
return face_dupli(ctx, inst_ob, child_imat, index, use_scale, scale_fac, coords);
}
static DupliObject *face_dupli_from_editmesh(const DupliContext *ctx,
Object *inst_ob,
const float child_imat[4][4],
const int index,
const bool use_scale,
const float scale_fac,
/* Mesh variables. */
BMFace *f,
const float (*vert_coords)[3])
{
const int coords_len = f->len;
Array<float3, 64> coords(coords_len);
BMLoop *l_first, *l_iter;
int i = 0;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
if (vert_coords != nullptr) {
do {
copy_v3_v3(coords[i++], vert_coords[BM_elem_index_get(l_iter->v)]);
} while ((l_iter = l_iter->next) != l_first);
}
else {
do {
copy_v3_v3(coords[i++], l_iter->v->co);
} while ((l_iter = l_iter->next) != l_first);
}
return face_dupli(ctx, inst_ob, child_imat, index, use_scale, scale_fac, coords);
}
static void make_child_duplis_faces_from_mesh(const DupliContext *ctx,
void *userdata,
Object *inst_ob)
{
FaceDupliData_Mesh *fdd = (FaceDupliData_Mesh *)userdata;
const MPoly *mpoly = fdd->mpoly, *mp;
const MLoop *mloop = fdd->mloop;
const MVert *mvert = fdd->mvert;
const float(*orco)[3] = fdd->orco;
const MLoopUV *mloopuv = fdd->mloopuv;
const int totface = fdd->totface;
const bool use_scale = fdd->params.use_scale;
int a;
float child_imat[4][4];
invert_m4_m4(inst_ob->imat, inst_ob->obmat);
/* Relative transform from parent to child space. */
mul_m4_m4m4(child_imat, inst_ob->imat, ctx->object->obmat);
const float scale_fac = ctx->object->instance_faces_scale;
for (a = 0, mp = mpoly; a < totface; a++, mp++) {
const MLoop *loopstart = mloop + mp->loopstart;
DupliObject *dob = face_dupli_from_mesh(
fdd->params.ctx, inst_ob, child_imat, a, use_scale, scale_fac, mp, loopstart, mvert);
const float w = 1.0f / (float)mp->totloop;
if (orco) {
for (int j = 0; j < mp->totloop; j++) {
madd_v3_v3fl(dob->orco, orco[loopstart[j].v], w);
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
}
if (mloopuv) {
for (int j = 0; j < mp->totloop; j++) {
madd_v2_v2fl(dob->uv, mloopuv[mp->loopstart + j].uv, w);
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
}
}
}
static void make_child_duplis_faces_from_editmesh(const DupliContext *ctx,
void *userdata,
Object *inst_ob)
{
FaceDupliData_EditMesh *fdd = (FaceDupliData_EditMesh *)userdata;
BMEditMesh *em = fdd->em;
float child_imat[4][4];
int a;
BMFace *f;
BMIter iter;
const bool use_scale = fdd->params.use_scale;
const float(*vert_coords)[3] = fdd->vert_coords;
BLI_assert((vert_coords == nullptr) || (em->bm->elem_index_dirty & BM_VERT) == 0);
invert_m4_m4(inst_ob->imat, inst_ob->obmat);
/* Relative transform from parent to child space. */
mul_m4_m4m4(child_imat, inst_ob->imat, ctx->object->obmat);
const float scale_fac = ctx->object->instance_faces_scale;
BM_ITER_MESH_INDEX (f, &iter, em->bm, BM_FACES_OF_MESH, a) {
DupliObject *dob = face_dupli_from_editmesh(
fdd->params.ctx, inst_ob, child_imat, a, use_scale, scale_fac, f, vert_coords);
if (fdd->has_orco) {
const float w = 1.0f / (float)f->len;
BMLoop *l_first, *l_iter;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
madd_v3_v3fl(dob->orco, l_iter->v->co, w);
} while ((l_iter = l_iter->next) != l_first);
}
if (fdd->has_uvs) {
BM_face_uv_calc_center_median(f, fdd->cd_loop_uv_offset, dob->uv);
}
}
}
static void make_duplis_faces(const DupliContext *ctx)
{
Object *parent = ctx->object;
/* Gather mesh info. */
BMEditMesh *em = nullptr;
const float(*vert_coords)[3] = nullptr;
const Mesh *me_eval = mesh_data_from_duplicator_object(parent, &em, &vert_coords, nullptr);
if (em == nullptr && me_eval == nullptr) {
return;
}
FaceDupliData_Params fdd_params = {ctx, (parent->transflag & OB_DUPLIFACES_SCALE) != 0};
if (em != nullptr) {
const int uv_idx = CustomData_get_render_layer(&em->bm->ldata, CD_MLOOPUV);
FaceDupliData_EditMesh fdd{};
fdd.params = fdd_params;
fdd.em = em;
fdd.vert_coords = vert_coords;
fdd.has_orco = (vert_coords != nullptr);
fdd.has_uvs = (uv_idx != -1);
fdd.cd_loop_uv_offset = (uv_idx != -1) ?
CustomData_get_n_offset(&em->bm->ldata, CD_MLOOPUV, uv_idx) :
-1;
make_child_duplis(ctx, &fdd, make_child_duplis_faces_from_editmesh);
}
else {
const int uv_idx = CustomData_get_render_layer(&me_eval->ldata, CD_MLOOPUV);
FaceDupliData_Mesh fdd{};
fdd.params = fdd_params;
fdd.totface = me_eval->totpoly;
fdd.mpoly = me_eval->mpoly;
fdd.mloop = me_eval->mloop;
fdd.mvert = me_eval->mvert;
fdd.mloopuv = (uv_idx != -1) ? (const MLoopUV *)CustomData_get_layer_n(
&me_eval->ldata, CD_MLOOPUV, uv_idx) :
nullptr;
fdd.orco = (const float(*)[3])CustomData_get_layer(&me_eval->vdata, CD_ORCO);
make_child_duplis(ctx, &fdd, make_child_duplis_faces_from_mesh);
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
}
static const DupliGenerator gen_dupli_faces = {
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
OB_DUPLIFACES, /* type */
make_duplis_faces /* make_duplis */
};
/** \} */
/* -------------------------------------------------------------------- */
/** \name Dupli-Particles Implementation (#OB_DUPLIPARTS)
* \{ */
static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem *psys)
{
Scene *scene = ctx->scene;
Object *par = ctx->object;
eEvaluationMode mode = DEG_get_mode(ctx->depsgraph);
bool for_render = mode == DAG_EVAL_RENDER;
Object *ob = nullptr, **oblist = nullptr;
DupliObject *dob;
ParticleSettings *part;
ParticleData *pa;
ChildParticle *cpa = nullptr;
ParticleKey state;
ParticleCacheKey *cache;
float ctime, scale = 1.0f;
float tmat[4][4], mat[4][4], pamat[4][4], size = 0.0;
int a, b, hair = 0;
int totpart, totchild;
int no_draw_flag = PARS_UNEXIST;
if (psys == nullptr) {
return;
}
part = psys->part;
if (part == nullptr) {
return;
}
if (!psys_check_enabled(par, psys, for_render)) {
return;
}
if (!for_render) {
no_draw_flag |= PARS_NO_DISP;
}
/* NOTE: in old animation system, used parent object's time-offset. */
ctime = DEG_get_ctime(ctx->depsgraph);
totpart = psys->totpart;
totchild = psys->totchild;
if ((for_render || part->draw_as == PART_DRAW_REND) &&
ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) {
ParticleSimulationData sim = {nullptr};
sim.depsgraph = ctx->depsgraph;
sim.scene = scene;
sim.ob = par;
sim.psys = psys;
sim.psmd = psys_get_modifier(par, psys);
/* Make sure emitter `imat` is in global coordinates instead of render view coordinates. */
invert_m4_m4(par->imat, par->obmat);
/* First check for loops (particle system object used as dupli-object). */
if (part->ren_as == PART_DRAW_OB) {
if (ELEM(part->instance_object, nullptr, par)) {
return;
}
}
else { /* #PART_DRAW_GR. */
if (part->instance_collection == nullptr) {
return;
}
const ListBase dup_collection_objects = BKE_collection_object_cache_get(
part->instance_collection);
if (BLI_listbase_is_empty(&dup_collection_objects)) {
Collections and groups unification OVERVIEW * In 2.7 terminology, all layers and groups are now collection datablocks. * These collections are nestable, linkable, instanceable, overrideable, .. which opens up new ways to set up scenes and link + override data. * Viewport/render visibility and selectability are now a part of the collection and shared across all view layers and linkable. * View layers define which subset of the scene collection hierarchy is excluded for each. For many workflows one view layer can be used, these are more of an advanced feature now. OUTLINER * The outliner now has a "View Layer" display mode instead of "Collections", which can display the collections and/or objects in the view layer. * In this display mode, collections can be excluded with the right click menu. These will then be greyed out and their objects will be excluded. * To view collections not linked to any scene, the "Blender File" display mode can be used, with the new filtering option to just see Colleciton datablocks. * The outliner right click menus for collections and objects were reorganized. * Drag and drop still needs to be improved. Like before, dragging the icon or text gives different results, we'll unify this later. LINKING AND OVERRIDES * Collections can now be linked into the scene without creating an instance, with the link/append operator or from the collections view in the outliner. * Collections can get static overrides with the right click menu in the outliner, but this is rather unreliable and not clearly communicated at the moment. * We still need to improve the make override operator to turn collection instances into collections with overrides directly in the scene. PERFORMANCE * We tried to make performance not worse than before and improve it in some cases. The main thing that's still a bit slower is multiple scenes, we have to change the layer syncing to only updated affected scenes. * Collections keep a list of their parent collections for faster incremental updates in syncing and caching. * View layer bases are now in a object -> base hash to avoid quadratic time lookups internally and in API functions like visible_get(). VERSIONING * Compatibility with 2.7 files should be improved due to the new visibility controls. Of course users may not want to set up their scenes differently now to avoid having separate layers and groups. * Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero files. There's a few things which are know to be not quite compatible, like nested layer collections inside groups. * The versioning code for 2.8 files is quite complicated, and isolated behind #ifdef so it can be removed at the end of the release cycle. KNOWN ISSUES * The G-key group operators in the 3D viewport were left mostly as is, they need to be modified still to fit better. * Same for the groups panel in the object properties. This needs to be updated still, or perhaps replaced by something better. * Collections must all have a unique name. Less restrictive namespacing is to be done later, we'll have to see how important this is as all objects within the collections must also have a unique name anyway. * Full scene copy and delete scene are exactly doing the right thing yet. Differential Revision: https://developer.blender.org/D3383 https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
return;
}
Collections and groups unification OVERVIEW * In 2.7 terminology, all layers and groups are now collection datablocks. * These collections are nestable, linkable, instanceable, overrideable, .. which opens up new ways to set up scenes and link + override data. * Viewport/render visibility and selectability are now a part of the collection and shared across all view layers and linkable. * View layers define which subset of the scene collection hierarchy is excluded for each. For many workflows one view layer can be used, these are more of an advanced feature now. OUTLINER * The outliner now has a "View Layer" display mode instead of "Collections", which can display the collections and/or objects in the view layer. * In this display mode, collections can be excluded with the right click menu. These will then be greyed out and their objects will be excluded. * To view collections not linked to any scene, the "Blender File" display mode can be used, with the new filtering option to just see Colleciton datablocks. * The outliner right click menus for collections and objects were reorganized. * Drag and drop still needs to be improved. Like before, dragging the icon or text gives different results, we'll unify this later. LINKING AND OVERRIDES * Collections can now be linked into the scene without creating an instance, with the link/append operator or from the collections view in the outliner. * Collections can get static overrides with the right click menu in the outliner, but this is rather unreliable and not clearly communicated at the moment. * We still need to improve the make override operator to turn collection instances into collections with overrides directly in the scene. PERFORMANCE * We tried to make performance not worse than before and improve it in some cases. The main thing that's still a bit slower is multiple scenes, we have to change the layer syncing to only updated affected scenes. * Collections keep a list of their parent collections for faster incremental updates in syncing and caching. * View layer bases are now in a object -> base hash to avoid quadratic time lookups internally and in API functions like visible_get(). VERSIONING * Compatibility with 2.7 files should be improved due to the new visibility controls. Of course users may not want to set up their scenes differently now to avoid having separate layers and groups. * Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero files. There's a few things which are know to be not quite compatible, like nested layer collections inside groups. * The versioning code for 2.8 files is quite complicated, and isolated behind #ifdef so it can be removed at the end of the release cycle. KNOWN ISSUES * The G-key group operators in the 3D viewport were left mostly as is, they need to be modified still to fit better. * Same for the groups panel in the object properties. This needs to be updated still, or perhaps replaced by something better. * Collections must all have a unique name. Less restrictive namespacing is to be done later, we'll have to see how important this is as all objects within the collections must also have a unique name anyway. * Full scene copy and delete scene are exactly doing the right thing yet. Differential Revision: https://developer.blender.org/D3383 https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
if (BLI_findptr(&dup_collection_objects, par, offsetof(Base, object))) {
return;
}
}
/* If we have a hair particle system, use the path cache. */
if (part->type == PART_HAIR) {
if (psys->flag & PSYS_HAIR_DONE) {
hair = (totchild == 0 || psys->childcache) && psys->pathcache;
}
if (!hair) {
return;
}
/* We use cache, update `totchild` according to cached data. */
totchild = psys->totchildcache;
totpart = psys->totcached;
}
RNG *rng = BLI_rng_new_srandom(31415926u + (unsigned int)psys->seed);
psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
/* Gather list of objects or single object. */
int totcollection = 0;
const bool use_whole_collection = part->draw & PART_DRAW_WHOLE_GR;
const bool use_collection_count = part->draw & PART_DRAW_COUNT_GR && !use_whole_collection;
if (part->ren_as == PART_DRAW_GR) {
if (use_collection_count) {
psys_find_group_weights(part);
LISTBASE_FOREACH (ParticleDupliWeight *, dw, &part->instance_weights) {
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (
part->instance_collection, object, mode) {
if (dw->ob == object) {
totcollection += dw->count;
break;
}
}
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
}
}
else {
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (
part->instance_collection, object, mode) {
(void)object;
Collections and groups unification OVERVIEW * In 2.7 terminology, all layers and groups are now collection datablocks. * These collections are nestable, linkable, instanceable, overrideable, .. which opens up new ways to set up scenes and link + override data. * Viewport/render visibility and selectability are now a part of the collection and shared across all view layers and linkable. * View layers define which subset of the scene collection hierarchy is excluded for each. For many workflows one view layer can be used, these are more of an advanced feature now. OUTLINER * The outliner now has a "View Layer" display mode instead of "Collections", which can display the collections and/or objects in the view layer. * In this display mode, collections can be excluded with the right click menu. These will then be greyed out and their objects will be excluded. * To view collections not linked to any scene, the "Blender File" display mode can be used, with the new filtering option to just see Colleciton datablocks. * The outliner right click menus for collections and objects were reorganized. * Drag and drop still needs to be improved. Like before, dragging the icon or text gives different results, we'll unify this later. LINKING AND OVERRIDES * Collections can now be linked into the scene without creating an instance, with the link/append operator or from the collections view in the outliner. * Collections can get static overrides with the right click menu in the outliner, but this is rather unreliable and not clearly communicated at the moment. * We still need to improve the make override operator to turn collection instances into collections with overrides directly in the scene. PERFORMANCE * We tried to make performance not worse than before and improve it in some cases. The main thing that's still a bit slower is multiple scenes, we have to change the layer syncing to only updated affected scenes. * Collections keep a list of their parent collections for faster incremental updates in syncing and caching. * View layer bases are now in a object -> base hash to avoid quadratic time lookups internally and in API functions like visible_get(). VERSIONING * Compatibility with 2.7 files should be improved due to the new visibility controls. Of course users may not want to set up their scenes differently now to avoid having separate layers and groups. * Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero files. There's a few things which are know to be not quite compatible, like nested layer collections inside groups. * The versioning code for 2.8 files is quite complicated, and isolated behind #ifdef so it can be removed at the end of the release cycle. KNOWN ISSUES * The G-key group operators in the 3D viewport were left mostly as is, they need to be modified still to fit better. * Same for the groups panel in the object properties. This needs to be updated still, or perhaps replaced by something better. * Collections must all have a unique name. Less restrictive namespacing is to be done later, we'll have to see how important this is as all objects within the collections must also have a unique name anyway. * Full scene copy and delete scene are exactly doing the right thing yet. Differential Revision: https://developer.blender.org/D3383 https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
totcollection++;
}
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
}
oblist = (Object **)MEM_callocN((size_t)totcollection * sizeof(Object *),
"dupcollection object list");
if (use_collection_count) {
a = 0;
LISTBASE_FOREACH (ParticleDupliWeight *, dw, &part->instance_weights) {
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (
part->instance_collection, object, mode) {
if (dw->ob == object) {
for (b = 0; b < dw->count; b++, a++) {
oblist[a] = dw->ob;
}
break;
}
}
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
}
}
else {
a = 0;
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (
part->instance_collection, object, mode) {
oblist[a] = object;
a++;
}
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
}
}
else {
ob = part->instance_object;
}
if (totchild == 0 || part->draw & PART_DRAW_PARENT) {
a = 0;
}
else {
a = totpart;
}
for (pa = psys->particles; a < totpart + totchild; a++, pa++) {
if (a < totpart) {
/* Handle parent particle. */
if (pa->flag & no_draw_flag) {
continue;
}
#if 0 /* UNUSED */
pa_num = pa->num;
#endif
size = pa->size;
}
else {
/* Handle child particle. */
cpa = &psys->child[a - totpart];
#if 0 /* UNUSED */
pa_num = a;
#endif
size = psys_get_child_size(psys, cpa, ctime, nullptr);
}
/* Some hair paths might be non-existent so they can't be used for duplication. */
if (hair && psys->pathcache &&
((a < totpart && psys->pathcache[a]->segments < 0) ||
(a >= totpart && psys->childcache[a - totpart]->segments < 0))) {
continue;
}
if (part->ren_as == PART_DRAW_GR) {
/* Prevent divide by zero below T28336. */
if (totcollection == 0) {
continue;
}
/* For collections, pick the object based on settings. */
if (part->draw & PART_DRAW_RAND_GR && !use_whole_collection) {
b = BLI_rng_get_int(rng) % totcollection;
}
else {
Collections and groups unification OVERVIEW * In 2.7 terminology, all layers and groups are now collection datablocks. * These collections are nestable, linkable, instanceable, overrideable, .. which opens up new ways to set up scenes and link + override data. * Viewport/render visibility and selectability are now a part of the collection and shared across all view layers and linkable. * View layers define which subset of the scene collection hierarchy is excluded for each. For many workflows one view layer can be used, these are more of an advanced feature now. OUTLINER * The outliner now has a "View Layer" display mode instead of "Collections", which can display the collections and/or objects in the view layer. * In this display mode, collections can be excluded with the right click menu. These will then be greyed out and their objects will be excluded. * To view collections not linked to any scene, the "Blender File" display mode can be used, with the new filtering option to just see Colleciton datablocks. * The outliner right click menus for collections and objects were reorganized. * Drag and drop still needs to be improved. Like before, dragging the icon or text gives different results, we'll unify this later. LINKING AND OVERRIDES * Collections can now be linked into the scene without creating an instance, with the link/append operator or from the collections view in the outliner. * Collections can get static overrides with the right click menu in the outliner, but this is rather unreliable and not clearly communicated at the moment. * We still need to improve the make override operator to turn collection instances into collections with overrides directly in the scene. PERFORMANCE * We tried to make performance not worse than before and improve it in some cases. The main thing that's still a bit slower is multiple scenes, we have to change the layer syncing to only updated affected scenes. * Collections keep a list of their parent collections for faster incremental updates in syncing and caching. * View layer bases are now in a object -> base hash to avoid quadratic time lookups internally and in API functions like visible_get(). VERSIONING * Compatibility with 2.7 files should be improved due to the new visibility controls. Of course users may not want to set up their scenes differently now to avoid having separate layers and groups. * Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero files. There's a few things which are know to be not quite compatible, like nested layer collections inside groups. * The versioning code for 2.8 files is quite complicated, and isolated behind #ifdef so it can be removed at the end of the release cycle. KNOWN ISSUES * The G-key group operators in the 3D viewport were left mostly as is, they need to be modified still to fit better. * Same for the groups panel in the object properties. This needs to be updated still, or perhaps replaced by something better. * Collections must all have a unique name. Less restrictive namespacing is to be done later, we'll have to see how important this is as all objects within the collections must also have a unique name anyway. * Full scene copy and delete scene are exactly doing the right thing yet. Differential Revision: https://developer.blender.org/D3383 https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
b = a % totcollection;
}
ob = oblist[b];
}
if (hair) {
/* Hair we handle separate and compute transform based on hair keys. */
if (a < totpart) {
cache = psys->pathcache[a];
psys_get_dupli_path_transform(&sim, pa, nullptr, cache, pamat, &scale);
}
else {
cache = psys->childcache[a - totpart];
psys_get_dupli_path_transform(&sim, nullptr, cpa, cache, pamat, &scale);
}
copy_v3_v3(pamat[3], cache->co);
pamat[3][3] = 1.0f;
}
else {
/* First key. */
state.time = ctime;
2021-12-08 09:52:38 +01:00
if (psys_get_particle_state(&sim, a, &state, false) == 0) {
continue;
}
float tquat[4];
normalize_qt_qt(tquat, state.rot);
quat_to_mat4(pamat, tquat);
copy_v3_v3(pamat[3], state.co);
pamat[3][3] = 1.0f;
}
if (part->ren_as == PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) {
b = 0;
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (
part->instance_collection, object, mode) {
copy_m4_m4(tmat, oblist[b]->obmat);
/* Apply collection instance offset. */
sub_v3_v3(tmat[3], part->instance_collection->instance_offset);
/* Apply particle scale. */
mul_mat3_m4_fl(tmat, size * scale);
mul_v3_fl(tmat[3], size * scale);
/* Individual particle transform. */
mul_m4_m4m4(mat, pamat, tmat);
dob = make_dupli(ctx, object, mat, a);
dob->particle_system = psys;
psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
b++;
}
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
}
else {
float obmat[4][4];
copy_m4_m4(obmat, ob->obmat);
float vec[3];
copy_v3_v3(vec, obmat[3]);
zero_v3(obmat[3]);
/* Particle rotation uses x-axis as the aligned axis,
* so pre-rotate the object accordingly. */
if ((part->draw & PART_DRAW_ROTATE_OB) == 0) {
float xvec[3], q[4], size_mat[4][4], original_size[3];
mat4_to_size(original_size, obmat);
size_to_mat4(size_mat, original_size);
xvec[0] = -1.0f;
xvec[1] = xvec[2] = 0;
vec_to_quat(q, xvec, ob->trackflag, ob->upflag);
quat_to_mat4(obmat, q);
obmat[3][3] = 1.0f;
/* Add scaling if requested. */
if ((part->draw & PART_DRAW_NO_SCALE_OB) == 0) {
mul_m4_m4m4(obmat, obmat, size_mat);
}
}
else if (part->draw & PART_DRAW_NO_SCALE_OB) {
/* Remove scaling. */
float size_mat[4][4], original_size[3];
mat4_to_size(original_size, obmat);
size_to_mat4(size_mat, original_size);
invert_m4(size_mat);
mul_m4_m4m4(obmat, obmat, size_mat);
}
mul_m4_m4m4(tmat, pamat, obmat);
mul_mat3_m4_fl(tmat, size * scale);
copy_m4_m4(mat, tmat);
if (part->draw & PART_DRAW_GLOBAL_OB) {
add_v3_v3v3(mat[3], mat[3], vec);
}
dob = make_dupli(ctx, ob, mat, a);
dob->particle_system = psys;
psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
}
}
BLI_rng_free(rng);
}
/* Clean up. */
if (oblist) {
MEM_freeN(oblist);
}
if (psys->lattice_deform_data) {
BKE_lattice_deform_data_destroy(psys->lattice_deform_data);
psys->lattice_deform_data = nullptr;
}
}
static void make_duplis_particles(const DupliContext *ctx)
{
/* Particle system take up one level in id, the particles another. */
int psysid;
LISTBASE_FOREACH_INDEX (ParticleSystem *, psys, &ctx->object->particlesystem, psysid) {
/* Particles create one more level for persistent `psys` index. */
DupliContext pctx;
if (copy_dupli_context(&pctx, ctx, ctx->object, nullptr, psysid)) {
make_duplis_particle_system(&pctx, psys);
}
}
}
static const DupliGenerator gen_dupli_particles = {
OB_DUPLIPARTS, /* type */
make_duplis_particles /* make_duplis */
};
/** \} */
/* -------------------------------------------------------------------- */
/** \name Dupli-Generator Selector For The Given Context
* \{ */
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
static const DupliGenerator *get_dupli_generator(const DupliContext *ctx)
{
int transflag = ctx->object->transflag;
int visibility_flag = ctx->object->visibility_flag;
if ((transflag & OB_DUPLI) == 0 && ctx->object->runtime.geometry_set_eval == nullptr) {
return nullptr;
}
/* Should the dupli's be generated for this object? - Respect restrict flags. */
if (DEG_get_mode(ctx->depsgraph) == DAG_EVAL_RENDER ? (visibility_flag & OB_HIDE_RENDER) :
(visibility_flag & OB_HIDE_VIEWPORT)) {
return nullptr;
}
/* Give "Object as Font" instances higher priority than geometry set instances, to retain
* the behavior from before curve object meshes were processed as instances internally. */
if (transflag & OB_DUPLIVERTS) {
if (ctx->object->type == OB_FONT) {
return &gen_dupli_verts_font;
}
}
if (ctx->object->runtime.geometry_set_eval != nullptr) {
Geometry Nodes: support for geometry instancing Previously, the Point Instance node in geometry nodes could only instance existing objects or collections. The reason was that large parts of Blender worked under the assumption that objects are the main unit of instancing. Now we also want to instance geometry within an object, so a slightly larger refactor was necessary. This should not affect files that do not use the new kind of instances. The main change is a redefinition of what "instanced data" is. Now, an instances is a cow-object + object-data (the geometry). This can be nicely seen in `struct DupliObject`. This allows the same object to generate multiple geometries of different types which can be instanced individually. A nice side effect of this refactor is that having multiple geometry components is not a special case in the depsgraph object iterator anymore, because those components are integrated with the `DupliObject` system. Unfortunately, different systems that work with instances in Blender (e.g. render engines and exporters) often work under the assumption that objects are the main unit of instancing. So those have to be updated as well to be able to handle the new instances. This patch updates Cycles, EEVEE and other viewport engines. Exporters have not been updated yet. Some minimal (not master-ready) changes to update the obj and alembic exporters can be found in P2336 and P2335. Different file formats may want to handle these new instances in different ways. For users, the only thing that changed is that the Point Instance node now has a geometry mode. This also fixes T88454. Differential Revision: https://developer.blender.org/D11841
2021-09-06 18:22:24 +02:00
if (BKE_object_has_geometry_set_instances(ctx->object)) {
return &gen_dupli_geometry_set;
Geometry Nodes: initial scattering and geometry nodes This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix
2020-12-02 13:25:25 +01:00
}
}
if (transflag & OB_DUPLIPARTS) {
return &gen_dupli_particles;
}
if (transflag & OB_DUPLIVERTS) {
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
if (ctx->object->type == OB_MESH) {
return &gen_dupli_verts;
}
}
else if (transflag & OB_DUPLIFACES) {
if (ctx->object->type == OB_MESH) {
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
return &gen_dupli_faces;
}
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
Collections and groups unification OVERVIEW * In 2.7 terminology, all layers and groups are now collection datablocks. * These collections are nestable, linkable, instanceable, overrideable, .. which opens up new ways to set up scenes and link + override data. * Viewport/render visibility and selectability are now a part of the collection and shared across all view layers and linkable. * View layers define which subset of the scene collection hierarchy is excluded for each. For many workflows one view layer can be used, these are more of an advanced feature now. OUTLINER * The outliner now has a "View Layer" display mode instead of "Collections", which can display the collections and/or objects in the view layer. * In this display mode, collections can be excluded with the right click menu. These will then be greyed out and their objects will be excluded. * To view collections not linked to any scene, the "Blender File" display mode can be used, with the new filtering option to just see Colleciton datablocks. * The outliner right click menus for collections and objects were reorganized. * Drag and drop still needs to be improved. Like before, dragging the icon or text gives different results, we'll unify this later. LINKING AND OVERRIDES * Collections can now be linked into the scene without creating an instance, with the link/append operator or from the collections view in the outliner. * Collections can get static overrides with the right click menu in the outliner, but this is rather unreliable and not clearly communicated at the moment. * We still need to improve the make override operator to turn collection instances into collections with overrides directly in the scene. PERFORMANCE * We tried to make performance not worse than before and improve it in some cases. The main thing that's still a bit slower is multiple scenes, we have to change the layer syncing to only updated affected scenes. * Collections keep a list of their parent collections for faster incremental updates in syncing and caching. * View layer bases are now in a object -> base hash to avoid quadratic time lookups internally and in API functions like visible_get(). VERSIONING * Compatibility with 2.7 files should be improved due to the new visibility controls. Of course users may not want to set up their scenes differently now to avoid having separate layers and groups. * Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero files. There's a few things which are know to be not quite compatible, like nested layer collections inside groups. * The versioning code for 2.8 files is quite complicated, and isolated behind #ifdef so it can be removed at the end of the release cycle. KNOWN ISSUES * The G-key group operators in the 3D viewport were left mostly as is, they need to be modified still to fit better. * Same for the groups panel in the object properties. This needs to be updated still, or perhaps replaced by something better. * Collections must all have a unique name. Less restrictive namespacing is to be done later, we'll have to see how important this is as all objects within the collections must also have a unique name anyway. * Full scene copy and delete scene are exactly doing the right thing yet. Differential Revision: https://developer.blender.org/D3383 https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
else if (transflag & OB_DUPLICOLLECTION) {
return &gen_dupli_collection;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
return nullptr;
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Dupli-Container Implementation
* \{ */
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
ListBase *object_duplilist(Depsgraph *depsgraph, Scene *sce, Object *ob)
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
{
ListBase *duplilist = MEM_cnew<ListBase>("duplilist");
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
DupliContext ctx;
Vector<Object *> instance_stack;
instance_stack.append(ob);
init_context(&ctx, depsgraph, sce, ob, nullptr, instance_stack);
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
if (ctx.gen) {
ctx.duplilist = duplilist;
ctx.gen->make_duplis(&ctx);
}
Code cleanup and structural improvements for dupli generation. This is a first step toward improving our dupli system. It implements a more generic way of treating the various methods of dupli generation by adding a few structs: * DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists. * DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c) Beside making the code more easily understandable this implementation should also help to avoid weird side effects from custom matrix hacks by defining clearly what a generator does. The DupliContext is deliberately made const, so a generator can not simply add hidden matrix or flag modifications that are hard to track down. The result container for the generated duplis is stored in the context instead of being passed explicitly. This means the generators are oblivious to the storage of duplis, all they need to do is call the make_dupli function. This will allow us to implement more efficient ways of storing DupliObject instances, such as MemPools or batches. These can be implemented alongside the current ListBase so we can improve dupli bottlenecks without having to replace each and every dupli use case at once. Differential Revision: https://developer.blender.org/D189
2014-01-21 12:11:34 +01:00
return duplilist;
}
void free_object_duplilist(ListBase *lb)
{
BLI_freelistN(lb);
MEM_freeN(lb);
}
/** \} */