Ids stored in the `id` attribute cannot be assumed to be unique. While they might be unique in some cases, this is not something that can be guaranteed in general. For some use cases (e.g. generating "stable randomness" on points) uniqueness is not important. To support features like motion blur, unique ids are important though. This patch implements a simple algorithm that turns non-unique ids into unique ones. It might fail to do so under very unlikely circumstances, in which it returns non-unique ids instead of possibly going into an endless loop. Here are some requirements I set for the algorithm: * Ids that are unique already, must not be changed. * The same input should generate the same output. * Handle cases when all ids are different and when all ids are the same equally well (in expected linear time). * Small changes in the input id array should ideally only have a small impact on the output id array. The reported bug happened because cycles found multiple objects with the same id and thought that it was a single object that moved on every check. Differential Revision: https://developer.blender.org/D10402
56 lines
1.5 KiB
C++
56 lines
1.5 KiB
C++
/*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
/** \file
|
|
* \ingroup bke
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
struct Collection;
|
|
struct GeometrySet;
|
|
struct Object;
|
|
|
|
void BKE_geometry_set_free(struct GeometrySet *geometry_set);
|
|
|
|
bool BKE_geometry_set_has_instances(const struct GeometrySet *geometry_set);
|
|
|
|
typedef enum InstancedDataType {
|
|
INSTANCE_DATA_TYPE_OBJECT = 0,
|
|
INSTANCE_DATA_TYPE_COLLECTION = 1,
|
|
} InstancedDataType;
|
|
|
|
typedef struct InstancedData {
|
|
InstancedDataType type;
|
|
union {
|
|
struct Object *object;
|
|
struct Collection *collection;
|
|
} data;
|
|
} InstancedData;
|
|
|
|
int BKE_geometry_set_instances(const struct GeometrySet *geometry_set,
|
|
float (**r_transforms)[4][4],
|
|
const int **r_almost_unique_ids,
|
|
struct InstancedData **r_instanced_data);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|