forked from blender/blender
davidhaver-WIP-realize-depth #3
@ -30,6 +30,7 @@
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_attribute_math.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
@ -165,7 +165,6 @@ add_definitions(-DMATH_STANDALONE)
|
||||
|
||||
add_library(bli_lib
|
||||
"../../../source/blender/blenlib/intern/fileops.c"
|
||||
"../../../source/blender/blenlib/intern/gsqueue.c"
|
||||
"../../../source/blender/blenlib/intern/rct.c"
|
||||
"../../../source/blender/blenlib/intern/string.c"
|
||||
"../../../source/blender/blenlib/intern/string_utf8.c"
|
||||
|
@ -2547,7 +2547,6 @@ class USERPREF_PT_experimental_new_features(ExperimentalPanel, Panel):
|
||||
({"property": "use_sculpt_tools_tilt"}, ("blender/blender/issues/82877", "#82877")),
|
||||
({"property": "use_extended_asset_browser"},
|
||||
("blender/blender/projects/10", "Pipeline, Assets & IO Project Page")),
|
||||
({"property": "use_override_templates"}, ("blender/blender/issues/73318", "Milestone 4")),
|
||||
({"property": "use_new_volume_nodes"}, ("blender/blender/issues/103248", "#103248")),
|
||||
({"property": "use_shader_node_previews"}, ("blender/blender/issues/110353", "#110353")),
|
||||
),
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
#include "BKE_customdata.hh"
|
||||
#include "DNA_customdata_types.h"
|
||||
|
||||
namespace blender::bke {
|
||||
enum class AttrDomain : int8_t;
|
||||
|
@ -76,6 +76,9 @@ class AttributeIDRef {
|
||||
friend std::ostream &operator<<(std::ostream &stream, const AttributeIDRef &attribute_id);
|
||||
};
|
||||
|
||||
const CPPType *custom_data_type_to_cpp_type(eCustomDataType type);
|
||||
eCustomDataType cpp_type_to_custom_data_type(const CPPType &type);
|
||||
|
||||
/**
|
||||
* Contains information about an attribute in a geometry component.
|
||||
* More information can be added in the future. E.g. whether the attribute is builtin and how it is
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "BLI_math_vector.hh"
|
||||
#include "BLI_offset_indices.hh"
|
||||
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_attribute.hh"
|
||||
|
||||
namespace blender::bke::attribute_math {
|
||||
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include "BKE_attribute_math.hh"
|
||||
#include "BKE_curves.h"
|
||||
|
||||
struct BlendDataReader;
|
||||
struct BlendWriter;
|
||||
struct MDeformVert;
|
||||
namespace blender::bke {
|
||||
class AnonymousAttributePropagationInfo;
|
||||
|
@ -31,8 +31,6 @@ struct CustomDataTransferLayerMap;
|
||||
struct ID;
|
||||
struct MeshPairRemap;
|
||||
|
||||
using eCustomDataMask = uint64_t;
|
||||
|
||||
/* These names are used as prefixes for UV layer names to find the associated boolean
|
||||
* layers. They should never be longer than 2 chars, as #MAX_CUSTOMDATA_LAYER_NAME
|
||||
* has 4 extra bytes above what can be used for the base layer name, and these
|
||||
@ -801,7 +799,5 @@ void CustomData_debug_info_from_layers(const CustomData *data, const char *inden
|
||||
#endif /* !NDEBUG */
|
||||
|
||||
namespace blender::bke {
|
||||
const CPPType *custom_data_type_to_cpp_type(eCustomDataType type);
|
||||
eCustomDataType cpp_type_to_custom_data_type(const CPPType &type);
|
||||
std::optional<VolumeGridType> custom_data_type_to_volume_grid_type(eCustomDataType type);
|
||||
} // namespace blender::bke
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BLI_compiler_compat.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -8,8 +8,6 @@
|
||||
* \ingroup bke
|
||||
* \brief display list (or rather multi purpose list) stuff.
|
||||
*/
|
||||
#include "BKE_customdata.hh"
|
||||
#include "DNA_customdata_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -8,10 +8,11 @@
|
||||
*/
|
||||
#include "BLI_compiler_attrs.h"
|
||||
#include "BLI_math_matrix_types.hh"
|
||||
#include "BLI_span.hh"
|
||||
|
||||
#include "DNA_modifier_types.h" /* Needed for all enum type definitions. */
|
||||
|
||||
#include "BKE_customdata.hh"
|
||||
#include "DNA_customdata_types.h"
|
||||
|
||||
namespace blender::bke {
|
||||
struct GeometrySet;
|
||||
|
@ -10,28 +10,26 @@
|
||||
|
||||
#include "BLI_array.hh"
|
||||
#include "BLI_bit_vector.hh"
|
||||
#include "BLI_bitmap.h"
|
||||
#include "BLI_compiler_compat.h"
|
||||
#include "BLI_math_matrix_types.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_offset_indices.hh"
|
||||
#include "BLI_ordered_edge.hh"
|
||||
#include "BLI_set.hh"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "DNA_brush_enums.h"
|
||||
#include "DNA_customdata_types.h"
|
||||
#include "DNA_object_enums.h"
|
||||
|
||||
#include "BKE_pbvh.hh"
|
||||
|
||||
#include "bmesh.hh"
|
||||
|
||||
struct BMFace;
|
||||
struct BMLog;
|
||||
struct BMesh;
|
||||
struct BlendDataReader;
|
||||
struct BlendLibReader;
|
||||
struct BlendWriter;
|
||||
struct Brush;
|
||||
struct CustomDataLayer;
|
||||
struct CurveMapping;
|
||||
struct Depsgraph;
|
||||
struct EnumPropertyItem;
|
||||
@ -785,27 +783,6 @@ void BKE_sculpt_attribute_destroy_temporary_all(Object *ob);
|
||||
/* Destroy attributes that were marked as stroke only in SculptAttributeParams. */
|
||||
void BKE_sculpt_attributes_destroy_temporary_stroke(Object *ob);
|
||||
|
||||
BLI_INLINE void *BKE_sculpt_vertex_attr_get(const PBVHVertRef vertex, const SculptAttribute *attr)
|
||||
{
|
||||
if (attr->data) {
|
||||
char *p = (char *)attr->data;
|
||||
int idx = (int)vertex.i;
|
||||
|
||||
if (attr->data_for_bmesh) {
|
||||
BMElem *v = (BMElem *)vertex.i;
|
||||
idx = v->head.index;
|
||||
}
|
||||
|
||||
return p + attr->elem_size * (int)idx;
|
||||
}
|
||||
else {
|
||||
BMElem *v = (BMElem *)vertex.i;
|
||||
return BM_ELEM_CD_GET_VOID_P(v, attr->bmesh_cd_offset);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new color layer on object if it doesn't have one and if experimental feature set has
|
||||
* sculpt vertex color enabled. Returns truth if new layer has been added, false otherwise.
|
||||
|
@ -6,11 +6,9 @@
|
||||
|
||||
/** \file
|
||||
* \ingroup bke
|
||||
* \brief External data structures for PBVH. Does not include data structures internal to the draw
|
||||
* code.
|
||||
* \brief External data structures for PBVH. Does not include internal data structures.
|
||||
*/
|
||||
|
||||
#include "BLI_compiler_compat.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
struct PBVHNode;
|
||||
@ -76,7 +74,7 @@ struct PBVHPublic {
|
||||
struct PBVH;
|
||||
struct PBVHNode;
|
||||
|
||||
BLI_INLINE PBVHType BKE_pbvh_type(const PBVH *pbvh)
|
||||
inline PBVHType BKE_pbvh_type(const PBVH *pbvh)
|
||||
{
|
||||
return ((const PBVHPublic *)pbvh)->type;
|
||||
}
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
# include "DNA_pointcloud_types.h"
|
||||
|
||||
# include "BKE_customdata.hh"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -51,20 +50,6 @@ struct PointCloudRuntime {
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
inline blender::Span<blender::float3> PointCloud::positions() const
|
||||
{
|
||||
return {static_cast<const blender::float3 *>(
|
||||
CustomData_get_layer_named(&this->pdata, CD_PROP_FLOAT3, "position")),
|
||||
this->totpoint};
|
||||
}
|
||||
|
||||
inline blender::MutableSpan<blender::float3> PointCloud::positions_for_write()
|
||||
{
|
||||
return {static_cast<blender::float3 *>(CustomData_get_layer_named_for_write(
|
||||
&this->pdata, CD_PROP_FLOAT3, "position", this->totpoint)),
|
||||
this->totpoint};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void *BKE_pointcloud_add(struct Main *bmain, const char *name);
|
||||
|
@ -8,12 +8,9 @@
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_geometry_set.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_pointcloud.h"
|
||||
#include "BKE_type_conversions.hh"
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_pointcloud_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
#include "BLI_array_utils.hh"
|
||||
#include "BLI_color.hh"
|
||||
@ -32,6 +29,74 @@
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
const blender::CPPType *custom_data_type_to_cpp_type(const eCustomDataType type)
|
||||
{
|
||||
switch (type) {
|
||||
case CD_PROP_FLOAT:
|
||||
return &CPPType::get<float>();
|
||||
case CD_PROP_FLOAT2:
|
||||
return &CPPType::get<float2>();
|
||||
case CD_PROP_FLOAT3:
|
||||
return &CPPType::get<float3>();
|
||||
case CD_PROP_INT32:
|
||||
return &CPPType::get<int>();
|
||||
case CD_PROP_INT32_2D:
|
||||
return &CPPType::get<int2>();
|
||||
case CD_PROP_COLOR:
|
||||
return &CPPType::get<ColorGeometry4f>();
|
||||
case CD_PROP_BOOL:
|
||||
return &CPPType::get<bool>();
|
||||
case CD_PROP_INT8:
|
||||
return &CPPType::get<int8_t>();
|
||||
case CD_PROP_BYTE_COLOR:
|
||||
return &CPPType::get<ColorGeometry4b>();
|
||||
case CD_PROP_QUATERNION:
|
||||
return &CPPType::get<math::Quaternion>();
|
||||
case CD_PROP_STRING:
|
||||
return &CPPType::get<MStringProperty>();
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
eCustomDataType cpp_type_to_custom_data_type(const blender::CPPType &type)
|
||||
{
|
||||
if (type.is<float>()) {
|
||||
return CD_PROP_FLOAT;
|
||||
}
|
||||
if (type.is<float2>()) {
|
||||
return CD_PROP_FLOAT2;
|
||||
}
|
||||
if (type.is<float3>()) {
|
||||
return CD_PROP_FLOAT3;
|
||||
}
|
||||
if (type.is<int>()) {
|
||||
return CD_PROP_INT32;
|
||||
}
|
||||
if (type.is<int2>()) {
|
||||
return CD_PROP_INT32_2D;
|
||||
}
|
||||
if (type.is<ColorGeometry4f>()) {
|
||||
return CD_PROP_COLOR;
|
||||
}
|
||||
if (type.is<bool>()) {
|
||||
return CD_PROP_BOOL;
|
||||
}
|
||||
if (type.is<int8_t>()) {
|
||||
return CD_PROP_INT8;
|
||||
}
|
||||
if (type.is<ColorGeometry4b>()) {
|
||||
return CD_PROP_BYTE_COLOR;
|
||||
}
|
||||
if (type.is<math::Quaternion>()) {
|
||||
return CD_PROP_QUATERNION;
|
||||
}
|
||||
if (type.is<MStringProperty>()) {
|
||||
return CD_PROP_STRING;
|
||||
}
|
||||
return static_cast<eCustomDataType>(-1);
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &stream, const AttributeIDRef &attribute_id)
|
||||
{
|
||||
if (attribute_id) {
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "BKE_bake_items.hh"
|
||||
#include "BKE_bake_items_serialize.hh"
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_instances.hh"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_mesh.hh"
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include "BKE_bvhutils.hh"
|
||||
#include "BKE_cloth.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_effect.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_lib_id.h"
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "BKE_attribute_math.hh"
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_geometry_set.hh"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_mesh.hh"
|
||||
|
@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include "BKE_curves_utils.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
|
||||
namespace blender::bke::curves {
|
||||
|
||||
|
@ -5294,36 +5294,6 @@ namespace blender::bke {
|
||||
/** \name Custom Data C++ API
|
||||
* \{ */
|
||||
|
||||
const blender::CPPType *custom_data_type_to_cpp_type(const eCustomDataType type)
|
||||
{
|
||||
switch (type) {
|
||||
case CD_PROP_FLOAT:
|
||||
return &CPPType::get<float>();
|
||||
case CD_PROP_FLOAT2:
|
||||
return &CPPType::get<float2>();
|
||||
case CD_PROP_FLOAT3:
|
||||
return &CPPType::get<float3>();
|
||||
case CD_PROP_INT32:
|
||||
return &CPPType::get<int>();
|
||||
case CD_PROP_INT32_2D:
|
||||
return &CPPType::get<int2>();
|
||||
case CD_PROP_COLOR:
|
||||
return &CPPType::get<ColorGeometry4f>();
|
||||
case CD_PROP_BOOL:
|
||||
return &CPPType::get<bool>();
|
||||
case CD_PROP_INT8:
|
||||
return &CPPType::get<int8_t>();
|
||||
case CD_PROP_BYTE_COLOR:
|
||||
return &CPPType::get<ColorGeometry4b>();
|
||||
case CD_PROP_QUATERNION:
|
||||
return &CPPType::get<math::Quaternion>();
|
||||
case CD_PROP_STRING:
|
||||
return &CPPType::get<MStringProperty>();
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<VolumeGridType> custom_data_type_to_volume_grid_type(const eCustomDataType type)
|
||||
{
|
||||
switch (type) {
|
||||
@ -5340,44 +5310,6 @@ std::optional<VolumeGridType> custom_data_type_to_volume_grid_type(const eCustom
|
||||
}
|
||||
}
|
||||
|
||||
eCustomDataType cpp_type_to_custom_data_type(const blender::CPPType &type)
|
||||
{
|
||||
if (type.is<float>()) {
|
||||
return CD_PROP_FLOAT;
|
||||
}
|
||||
if (type.is<float2>()) {
|
||||
return CD_PROP_FLOAT2;
|
||||
}
|
||||
if (type.is<float3>()) {
|
||||
return CD_PROP_FLOAT3;
|
||||
}
|
||||
if (type.is<int>()) {
|
||||
return CD_PROP_INT32;
|
||||
}
|
||||
if (type.is<int2>()) {
|
||||
return CD_PROP_INT32_2D;
|
||||
}
|
||||
if (type.is<ColorGeometry4f>()) {
|
||||
return CD_PROP_COLOR;
|
||||
}
|
||||
if (type.is<bool>()) {
|
||||
return CD_PROP_BOOL;
|
||||
}
|
||||
if (type.is<int8_t>()) {
|
||||
return CD_PROP_INT8;
|
||||
}
|
||||
if (type.is<ColorGeometry4b>()) {
|
||||
return CD_PROP_BYTE_COLOR;
|
||||
}
|
||||
if (type.is<math::Quaternion>()) {
|
||||
return CD_PROP_QUATERNION;
|
||||
}
|
||||
if (type.is<MStringProperty>()) {
|
||||
return CD_PROP_STRING;
|
||||
}
|
||||
return static_cast<eCustomDataType>(-1);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender::bke
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_grease_pencil.hh"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_lib_id.h"
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "BLI_task.hh"
|
||||
|
||||
#include "BKE_attribute_math.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_geometry_set.hh"
|
||||
#include "BKE_instances.hh"
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "BLI_threads.h"
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
|
||||
namespace blender::bke {
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_attribute_math.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
|
||||
namespace blender::bke {
|
||||
|
@ -9,6 +9,8 @@
|
||||
* its corresponding grids to match a given original mesh.
|
||||
*/
|
||||
|
||||
#include <queue>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
@ -16,7 +18,6 @@
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BLI_gsqueue.h"
|
||||
#include "BLI_math_vector.h"
|
||||
|
||||
#include "BKE_customdata.hh"
|
||||
@ -163,10 +164,8 @@ static bool is_vertex_diagonal(BMVert *from_v, BMVert *to_v)
|
||||
*/
|
||||
static void unsubdivide_face_center_vertex_tag(BMesh *bm, BMVert *initial_vertex)
|
||||
{
|
||||
bool *visited_verts = static_cast<bool *>(
|
||||
MEM_calloc_arrayN(bm->totvert, sizeof(bool), "visited vertices"));
|
||||
GSQueue *queue;
|
||||
queue = BLI_gsqueue_new(sizeof(BMVert *));
|
||||
blender::BitVector<> visited_verts(bm->totvert);
|
||||
std::queue<BMVert *> queue;
|
||||
|
||||
/* Add and tag the vertices connected by a diagonal to initial_vertex to the flood fill queue. If
|
||||
* initial_vertex is a pole and there is a valid solution, those vertices should be the (0,0) of
|
||||
@ -179,8 +178,8 @@ static void unsubdivide_face_center_vertex_tag(BMesh *bm, BMVert *initial_vertex
|
||||
BM_ITER_ELEM (neighbor_v, &iter_a, f, BM_VERTS_OF_FACE) {
|
||||
int neighbor_vertex_index = BM_elem_index_get(neighbor_v);
|
||||
if (neighbor_v != initial_vertex && is_vertex_diagonal(neighbor_v, initial_vertex)) {
|
||||
BLI_gsqueue_push(queue, &neighbor_v);
|
||||
visited_verts[neighbor_vertex_index] = true;
|
||||
queue.push(neighbor_v);
|
||||
visited_verts[neighbor_vertex_index].set();
|
||||
BM_elem_flag_set(neighbor_v, BM_ELEM_TAG, true);
|
||||
}
|
||||
}
|
||||
@ -191,44 +190,39 @@ static void unsubdivide_face_center_vertex_tag(BMesh *bm, BMVert *initial_vertex
|
||||
* direction. If a solution exists and `initial_vertex` was a pole, this is guaranteed that will
|
||||
* tag all the (0,0) vertices of the grids, and nothing else. */
|
||||
/* If it was not a pole, it may or may not find a solution, even if the solution exists. */
|
||||
while (!BLI_gsqueue_is_empty(queue)) {
|
||||
BMVert *from_v;
|
||||
BLI_gsqueue_pop(queue, &from_v);
|
||||
while (!queue.empty()) {
|
||||
BMVert *from_v = queue.front();
|
||||
queue.pop();
|
||||
|
||||
/* Get the diagonals (first connected step) */
|
||||
GSQueue *diagonals;
|
||||
diagonals = BLI_gsqueue_new(sizeof(BMVert *));
|
||||
std::queue<BMVert *> diagonals;
|
||||
BM_ITER_ELEM (f, &iter, from_v, BM_FACES_OF_VERT) {
|
||||
BM_ITER_ELEM (neighbor_v, &iter_a, f, BM_VERTS_OF_FACE) {
|
||||
if (neighbor_v != from_v && is_vertex_diagonal(neighbor_v, from_v)) {
|
||||
BLI_gsqueue_push(diagonals, &neighbor_v);
|
||||
diagonals.push(neighbor_v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do the second connected step. This vertices are the ones that are added to the flood fill
|
||||
* queue. */
|
||||
while (!BLI_gsqueue_is_empty(diagonals)) {
|
||||
BMVert *diagonal_v;
|
||||
BLI_gsqueue_pop(diagonals, &diagonal_v);
|
||||
while (!diagonals.empty()) {
|
||||
BMVert *diagonal_v = diagonals.front();
|
||||
diagonals.pop();
|
||||
BM_ITER_ELEM (f, &iter, diagonal_v, BM_FACES_OF_VERT) {
|
||||
BM_ITER_ELEM (neighbor_v, &iter_a, f, BM_VERTS_OF_FACE) {
|
||||
int neighbor_vertex_index = BM_elem_index_get(neighbor_v);
|
||||
if (!visited_verts[neighbor_vertex_index] && neighbor_v != diagonal_v &&
|
||||
is_vertex_diagonal(neighbor_v, diagonal_v))
|
||||
{
|
||||
BLI_gsqueue_push(queue, &neighbor_v);
|
||||
visited_verts[neighbor_vertex_index] = true;
|
||||
queue.push(neighbor_v);
|
||||
visited_verts[neighbor_vertex_index].set();
|
||||
BM_elem_flag_set(neighbor_v, BM_ELEM_TAG, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BLI_gsqueue_free(diagonals);
|
||||
}
|
||||
|
||||
BLI_gsqueue_free(queue);
|
||||
MEM_freeN(visited_verts);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -292,10 +286,10 @@ static bool unsubdivide_tag_disconnected_mesh_element(BMesh *bm, int *elem_id, i
|
||||
/* First, get vertex candidates to try to generate possible un-subdivide solution. */
|
||||
/* Find a vertex pole. If there is a solution on an all quad base mesh, this vertex should be
|
||||
* part of the base mesh. If it isn't, then there is no solution. */
|
||||
GSQueue *initial_vertex = BLI_gsqueue_new(sizeof(BMVert *));
|
||||
std::queue<BMVert *> initial_vertex;
|
||||
BMVert *initial_vertex_pole = unsubdivide_find_any_pole(bm, elem_id, elem);
|
||||
if (initial_vertex_pole != nullptr) {
|
||||
BLI_gsqueue_push(initial_vertex, &initial_vertex_pole);
|
||||
initial_vertex.push(initial_vertex_pole);
|
||||
}
|
||||
|
||||
/* Also try from the different 4 vertices of a quad in the current
|
||||
@ -317,16 +311,16 @@ static bool unsubdivide_tag_disconnected_mesh_element(BMesh *bm, int *elem_id, i
|
||||
}
|
||||
|
||||
BM_ITER_ELEM (v, &iter_a, init_face, BM_VERTS_OF_FACE) {
|
||||
BLI_gsqueue_push(initial_vertex, &v);
|
||||
initial_vertex.push(v);
|
||||
}
|
||||
|
||||
bool valid_tag_found = false;
|
||||
|
||||
/* Check all vertex candidates to a solution. */
|
||||
while (!BLI_gsqueue_is_empty(initial_vertex)) {
|
||||
while (!initial_vertex.empty()) {
|
||||
|
||||
BMVert *iv;
|
||||
BLI_gsqueue_pop(initial_vertex, &iv);
|
||||
BMVert *iv = initial_vertex.front();
|
||||
initial_vertex.pop();
|
||||
|
||||
/* Generate a possible solution. */
|
||||
unsubdivide_face_center_vertex_tag(bm, iv);
|
||||
@ -347,7 +341,6 @@ static bool unsubdivide_tag_disconnected_mesh_element(BMesh *bm, int *elem_id, i
|
||||
}
|
||||
}
|
||||
}
|
||||
BLI_gsqueue_free(initial_vertex);
|
||||
return valid_tag_found;
|
||||
}
|
||||
|
||||
@ -361,31 +354,29 @@ static int unsubdivide_init_elem_ids(BMesh *bm, int *elem_id)
|
||||
int current_id = 0;
|
||||
for (int i = 0; i < bm->totvert; i++) {
|
||||
if (!visited_verts[i]) {
|
||||
GSQueue *queue;
|
||||
queue = BLI_gsqueue_new(sizeof(BMVert *));
|
||||
std::queue<BMVert *> queue;
|
||||
|
||||
visited_verts[i] = true;
|
||||
elem_id[i] = current_id;
|
||||
BMVert *iv = BM_vert_at_index(bm, i);
|
||||
BLI_gsqueue_push(queue, &iv);
|
||||
queue.push(BM_vert_at_index(bm, i));
|
||||
|
||||
while (!BLI_gsqueue_is_empty(queue)) {
|
||||
while (!queue.empty()) {
|
||||
BMIter iter;
|
||||
BMVert *current_v, *neighbor_v;
|
||||
BMVert *current_v = queue.front();
|
||||
queue.pop();
|
||||
BMVert *neighbor_v;
|
||||
BMEdge *ed;
|
||||
BLI_gsqueue_pop(queue, ¤t_v);
|
||||
BM_ITER_ELEM (ed, &iter, current_v, BM_EDGES_OF_VERT) {
|
||||
neighbor_v = BM_edge_other_vert(ed, current_v);
|
||||
const int neighbor_index = BM_elem_index_get(neighbor_v);
|
||||
if (!visited_verts[neighbor_index]) {
|
||||
visited_verts[neighbor_index] = true;
|
||||
elem_id[neighbor_index] = current_id;
|
||||
BLI_gsqueue_push(queue, &neighbor_v);
|
||||
queue.push(neighbor_v);
|
||||
}
|
||||
}
|
||||
}
|
||||
current_id++;
|
||||
BLI_gsqueue_free(queue);
|
||||
}
|
||||
}
|
||||
MEM_freeN(visited_verts);
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include "BKE_cloth.hh"
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_colortools.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_displist.h"
|
||||
#include "BKE_effect.h"
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "BKE_boids.h"
|
||||
#include "BKE_collision.h"
|
||||
#include "BKE_colortools.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_effect.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_lib_query.h"
|
||||
|
@ -47,6 +47,7 @@
|
||||
|
||||
using blender::float3;
|
||||
using blender::IndexRange;
|
||||
using blender::MutableSpan;
|
||||
using blender::Span;
|
||||
using blender::Vector;
|
||||
|
||||
@ -197,6 +198,20 @@ static void pointcloud_random(PointCloud *pointcloud)
|
||||
BLI_rng_free(rng);
|
||||
}
|
||||
|
||||
Span<float3> PointCloud::positions() const
|
||||
{
|
||||
return {static_cast<const float3 *>(
|
||||
CustomData_get_layer_named(&this->pdata, CD_PROP_FLOAT3, "position")),
|
||||
this->totpoint};
|
||||
}
|
||||
|
||||
MutableSpan<float3> PointCloud::positions_for_write()
|
||||
{
|
||||
return {static_cast<float3 *>(CustomData_get_layer_named_for_write(
|
||||
&this->pdata, CD_PROP_FLOAT3, "position", this->totpoint)),
|
||||
this->totpoint};
|
||||
}
|
||||
|
||||
void *BKE_pointcloud_add(Main *bmain, const char *name)
|
||||
{
|
||||
PointCloud *pointcloud = static_cast<PointCloud *>(BKE_id_new(bmain, ID_PT, name));
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_collision.h"
|
||||
#include "BKE_curve.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_effect.h"
|
||||
#include "BKE_global.h"
|
||||
@ -2678,7 +2679,7 @@ static void mesh_to_softbody(Object *ob)
|
||||
{
|
||||
SoftBody *sb;
|
||||
Mesh *mesh = static_cast<Mesh *>(ob->data);
|
||||
const vec2i *edge = static_cast<const vec2i *>(
|
||||
const blender::int2 *edge = static_cast<const blender::int2 *>(
|
||||
CustomData_get_layer_named(&mesh->edge_data, CD_PROP_INT32_2D, ".edge_verts"));
|
||||
BodyPoint *bp;
|
||||
BodySpring *bs;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_mesh_mapping.hh"
|
||||
#include "BKE_subdiv.hh"
|
||||
|
@ -34,6 +34,7 @@
|
||||
|
||||
#include "BKE_ccg.h"
|
||||
#include "BKE_cdderivedmesh.h"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_mesh_mapping.hh"
|
||||
#include "BKE_modifier.hh"
|
||||
|
@ -1,48 +0,0 @@
|
||||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
/** \file
|
||||
* \ingroup bli
|
||||
*/
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _GSQueue GSQueue;
|
||||
|
||||
GSQueue *BLI_gsqueue_new(size_t elem_size);
|
||||
/**
|
||||
* Returns true if the queue is empty, false otherwise.
|
||||
*/
|
||||
bool BLI_gsqueue_is_empty(const GSQueue *queue);
|
||||
size_t BLI_gsqueue_len(const GSQueue *queue);
|
||||
/**
|
||||
* Retrieves and removes the first element from the queue.
|
||||
* The value is copies to \a r_item, which must be at least \a elem_size bytes.
|
||||
*
|
||||
* Does not reduce amount of allocated memory.
|
||||
*/
|
||||
void BLI_gsqueue_pop(GSQueue *queue, void *r_item);
|
||||
/**
|
||||
* Copies the source value onto the end of the queue
|
||||
*
|
||||
* \note This copies #GSQueue.elem_size bytes from \a item,
|
||||
* (the pointer itself is not stored).
|
||||
*
|
||||
* \param item: source data to be copied to the queue.
|
||||
*/
|
||||
void BLI_gsqueue_push(GSQueue *queue, const void *item);
|
||||
/**
|
||||
* Free the queue's data and the queue itself.
|
||||
*/
|
||||
void BLI_gsqueue_free(GSQueue *queue);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -76,7 +76,6 @@ set(SRC
|
||||
intern/generic_vector_array.cc
|
||||
intern/generic_virtual_array.cc
|
||||
intern/generic_virtual_vector_array.cc
|
||||
intern/gsqueue.c
|
||||
intern/hash_md5.c
|
||||
intern/hash_mm2a.c
|
||||
intern/hash_mm3.c
|
||||
@ -239,7 +238,6 @@ set(SRC
|
||||
BLI_generic_virtual_array.hh
|
||||
BLI_generic_virtual_vector_array.hh
|
||||
BLI_ghash.h
|
||||
BLI_gsqueue.h
|
||||
BLI_hash.h
|
||||
BLI_hash.hh
|
||||
BLI_hash_md5.h
|
||||
|
@ -1,164 +0,0 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup bli
|
||||
*
|
||||
* \brief A generic structure queue
|
||||
* (a queue for fixed length generally small) structures.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_gsqueue.h"
|
||||
#include "BLI_strict_flags.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
/* target chunk size: 64kb */
|
||||
#define CHUNK_SIZE_DEFAULT (1 << 16)
|
||||
/* ensure we get at least this many elems per chunk */
|
||||
#define CHUNK_ELEM_MIN 32
|
||||
|
||||
struct QueueChunk {
|
||||
struct QueueChunk *next;
|
||||
char data[0];
|
||||
};
|
||||
|
||||
struct _GSQueue {
|
||||
struct QueueChunk *chunk_first; /* first active chunk to pop from */
|
||||
struct QueueChunk *chunk_last; /* last active chunk to push onto */
|
||||
struct QueueChunk *chunk_free; /* free chunks to reuse */
|
||||
size_t chunk_first_index; /* index into 'chunk_first' */
|
||||
size_t chunk_last_index; /* index into 'chunk_last' */
|
||||
size_t chunk_elem_max; /* number of elements per chunk */
|
||||
size_t elem_size; /* memory size of elements */
|
||||
size_t elem_num; /* total number of elements */
|
||||
};
|
||||
|
||||
static void *queue_get_first_elem(GSQueue *queue)
|
||||
{
|
||||
return ((char *)(queue)->chunk_first->data) + ((queue)->elem_size * (queue)->chunk_first_index);
|
||||
}
|
||||
|
||||
static void *queue_get_last_elem(GSQueue *queue)
|
||||
{
|
||||
return ((char *)(queue)->chunk_last->data) + ((queue)->elem_size * (queue)->chunk_last_index);
|
||||
}
|
||||
|
||||
/**
|
||||
* \return number of elements per chunk, optimized for slop-space.
|
||||
*/
|
||||
static size_t queue_chunk_elem_max_calc(const size_t elem_size, size_t chunk_size)
|
||||
{
|
||||
/* get at least this number of elems per chunk */
|
||||
const size_t elem_size_min = elem_size * CHUNK_ELEM_MIN;
|
||||
|
||||
BLI_assert((elem_size != 0) && (chunk_size != 0));
|
||||
|
||||
while (UNLIKELY(chunk_size <= elem_size_min)) {
|
||||
chunk_size <<= 1;
|
||||
}
|
||||
|
||||
/* account for slop-space */
|
||||
chunk_size -= (sizeof(struct QueueChunk) + MEM_SIZE_OVERHEAD);
|
||||
|
||||
return chunk_size / elem_size;
|
||||
}
|
||||
|
||||
GSQueue *BLI_gsqueue_new(const size_t elem_size)
|
||||
{
|
||||
GSQueue *queue = MEM_callocN(sizeof(*queue), "BLI_gsqueue_new");
|
||||
|
||||
queue->chunk_elem_max = queue_chunk_elem_max_calc(elem_size, CHUNK_SIZE_DEFAULT);
|
||||
queue->elem_size = elem_size;
|
||||
/* force init */
|
||||
queue->chunk_last_index = queue->chunk_elem_max - 1;
|
||||
|
||||
return queue;
|
||||
}
|
||||
|
||||
static void queue_free_chunk(struct QueueChunk *data)
|
||||
{
|
||||
while (data) {
|
||||
struct QueueChunk *data_next = data->next;
|
||||
MEM_freeN(data);
|
||||
data = data_next;
|
||||
}
|
||||
}
|
||||
|
||||
void BLI_gsqueue_free(GSQueue *queue)
|
||||
{
|
||||
queue_free_chunk(queue->chunk_first);
|
||||
queue_free_chunk(queue->chunk_free);
|
||||
MEM_freeN(queue);
|
||||
}
|
||||
|
||||
void BLI_gsqueue_push(GSQueue *queue, const void *item)
|
||||
{
|
||||
queue->chunk_last_index++;
|
||||
queue->elem_num++;
|
||||
|
||||
if (UNLIKELY(queue->chunk_last_index == queue->chunk_elem_max)) {
|
||||
struct QueueChunk *chunk;
|
||||
if (queue->chunk_free) {
|
||||
chunk = queue->chunk_free;
|
||||
queue->chunk_free = chunk->next;
|
||||
}
|
||||
else {
|
||||
chunk = MEM_mallocN(sizeof(*chunk) + (queue->elem_size * queue->chunk_elem_max), __func__);
|
||||
}
|
||||
|
||||
chunk->next = NULL;
|
||||
|
||||
if (queue->chunk_last == NULL) {
|
||||
queue->chunk_first = chunk;
|
||||
}
|
||||
else {
|
||||
queue->chunk_last->next = chunk;
|
||||
}
|
||||
|
||||
queue->chunk_last = chunk;
|
||||
queue->chunk_last_index = 0;
|
||||
}
|
||||
|
||||
BLI_assert(queue->chunk_last_index < queue->chunk_elem_max);
|
||||
|
||||
/* Return last of queue */
|
||||
memcpy(queue_get_last_elem(queue), item, queue->elem_size);
|
||||
}
|
||||
|
||||
void BLI_gsqueue_pop(GSQueue *queue, void *r_item)
|
||||
{
|
||||
BLI_assert(BLI_gsqueue_is_empty(queue) == false);
|
||||
|
||||
memcpy(r_item, queue_get_first_elem(queue), queue->elem_size);
|
||||
queue->chunk_first_index++;
|
||||
queue->elem_num--;
|
||||
|
||||
if (UNLIKELY(queue->chunk_first_index == queue->chunk_elem_max || queue->elem_num == 0)) {
|
||||
struct QueueChunk *chunk_free = queue->chunk_first;
|
||||
|
||||
queue->chunk_first = queue->chunk_first->next;
|
||||
queue->chunk_first_index = 0;
|
||||
if (queue->chunk_first == NULL) {
|
||||
queue->chunk_last = NULL;
|
||||
queue->chunk_last_index = queue->chunk_elem_max - 1;
|
||||
}
|
||||
|
||||
chunk_free->next = queue->chunk_free;
|
||||
queue->chunk_free = chunk_free;
|
||||
}
|
||||
}
|
||||
|
||||
size_t BLI_gsqueue_len(const GSQueue *queue)
|
||||
{
|
||||
return queue->elem_num;
|
||||
}
|
||||
|
||||
bool BLI_gsqueue_is_empty(const GSQueue *queue)
|
||||
{
|
||||
return (queue->chunk_first == NULL);
|
||||
}
|
@ -9,10 +9,10 @@
|
||||
#include <cerrno>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <queue>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_gsqueue.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_system.h"
|
||||
#include "BLI_task.h"
|
||||
@ -578,7 +578,7 @@ void BLI_condition_end(ThreadCondition *cond)
|
||||
/* ************************************************ */
|
||||
|
||||
struct ThreadQueue {
|
||||
GSQueue *queue;
|
||||
std::queue<void *> queue;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t push_cond;
|
||||
pthread_cond_t finish_cond;
|
||||
@ -588,11 +588,7 @@ struct ThreadQueue {
|
||||
|
||||
ThreadQueue *BLI_thread_queue_init()
|
||||
{
|
||||
ThreadQueue *queue;
|
||||
|
||||
queue = static_cast<ThreadQueue *>(MEM_callocN(sizeof(ThreadQueue), "ThreadQueue"));
|
||||
queue->queue = BLI_gsqueue_new(sizeof(void *));
|
||||
|
||||
ThreadQueue *queue = MEM_new<ThreadQueue>(__func__);
|
||||
pthread_mutex_init(&queue->mutex, nullptr);
|
||||
pthread_cond_init(&queue->push_cond, nullptr);
|
||||
pthread_cond_init(&queue->finish_cond, nullptr);
|
||||
@ -607,16 +603,14 @@ void BLI_thread_queue_free(ThreadQueue *queue)
|
||||
pthread_cond_destroy(&queue->push_cond);
|
||||
pthread_mutex_destroy(&queue->mutex);
|
||||
|
||||
BLI_gsqueue_free(queue->queue);
|
||||
|
||||
MEM_freeN(queue);
|
||||
MEM_delete(queue);
|
||||
}
|
||||
|
||||
void BLI_thread_queue_push(ThreadQueue *queue, void *work)
|
||||
{
|
||||
pthread_mutex_lock(&queue->mutex);
|
||||
|
||||
BLI_gsqueue_push(queue->queue, &work);
|
||||
queue->queue.push(work);
|
||||
|
||||
/* signal threads waiting to pop */
|
||||
pthread_cond_signal(&queue->push_cond);
|
||||
@ -629,15 +623,16 @@ void *BLI_thread_queue_pop(ThreadQueue *queue)
|
||||
|
||||
/* wait until there is work */
|
||||
pthread_mutex_lock(&queue->mutex);
|
||||
while (BLI_gsqueue_is_empty(queue->queue) && !queue->nowait) {
|
||||
while (queue->queue.empty() && !queue->nowait) {
|
||||
pthread_cond_wait(&queue->push_cond, &queue->mutex);
|
||||
}
|
||||
|
||||
/* if we have something, pop it */
|
||||
if (!BLI_gsqueue_is_empty(queue->queue)) {
|
||||
BLI_gsqueue_pop(queue->queue, &work);
|
||||
if (!queue->queue.empty()) {
|
||||
work = queue->queue.front();
|
||||
queue->queue.pop();
|
||||
|
||||
if (BLI_gsqueue_is_empty(queue->queue)) {
|
||||
if (queue->queue.empty()) {
|
||||
pthread_cond_broadcast(&queue->finish_cond);
|
||||
}
|
||||
}
|
||||
@ -693,7 +688,7 @@ void *BLI_thread_queue_pop_timeout(ThreadQueue *queue, int ms)
|
||||
|
||||
/* wait until there is work */
|
||||
pthread_mutex_lock(&queue->mutex);
|
||||
while (BLI_gsqueue_is_empty(queue->queue) && !queue->nowait) {
|
||||
while (queue->queue.empty() && !queue->nowait) {
|
||||
if (pthread_cond_timedwait(&queue->push_cond, &queue->mutex, &timeout) == ETIMEDOUT) {
|
||||
break;
|
||||
}
|
||||
@ -703,10 +698,11 @@ void *BLI_thread_queue_pop_timeout(ThreadQueue *queue, int ms)
|
||||
}
|
||||
|
||||
/* if we have something, pop it */
|
||||
if (!BLI_gsqueue_is_empty(queue->queue)) {
|
||||
BLI_gsqueue_pop(queue->queue, &work);
|
||||
if (!queue->queue.empty()) {
|
||||
work = queue->queue.front();
|
||||
queue->queue.pop();
|
||||
|
||||
if (BLI_gsqueue_is_empty(queue->queue)) {
|
||||
if (queue->queue.empty()) {
|
||||
pthread_cond_broadcast(&queue->finish_cond);
|
||||
}
|
||||
}
|
||||
@ -721,7 +717,7 @@ int BLI_thread_queue_len(ThreadQueue *queue)
|
||||
int size;
|
||||
|
||||
pthread_mutex_lock(&queue->mutex);
|
||||
size = BLI_gsqueue_len(queue->queue);
|
||||
size = queue->queue.size();
|
||||
pthread_mutex_unlock(&queue->mutex);
|
||||
|
||||
return size;
|
||||
@ -732,7 +728,7 @@ bool BLI_thread_queue_is_empty(ThreadQueue *queue)
|
||||
bool is_empty;
|
||||
|
||||
pthread_mutex_lock(&queue->mutex);
|
||||
is_empty = BLI_gsqueue_is_empty(queue->queue);
|
||||
is_empty = queue->queue.empty();
|
||||
pthread_mutex_unlock(&queue->mutex);
|
||||
|
||||
return is_empty;
|
||||
@ -754,7 +750,7 @@ void BLI_thread_queue_wait_finish(ThreadQueue *queue)
|
||||
/* wait for finish condition */
|
||||
pthread_mutex_lock(&queue->mutex);
|
||||
|
||||
while (!BLI_gsqueue_is_empty(queue->queue)) {
|
||||
while (!queue->queue.empty()) {
|
||||
pthread_cond_wait(&queue->finish_cond, &queue->mutex);
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,7 @@
|
||||
#include "BKE_anim_visualization.h"
|
||||
#include "BKE_armature.hh"
|
||||
#include "BKE_colortools.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_global.h" /* for G */
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_main.hh"
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_anim_visualization.h"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_main.hh" /* for Main */
|
||||
#include "BKE_mesh.hh" /* for ME_ defines (patching) */
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "BKE_anim_data.h"
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_colortools.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_fcurve_driver.h"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_mask.h"
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include "BKE_colortools.hh"
|
||||
#include "BKE_cryptomatte.h"
|
||||
#include "BKE_curve.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_gpencil_legacy.h"
|
||||
#include "BKE_lib_id.h"
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include "BKE_colortools.hh"
|
||||
#include "BKE_curve.hh"
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_data_transfer.h"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_fcurve.h"
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_armature.hh"
|
||||
#include "BKE_constraint.h"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_lattice.hh"
|
||||
|
@ -8,13 +8,14 @@
|
||||
* Evaluation engine entry-points for Depsgraph Engine.
|
||||
*/
|
||||
|
||||
#include <queue>
|
||||
|
||||
#include "intern/eval/deg_eval.h"
|
||||
|
||||
#include "PIL_time.h"
|
||||
|
||||
#include "BLI_compiler_attrs.h"
|
||||
#include "BLI_function_ref.hh"
|
||||
#include "BLI_gsqueue.h"
|
||||
#include "BLI_task.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
@ -335,21 +336,18 @@ void evaluate_graph_single_threaded_if_needed(DepsgraphEvalState *state)
|
||||
|
||||
state->stage = EvaluationStage::SINGLE_THREADED_WORKAROUND;
|
||||
|
||||
GSQueue *evaluation_queue = BLI_gsqueue_new(sizeof(OperationNode *));
|
||||
auto schedule_node_to_queue = [&](OperationNode *node) {
|
||||
BLI_gsqueue_push(evaluation_queue, &node);
|
||||
};
|
||||
std::queue<OperationNode *> evaluation_queue;
|
||||
auto schedule_node_to_queue = [&](OperationNode *node) { evaluation_queue.push(node); };
|
||||
|
||||
schedule_graph(state, schedule_node_to_queue);
|
||||
|
||||
while (!BLI_gsqueue_is_empty(evaluation_queue)) {
|
||||
OperationNode *operation_node;
|
||||
BLI_gsqueue_pop(evaluation_queue, &operation_node);
|
||||
while (!evaluation_queue.empty()) {
|
||||
OperationNode *operation_node = evaluation_queue.front();
|
||||
evaluation_queue.pop();
|
||||
|
||||
evaluate_node(state, operation_node);
|
||||
schedule_children(state, operation_node, schedule_node_to_queue);
|
||||
}
|
||||
|
||||
BLI_gsqueue_free(evaluation_queue);
|
||||
}
|
||||
|
||||
void depsgraph_ensure_view_layer(Depsgraph *graph)
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
|
||||
#include "draw_attributes.hh"
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include "BKE_crazyspace.hh"
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_geometry_set.hh"
|
||||
|
||||
#include "GPU_batch.h"
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_armature.hh"
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_mesh_iterators.hh"
|
||||
@ -200,6 +201,7 @@ static void envelope_bone_weighting(Object *ob,
|
||||
const int *selected,
|
||||
float scale)
|
||||
{
|
||||
using namespace blender;
|
||||
/* Create vertex group weights from envelopes */
|
||||
|
||||
bool use_topology = (mesh->editflag & ME_EDIT_MIRROR_TOPO) != 0;
|
||||
@ -211,8 +213,8 @@ static void envelope_bone_weighting(Object *ob,
|
||||
use_mask = true;
|
||||
}
|
||||
|
||||
const bool *select_vert = (const bool *)CustomData_get_layer_named(
|
||||
&mesh->vert_data, CD_PROP_BOOL, ".select_vert");
|
||||
const bke::AttributeAccessor attributes = mesh->attributes();
|
||||
const VArray select_vert = *attributes.lookup<bool>(".select_vert", bke::AttrDomain::Point);
|
||||
|
||||
/* for each vertex in the mesh */
|
||||
for (int i = 0; i < mesh->verts_num; i++) {
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_bvhutils.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_mesh_runtime.hh"
|
||||
@ -641,6 +642,7 @@ void heat_bone_weighting(Object *ob,
|
||||
const int *selected,
|
||||
const char **error_str)
|
||||
{
|
||||
using namespace blender;
|
||||
LaplacianSystem *sys;
|
||||
blender::int3 *corner_tris;
|
||||
float solution, weight;
|
||||
@ -651,6 +653,7 @@ void heat_bone_weighting(Object *ob,
|
||||
const blender::Span<blender::float3> vert_positions = mesh->vert_positions();
|
||||
const blender::OffsetIndices faces = mesh->faces();
|
||||
const blender::Span<int> corner_verts = mesh->corner_verts();
|
||||
const bke::AttributeAccessor attributes = mesh->attributes();
|
||||
bool use_vert_sel = (mesh->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
|
||||
bool use_face_sel = (mesh->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
|
||||
|
||||
@ -666,8 +669,8 @@ void heat_bone_weighting(Object *ob,
|
||||
|
||||
/* (added selectedVerts content for vertex mask, they used to just equal 1) */
|
||||
if (use_vert_sel) {
|
||||
const bool *select_vert = (const bool *)CustomData_get_layer_named(
|
||||
&mesh->vert_data, CD_PROP_BOOL, ".select_vert");
|
||||
const VArray select_vert = *attributes.lookup_or_default<bool>(
|
||||
".select_vert", bke::AttrDomain::Point, false);
|
||||
if (select_vert) {
|
||||
for (const int i : faces.index_range()) {
|
||||
for (const int vert : corner_verts.slice(faces[i])) {
|
||||
@ -677,8 +680,8 @@ void heat_bone_weighting(Object *ob,
|
||||
}
|
||||
}
|
||||
else if (use_face_sel) {
|
||||
const bool *select_poly = (const bool *)CustomData_get_layer_named(
|
||||
&mesh->face_data, CD_PROP_BOOL, ".select_poly");
|
||||
const VArray select_poly = *attributes.lookup_or_default<bool>(
|
||||
".select_poly", bke::AttrDomain::Face, false);
|
||||
if (select_poly) {
|
||||
for (const int i : faces.index_range()) {
|
||||
if (select_poly[i]) {
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "BKE_bvhutils.hh"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_geometry_set.hh"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.h"
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_geometry_set.hh"
|
||||
#include "BKE_lib_id.h"
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "BKE_compute_contexts.hh"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_editmesh.hh"
|
||||
#include "BKE_geometry_set.hh"
|
||||
#include "BKE_layer.h"
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_editmesh.hh"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.h"
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "BKE_curve.hh"
|
||||
#include "BKE_curve_to_mesh.hh"
|
||||
#include "BKE_curves.h"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_displist.h"
|
||||
#include "BKE_duplilist.h"
|
||||
#include "BKE_effect.h"
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "BKE_blender.h"
|
||||
#include "BKE_cdderivedmesh.h"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_material.h"
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_data_transfer.h"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_mesh_mapping.hh"
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include "BKE_bvhutils.hh"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_main.hh"
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "BKE_bvhutils.hh"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.h"
|
||||
|
@ -534,7 +534,7 @@ struct LassoGestureData {
|
||||
int width;
|
||||
|
||||
/* 2D bitmap to test if a vertex is affected by the lasso shape. */
|
||||
BLI_bitmap *mask_px;
|
||||
blender::BitVector<> mask_px;
|
||||
};
|
||||
|
||||
struct LineGestureData {
|
||||
@ -668,7 +668,7 @@ static void sculpt_gesture_lasso_px_cb(int x, int x_end, int y, void *user_data)
|
||||
int index = (y * lasso->width) + x;
|
||||
int index_end = (y * lasso->width) + x_end;
|
||||
do {
|
||||
BLI_BITMAP_ENABLE(lasso->mask_px, index);
|
||||
lasso->mask_px[index].set();
|
||||
} while (++index != index_end);
|
||||
}
|
||||
|
||||
@ -692,7 +692,7 @@ static SculptGestureContext *sculpt_gesture_init_from_lasso(bContext *C, wmOpera
|
||||
const int lasso_width = 1 + sgcontext->lasso.boundbox.xmax - sgcontext->lasso.boundbox.xmin;
|
||||
const int lasso_height = 1 + sgcontext->lasso.boundbox.ymax - sgcontext->lasso.boundbox.ymin;
|
||||
sgcontext->lasso.width = lasso_width;
|
||||
sgcontext->lasso.mask_px = BLI_BITMAP_NEW(lasso_width * lasso_height, __func__);
|
||||
sgcontext->lasso.mask_px.resize(lasso_width * lasso_height);
|
||||
|
||||
BLI_bitmap_draw_2d_poly_v2i_n(sgcontext->lasso.boundbox.xmin,
|
||||
sgcontext->lasso.boundbox.ymin,
|
||||
@ -847,7 +847,6 @@ static SculptGestureContext *sculpt_gesture_init_from_line(bContext *C, wmOperat
|
||||
|
||||
static void sculpt_gesture_context_free(SculptGestureContext *sgcontext)
|
||||
{
|
||||
MEM_SAFE_FREE(sgcontext->lasso.mask_px);
|
||||
MEM_SAFE_FREE(sgcontext->gesture_points);
|
||||
MEM_SAFE_FREE(sgcontext->operation);
|
||||
MEM_delete(sgcontext);
|
||||
@ -964,7 +963,7 @@ static bool sculpt_gesture_is_effected_lasso(SculptGestureContext *sgcontext, co
|
||||
scr_co_s[0] -= lasso->boundbox.xmin;
|
||||
scr_co_s[1] -= lasso->boundbox.ymin;
|
||||
|
||||
return BLI_BITMAP_TEST_BOOL(lasso->mask_px, scr_co_s[1] * lasso->width + scr_co_s[0]);
|
||||
return lasso->mask_px[scr_co_s[1] * lasso->width + scr_co_s[0]].test();
|
||||
}
|
||||
|
||||
static bool sculpt_gesture_is_effected(SculptGestureContext *sgcontext,
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_dial_2d.h"
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_gsqueue.h"
|
||||
#include "BLI_math_geom.h"
|
||||
#include "BLI_math_matrix.h"
|
||||
#include "BLI_set.hh"
|
||||
@ -31,6 +30,7 @@
|
||||
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_customdata_types.h"
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_node_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
@ -40,6 +40,7 @@
|
||||
#include "BKE_ccg.h"
|
||||
#include "BKE_colortools.hh"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_lib_id.h"
|
||||
@ -1010,22 +1011,19 @@ namespace blender::ed::sculpt_paint::flood_fill {
|
||||
|
||||
void init_fill(SculptSession *ss, SculptFloodFill *flood)
|
||||
{
|
||||
int vertex_count = SCULPT_vertex_count_get(ss);
|
||||
SCULPT_vertex_random_access_ensure(ss);
|
||||
|
||||
flood->queue = BLI_gsqueue_new(sizeof(intptr_t));
|
||||
flood->visited_verts = BLI_BITMAP_NEW(vertex_count, "visited verts");
|
||||
flood->visited_verts.resize(SCULPT_vertex_count_get(ss));
|
||||
}
|
||||
|
||||
void add_initial(SculptFloodFill *flood, PBVHVertRef vertex)
|
||||
{
|
||||
BLI_gsqueue_push(flood->queue, &vertex);
|
||||
flood->queue.push(vertex);
|
||||
}
|
||||
|
||||
void add_and_skip_initial(SculptFloodFill *flood, PBVHVertRef vertex)
|
||||
{
|
||||
BLI_gsqueue_push(flood->queue, &vertex);
|
||||
BLI_BITMAP_ENABLE(flood->visited_verts, vertex.i);
|
||||
flood->queue.push(vertex);
|
||||
flood->visited_verts[vertex.i].set(vertex.i);
|
||||
}
|
||||
|
||||
void add_initial_with_symmetry(Sculpt *sd,
|
||||
@ -1094,16 +1092,16 @@ void execute(SculptSession *ss,
|
||||
void *userdata),
|
||||
void *userdata)
|
||||
{
|
||||
while (!BLI_gsqueue_is_empty(flood->queue)) {
|
||||
PBVHVertRef from_v;
|
||||
while (!flood->queue.empty()) {
|
||||
PBVHVertRef from_v = flood->queue.front();
|
||||
flood->queue.pop();
|
||||
|
||||
BLI_gsqueue_pop(flood->queue, &from_v);
|
||||
SculptVertexNeighborIter ni;
|
||||
SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) {
|
||||
const PBVHVertRef to_v = ni.vertex;
|
||||
int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v);
|
||||
|
||||
if (BLI_BITMAP_TEST(flood->visited_verts, to_v_i)) {
|
||||
if (flood->visited_verts[to_v_i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1111,23 +1109,16 @@ void execute(SculptSession *ss,
|
||||
continue;
|
||||
}
|
||||
|
||||
BLI_BITMAP_ENABLE(flood->visited_verts, BKE_pbvh_vertex_to_index(ss->pbvh, to_v));
|
||||
flood->visited_verts[BKE_pbvh_vertex_to_index(ss->pbvh, to_v)].set();
|
||||
|
||||
if (func(ss, from_v, to_v, ni.is_duplicate, userdata)) {
|
||||
BLI_gsqueue_push(flood->queue, &to_v);
|
||||
flood->queue.push(to_v);
|
||||
}
|
||||
}
|
||||
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
|
||||
}
|
||||
}
|
||||
|
||||
void free_fill(SculptFloodFill *flood)
|
||||
{
|
||||
MEM_SAFE_FREE(flood->visited_verts);
|
||||
BLI_gsqueue_free(flood->queue);
|
||||
flood->queue = nullptr;
|
||||
}
|
||||
|
||||
} // namespace blender::ed::sculpt_paint::flood_fill
|
||||
|
||||
/** \} */
|
||||
@ -2965,6 +2956,39 @@ void SCULPT_flip_quat_by_symm_area(float quat[4],
|
||||
}
|
||||
}
|
||||
|
||||
bool SCULPT_tool_needs_all_pbvh_nodes(const Brush *brush)
|
||||
{
|
||||
if (brush->sculpt_tool == SCULPT_TOOL_ELASTIC_DEFORM) {
|
||||
/* Elastic deformations in any brush need all nodes to avoid artifacts as the effect
|
||||
* of the Kelvinlet is not constrained by the radius. */
|
||||
return true;
|
||||
}
|
||||
|
||||
if (brush->sculpt_tool == SCULPT_TOOL_POSE) {
|
||||
/* Pose needs all nodes because it applies all symmetry iterations at the same time
|
||||
* and the IK chain can grow to any area of the model. */
|
||||
/* TODO: This can be optimized by filtering the nodes after calculating the chain. */
|
||||
return true;
|
||||
}
|
||||
|
||||
if (brush->sculpt_tool == SCULPT_TOOL_BOUNDARY) {
|
||||
/* Boundary needs all nodes because it is not possible to know where the boundary
|
||||
* deformation is going to be propagated before calculating it. */
|
||||
/* TODO: after calculating the boundary info in the first iteration, it should be
|
||||
* possible to get the nodes that have vertices included in any boundary deformation
|
||||
* and cache them. */
|
||||
return true;
|
||||
}
|
||||
|
||||
if (brush->sculpt_tool == SCULPT_TOOL_SNAKE_HOOK &&
|
||||
brush->snake_hook_deform_type == BRUSH_SNAKE_HOOK_DEFORM_ELASTIC)
|
||||
{
|
||||
/* Snake hook in elastic deform type has same requirements as the elastic deform tool. */
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SCULPT_calc_brush_plane(
|
||||
Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float r_area_no[3], float r_area_co[3])
|
||||
{
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "BLI_math_base_safe.h"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_set.hh"
|
||||
#include "BLI_task.h"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "DNA_brush_types.h"
|
||||
@ -653,7 +652,6 @@ static void SCULPT_topology_automasking_init(Sculpt *sd, Object *ob)
|
||||
|
||||
copy_v3_v3(fdata.location, SCULPT_active_vertex_co_get(ss));
|
||||
flood_fill::execute(ss, &flood, automask_floodfill_cb, &fdata);
|
||||
flood_fill::free_fill(&flood);
|
||||
}
|
||||
|
||||
static void sculpt_face_sets_automasking_init(Sculpt *sd, Object *ob)
|
||||
|
@ -101,7 +101,6 @@ static PBVHVertRef sculpt_boundary_get_closest_boundary_vertex(SculptSession *ss
|
||||
fdata.floodfill_steps = MEM_cnew_array<int>(SCULPT_vertex_count_get(ss), __func__);
|
||||
|
||||
flood_fill::execute(ss, &flood, boundary_initial_vertex_floodfill_cb, &fdata);
|
||||
flood_fill::free_fill(&flood);
|
||||
|
||||
MEM_freeN(fdata.floodfill_steps);
|
||||
return fdata.boundary_initial_vertex;
|
||||
@ -264,7 +263,6 @@ static void sculpt_boundary_indices_init(SculptSession *ss,
|
||||
fdata.last_visited_vertex = {BOUNDARY_VERTEX_NONE};
|
||||
|
||||
flood_fill::execute(ss, &flood, boundary_floodfill_cb, &fdata);
|
||||
flood_fill::free_fill(&flood);
|
||||
|
||||
/* Check if the boundary loops into itself and add the extra preview edge to close the loop. */
|
||||
if (fdata.last_visited_vertex.i != BOUNDARY_VERTEX_NONE &&
|
||||
@ -308,12 +306,9 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
|
||||
boundary->edit_info[i].propagation_steps_num = BOUNDARY_STEPS_NONE;
|
||||
}
|
||||
|
||||
GSQueue *current_iteration = BLI_gsqueue_new(sizeof(PBVHVertRef));
|
||||
GSQueue *next_iteration = BLI_gsqueue_new(sizeof(PBVHVertRef));
|
||||
std::queue<PBVHVertRef> current_iteration;
|
||||
std::queue<PBVHVertRef> next_iteration;
|
||||
|
||||
/* Initialized the first iteration with the vertices already in the boundary. This is propagation
|
||||
* step 0. */
|
||||
BLI_bitmap *visited_verts = BLI_BITMAP_NEW(SCULPT_vertex_count_get(ss), "visited_verts");
|
||||
for (int i = 0; i < boundary->verts_num; i++) {
|
||||
int index = BKE_pbvh_vertex_to_index(ss->pbvh, boundary->verts[i]);
|
||||
|
||||
@ -334,7 +329,7 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
|
||||
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis);
|
||||
}
|
||||
|
||||
BLI_gsqueue_push(current_iteration, &boundary->verts[i]);
|
||||
current_iteration.push(boundary->verts[i]);
|
||||
}
|
||||
|
||||
int propagation_steps_num = 0;
|
||||
@ -343,14 +338,14 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
|
||||
while (true) {
|
||||
/* Stop adding steps to edit info. This happens when a steps is further away from the boundary
|
||||
* than the brush radius or when the entire mesh was already processed. */
|
||||
if (accum_distance > radius || BLI_gsqueue_is_empty(current_iteration)) {
|
||||
if (accum_distance > radius || current_iteration.empty()) {
|
||||
boundary->max_propagation_steps = propagation_steps_num;
|
||||
break;
|
||||
}
|
||||
|
||||
while (!BLI_gsqueue_is_empty(current_iteration)) {
|
||||
PBVHVertRef from_v;
|
||||
BLI_gsqueue_pop(current_iteration, &from_v);
|
||||
while (!current_iteration.empty()) {
|
||||
PBVHVertRef from_v = current_iteration.front();
|
||||
current_iteration.pop();
|
||||
|
||||
int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v);
|
||||
|
||||
@ -364,8 +359,6 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
|
||||
boundary->edit_info[ni.index].original_vertex_i =
|
||||
boundary->edit_info[from_v_i].original_vertex_i;
|
||||
|
||||
BLI_BITMAP_ENABLE(visited_verts, ni.index);
|
||||
|
||||
if (ni.is_duplicate) {
|
||||
/* Grids duplicates handling. */
|
||||
boundary->edit_info[ni.index].propagation_steps_num =
|
||||
@ -375,7 +368,7 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
|
||||
boundary->edit_info[ni.index].propagation_steps_num =
|
||||
boundary->edit_info[from_v_i].propagation_steps_num + 1;
|
||||
|
||||
BLI_gsqueue_push(next_iteration, &ni.vertex);
|
||||
next_iteration.push(ni.vertex);
|
||||
|
||||
/* When copying the data to the neighbor for the next iteration, it has to be copied to
|
||||
* all its duplicates too. This is because it is not possible to know if the updated
|
||||
@ -410,19 +403,14 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
|
||||
}
|
||||
|
||||
/* Copy the new vertices to the queue to be processed in the next iteration. */
|
||||
while (!BLI_gsqueue_is_empty(next_iteration)) {
|
||||
PBVHVertRef next_v;
|
||||
BLI_gsqueue_pop(next_iteration, &next_v);
|
||||
BLI_gsqueue_push(current_iteration, &next_v);
|
||||
while (!next_iteration.empty()) {
|
||||
PBVHVertRef next_v = next_iteration.front();
|
||||
next_iteration.pop();
|
||||
current_iteration.push(next_v);
|
||||
}
|
||||
|
||||
propagation_steps_num++;
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(visited_verts);
|
||||
|
||||
BLI_gsqueue_free(current_iteration);
|
||||
BLI_gsqueue_free(next_iteration);
|
||||
}
|
||||
|
||||
/* This functions assigns a falloff factor to each one of the SculptBoundaryEditInfo structs based
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_gsqueue.h"
|
||||
#include "BLI_math_geom.h"
|
||||
#include "BLI_math_matrix.h"
|
||||
#include "BLI_math_vector.h"
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_gsqueue.h"
|
||||
#include "BLI_math_matrix.h"
|
||||
#include "BLI_math_rotation.h"
|
||||
#include "BLI_task.h"
|
||||
@ -106,6 +105,17 @@ Vector<PBVHNode *> brush_affected_nodes_gather(SculptSession *ss, Brush *brush)
|
||||
return Vector<PBVHNode *>();
|
||||
}
|
||||
|
||||
bool is_cloth_deform_brush(const Brush *brush)
|
||||
{
|
||||
return (brush->sculpt_tool == SCULPT_TOOL_CLOTH && ELEM(brush->cloth_deform_type,
|
||||
BRUSH_CLOTH_DEFORM_GRAB,
|
||||
BRUSH_CLOTH_DEFORM_SNAKE_HOOK)) ||
|
||||
/* All brushes that are not the cloth brush deform the simulation using softbody
|
||||
* constraints instead of applying forces. */
|
||||
(brush->sculpt_tool != SCULPT_TOOL_CLOTH &&
|
||||
brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM);
|
||||
}
|
||||
|
||||
static float cloth_brush_simulation_falloff_get(const Brush *brush,
|
||||
const float radius,
|
||||
const float location[3],
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
|
||||
#include "BKE_context.hh"
|
||||
|
@ -503,7 +503,6 @@ static float *sculpt_expand_topology_falloff_create(Sculpt *sd, Object *ob, cons
|
||||
fdata.dists = dists;
|
||||
|
||||
flood_fill::execute(ss, &flood, expand_topology_floodfill_cb, &fdata);
|
||||
flood_fill::free_fill(&flood);
|
||||
|
||||
return dists;
|
||||
}
|
||||
@ -564,7 +563,6 @@ static float *sculpt_expand_normal_falloff_create(Sculpt *sd,
|
||||
SCULPT_vertex_normal_get(ss, v, fdata.original_normal);
|
||||
|
||||
flood_fill::execute(ss, &flood, mask_expand_normal_floodfill_cb, &fdata);
|
||||
flood_fill::free_fill(&flood);
|
||||
|
||||
for (int repeat = 0; repeat < blur_steps; repeat++) {
|
||||
for (int i = 0; i < totvert; i++) {
|
||||
@ -637,7 +635,7 @@ static float *sculpt_expand_boundary_topology_falloff_create(Object *ob, const P
|
||||
const int totvert = SCULPT_vertex_count_get(ss);
|
||||
float *dists = static_cast<float *>(MEM_calloc_arrayN(totvert, sizeof(float), __func__));
|
||||
BitVector<> visited_verts(totvert);
|
||||
GSQueue *queue = BLI_gsqueue_new(sizeof(PBVHVertRef));
|
||||
std::queue<PBVHVertRef> queue;
|
||||
|
||||
/* Search and initialize a boundary per symmetry pass, then mark those vertices as visited. */
|
||||
const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
|
||||
@ -655,22 +653,22 @@ static float *sculpt_expand_boundary_topology_falloff_create(Object *ob, const P
|
||||
}
|
||||
|
||||
for (int i = 0; i < boundary->verts_num; i++) {
|
||||
BLI_gsqueue_push(queue, &boundary->verts[i]);
|
||||
queue.push(boundary->verts[i]);
|
||||
visited_verts[BKE_pbvh_vertex_to_index(ss->pbvh, boundary->verts[i])].set();
|
||||
}
|
||||
boundary::data_free(boundary);
|
||||
}
|
||||
|
||||
/* If there are no boundaries, return a falloff with all values set to 0. */
|
||||
if (BLI_gsqueue_is_empty(queue)) {
|
||||
if (queue.empty()) {
|
||||
return dists;
|
||||
}
|
||||
|
||||
/* Propagate the values from the boundaries to the rest of the mesh. */
|
||||
while (!BLI_gsqueue_is_empty(queue)) {
|
||||
PBVHVertRef v_next;
|
||||
while (!queue.empty()) {
|
||||
PBVHVertRef v_next = queue.front();
|
||||
queue.pop();
|
||||
|
||||
BLI_gsqueue_pop(queue, &v_next);
|
||||
int v_next_i = BKE_pbvh_vertex_to_index(ss->pbvh, v_next);
|
||||
|
||||
SculptVertexNeighborIter ni;
|
||||
@ -680,12 +678,11 @@ static float *sculpt_expand_boundary_topology_falloff_create(Object *ob, const P
|
||||
}
|
||||
dists[ni.index] = dists[v_next_i] + 1.0f;
|
||||
visited_verts[ni.index].set();
|
||||
BLI_gsqueue_push(queue, &ni.vertex);
|
||||
queue.push(ni.vertex);
|
||||
}
|
||||
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
|
||||
}
|
||||
|
||||
BLI_gsqueue_free(queue);
|
||||
return dists;
|
||||
}
|
||||
|
||||
@ -709,7 +706,7 @@ static float *sculpt_expand_diagonals_falloff_create(Object *ob, const PBVHVertR
|
||||
|
||||
/* Search and mask as visited the initial vertices using the enabled symmetry passes. */
|
||||
BitVector<> visited_verts(totvert);
|
||||
GSQueue *queue = BLI_gsqueue_new(sizeof(PBVHVertRef));
|
||||
std::queue<PBVHVertRef> queue;
|
||||
const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
|
||||
for (char symm_it = 0; symm_it <= symm; symm_it++) {
|
||||
if (!SCULPT_is_symmetry_iteration_valid(symm_it, symm)) {
|
||||
@ -720,18 +717,18 @@ static float *sculpt_expand_diagonals_falloff_create(Object *ob, const PBVHVertR
|
||||
ob, symm_it, v);
|
||||
int symm_vertex_i = BKE_pbvh_vertex_to_index(ss->pbvh, symm_vertex);
|
||||
|
||||
BLI_gsqueue_push(queue, &symm_vertex);
|
||||
queue.push(symm_vertex);
|
||||
visited_verts[symm_vertex_i].set();
|
||||
}
|
||||
|
||||
if (BLI_gsqueue_is_empty(queue)) {
|
||||
if (queue.empty()) {
|
||||
return dists;
|
||||
}
|
||||
|
||||
/* Propagate the falloff increasing the value by 1 each time a new vertex is visited. */
|
||||
while (!BLI_gsqueue_is_empty(queue)) {
|
||||
PBVHVertRef v_next;
|
||||
BLI_gsqueue_pop(queue, &v_next);
|
||||
while (!queue.empty()) {
|
||||
PBVHVertRef v_next = queue.front();
|
||||
queue.pop();
|
||||
|
||||
int v_next_i = BKE_pbvh_vertex_to_index(ss->pbvh, v_next);
|
||||
|
||||
@ -743,12 +740,11 @@ static float *sculpt_expand_diagonals_falloff_create(Object *ob, const PBVHVertR
|
||||
}
|
||||
dists[neighbor_v.i] = dists[v_next_i] + 1.0f;
|
||||
visited_verts[neighbor_v.i].set();
|
||||
BLI_gsqueue_push(queue, &neighbor_v);
|
||||
queue.push(neighbor_v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BLI_gsqueue_free(queue);
|
||||
return dists;
|
||||
}
|
||||
|
||||
@ -927,7 +923,6 @@ static void sculpt_expand_topology_from_state_boundary(Object *ob,
|
||||
ExpandFloodFillData fdata;
|
||||
fdata.dists = dists;
|
||||
flood_fill::execute(ss, &flood, expand_topology_floodfill_cb, &fdata);
|
||||
flood_fill::free_fill(&flood);
|
||||
|
||||
expand_cache->vert_falloff = dists;
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ static float *geodesic_mesh_create(Object *ob, GSet *initial_verts, const float
|
||||
const VArraySpan<bool> hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
|
||||
|
||||
float *dists = static_cast<float *>(MEM_malloc_arrayN(totvert, sizeof(float), __func__));
|
||||
BLI_bitmap *edge_tag = BLI_BITMAP_NEW(totedge, "edge tag");
|
||||
BitVector<> edge_tag(totedge);
|
||||
|
||||
if (ss->epmap.is_empty()) {
|
||||
ss->epmap = bke::mesh::build_edge_to_face_map(
|
||||
@ -125,13 +125,13 @@ static float *geodesic_mesh_create(Object *ob, GSet *initial_verts, const float
|
||||
|
||||
/* Masks vertices that are further than limit radius from an initial vertex. As there is no need
|
||||
* to define a distance to them the algorithm can stop earlier by skipping them. */
|
||||
BLI_bitmap *affected_vertex = BLI_BITMAP_NEW(totvert, "affected vertex");
|
||||
BitVector<> affected_vert(totvert);
|
||||
GSetIterator gs_iter;
|
||||
|
||||
if (limit_radius == FLT_MAX) {
|
||||
/* In this case, no need to loop through all initial vertices to check distances as they are
|
||||
* all going to be affected. */
|
||||
BLI_bitmap_set_all(affected_vertex, true, totvert);
|
||||
affected_vert.fill(true);
|
||||
}
|
||||
else {
|
||||
/* This is an O(n^2) loop used to limit the geodesic distance calculation to a radius. When
|
||||
@ -142,7 +142,7 @@ static float *geodesic_mesh_create(Object *ob, GSet *initial_verts, const float
|
||||
const float *v_co = vert_positions[v];
|
||||
for (int i = 0; i < totvert; i++) {
|
||||
if (len_squared_v3v3(v_co, vert_positions[i]) <= limit_radius_sq) {
|
||||
BLI_BITMAP_ENABLE(affected_vertex, i);
|
||||
affected_vert[i].set();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -152,7 +152,7 @@ static float *geodesic_mesh_create(Object *ob, GSet *initial_verts, const float
|
||||
for (int i = 0; i < totedge; i++) {
|
||||
const int v1 = edges[i][0];
|
||||
const int v2 = edges[i][1];
|
||||
if (!BLI_BITMAP_TEST(affected_vertex, v1) && !BLI_BITMAP_TEST(affected_vertex, v2)) {
|
||||
if (!affected_vert[v1] && !affected_vert[v2]) {
|
||||
continue;
|
||||
}
|
||||
if (dists[v1] != FLT_MAX || dists[v2] != FLT_MAX) {
|
||||
@ -197,12 +197,11 @@ static float *geodesic_mesh_create(Object *ob, GSet *initial_verts, const float
|
||||
ev_other = edges[e_other][0];
|
||||
}
|
||||
|
||||
if (e_other != e && !BLI_BITMAP_TEST(edge_tag, e_other) &&
|
||||
if (e_other != e && !edge_tag[e_other] &&
|
||||
(ss->epmap[e_other].is_empty() || dists[ev_other] != FLT_MAX))
|
||||
{
|
||||
if (BLI_BITMAP_TEST(affected_vertex, v_other) ||
|
||||
BLI_BITMAP_TEST(affected_vertex, ev_other)) {
|
||||
BLI_BITMAP_ENABLE(edge_tag, e_other);
|
||||
if (affected_vert[v_other] || affected_vert[ev_other]) {
|
||||
edge_tag[e_other].set();
|
||||
BLI_LINKSTACK_PUSH(queue_next, POINTER_FROM_INT(e_other));
|
||||
}
|
||||
}
|
||||
@ -215,7 +214,7 @@ static float *geodesic_mesh_create(Object *ob, GSet *initial_verts, const float
|
||||
|
||||
for (LinkNode *lnk = queue_next; lnk; lnk = lnk->next) {
|
||||
const int e = POINTER_AS_INT(lnk->link);
|
||||
BLI_BITMAP_DISABLE(edge_tag, e);
|
||||
edge_tag[e].reset();
|
||||
}
|
||||
|
||||
BLI_LINKSTACK_SWAP(queue, queue_next);
|
||||
@ -224,8 +223,6 @@ static float *geodesic_mesh_create(Object *ob, GSet *initial_verts, const float
|
||||
|
||||
BLI_LINKSTACK_FREE(queue);
|
||||
BLI_LINKSTACK_FREE(queue_next);
|
||||
MEM_SAFE_FREE(edge_tag);
|
||||
MEM_SAFE_FREE(affected_vertex);
|
||||
|
||||
return dists;
|
||||
}
|
||||
|
@ -8,37 +8,22 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_listBase.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_vec_types.h"
|
||||
#include <queue>
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_paint.hh"
|
||||
#include "BKE_pbvh_api.hh"
|
||||
|
||||
#include "BLI_array.hh"
|
||||
#include "BLI_bit_vector.hh"
|
||||
#include "BLI_bitmap.h"
|
||||
#include "BLI_compiler_attrs.h"
|
||||
#include "BLI_compiler_compat.h"
|
||||
#include "BLI_generic_array.hh"
|
||||
#include "BLI_gsqueue.h"
|
||||
#include "BLI_implicit_sharing.hh"
|
||||
#include "BLI_math_matrix_types.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_set.hh"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_threads.h"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "ED_view3d.hh"
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace blender::ed::sculpt_paint {
|
||||
namespace auto_mask {
|
||||
struct NodeData;
|
||||
@ -134,8 +119,8 @@ struct SculptOrigFaceData {
|
||||
|
||||
/* Flood Fill. */
|
||||
struct SculptFloodFill {
|
||||
GSQueue *queue;
|
||||
BLI_bitmap *visited_verts;
|
||||
std::queue<PBVHVertRef> queue;
|
||||
blender::BitVector<> visited_verts;
|
||||
};
|
||||
|
||||
enum eBoundaryAutomaskMode {
|
||||
@ -219,7 +204,7 @@ struct Node {
|
||||
bool applied;
|
||||
|
||||
/* shape keys */
|
||||
char shapeName[sizeof(KeyBlock::name)];
|
||||
char shapeName[MAX_NAME]; /* sizeof(KeyBlock::name). */
|
||||
|
||||
/* Geometry modification operations.
|
||||
*
|
||||
@ -1044,38 +1029,7 @@ void SCULPT_orig_vert_data_unode_init(SculptOrigVertData *data,
|
||||
/** \name Brush Utilities.
|
||||
* \{ */
|
||||
|
||||
BLI_INLINE bool SCULPT_tool_needs_all_pbvh_nodes(const Brush *brush)
|
||||
{
|
||||
if (brush->sculpt_tool == SCULPT_TOOL_ELASTIC_DEFORM) {
|
||||
/* Elastic deformations in any brush need all nodes to avoid artifacts as the effect
|
||||
* of the Kelvinlet is not constrained by the radius. */
|
||||
return true;
|
||||
}
|
||||
|
||||
if (brush->sculpt_tool == SCULPT_TOOL_POSE) {
|
||||
/* Pose needs all nodes because it applies all symmetry iterations at the same time
|
||||
* and the IK chain can grow to any area of the model. */
|
||||
/* TODO: This can be optimized by filtering the nodes after calculating the chain. */
|
||||
return true;
|
||||
}
|
||||
|
||||
if (brush->sculpt_tool == SCULPT_TOOL_BOUNDARY) {
|
||||
/* Boundary needs all nodes because it is not possible to know where the boundary
|
||||
* deformation is going to be propagated before calculating it. */
|
||||
/* TODO: after calculating the boundary info in the first iteration, it should be
|
||||
* possible to get the nodes that have vertices included in any boundary deformation
|
||||
* and cache them. */
|
||||
return true;
|
||||
}
|
||||
|
||||
if (brush->sculpt_tool == SCULPT_TOOL_SNAKE_HOOK &&
|
||||
brush->snake_hook_deform_type == BRUSH_SNAKE_HOOK_DEFORM_ELASTIC)
|
||||
{
|
||||
/* Snake hook in elastic deform type has same requirements as the elastic deform tool. */
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool SCULPT_tool_needs_all_pbvh_nodes(const Brush *brush);
|
||||
|
||||
void SCULPT_calc_brush_plane(Sculpt *sd,
|
||||
Object *ob,
|
||||
@ -1249,7 +1203,6 @@ void execute(SculptSession *ss,
|
||||
bool is_duplicate,
|
||||
void *userdata),
|
||||
void *userdata);
|
||||
void free_fill(SculptFloodFill *flood);
|
||||
|
||||
}
|
||||
|
||||
@ -1462,16 +1415,7 @@ void plane_falloff_preview_draw(uint gpuattr,
|
||||
|
||||
blender::Vector<PBVHNode *> brush_affected_nodes_gather(SculptSession *ss, Brush *brush);
|
||||
|
||||
BLI_INLINE bool is_cloth_deform_brush(const Brush *brush)
|
||||
{
|
||||
return (brush->sculpt_tool == SCULPT_TOOL_CLOTH && ELEM(brush->cloth_deform_type,
|
||||
BRUSH_CLOTH_DEFORM_GRAB,
|
||||
BRUSH_CLOTH_DEFORM_SNAKE_HOOK)) ||
|
||||
/* All brushes that are not the cloth brush deform the simulation using softbody
|
||||
* constraints instead of applying forces. */
|
||||
(brush->sculpt_tool != SCULPT_TOOL_CLOTH &&
|
||||
brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM);
|
||||
}
|
||||
bool is_cloth_deform_brush(const Brush *brush);
|
||||
|
||||
}
|
||||
|
||||
@ -1882,6 +1826,23 @@ int SCULPT_vertex_island_get(const SculptSession *ss, PBVHVertRef vertex);
|
||||
|
||||
/** \} */
|
||||
|
||||
/* Make SCULPT_ alias to a few blenkernel sculpt methods. */
|
||||
inline void *SCULPT_vertex_attr_get(const PBVHVertRef vertex, const SculptAttribute *attr)
|
||||
{
|
||||
if (attr->data) {
|
||||
char *p = (char *)attr->data;
|
||||
int idx = (int)vertex.i;
|
||||
|
||||
#define SCULPT_vertex_attr_get BKE_sculpt_vertex_attr_get
|
||||
if (attr->data_for_bmesh) {
|
||||
BMElem *v = (BMElem *)vertex.i;
|
||||
idx = v->head.index;
|
||||
}
|
||||
|
||||
return p + attr->elem_size * (int)idx;
|
||||
}
|
||||
else {
|
||||
BMElem *v = (BMElem *)vertex.i;
|
||||
return BM_ELEM_CD_GET_VOID_P(v, attr->bmesh_cd_offset);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_gsqueue.h"
|
||||
#include "BLI_math_matrix.hh"
|
||||
#include "BLI_math_vector.hh"
|
||||
#include "BLI_task.h"
|
||||
@ -586,7 +585,7 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float
|
||||
float brush_co[3];
|
||||
copy_v3_v3(brush_co, SCULPT_active_vertex_co_get(ss));
|
||||
|
||||
BLI_bitmap *visited_verts = BLI_BITMAP_NEW(SCULPT_vertex_count_get(ss), "visited_verts");
|
||||
blender::BitVector<> visited_verts(SCULPT_vertex_count_get(ss));
|
||||
|
||||
/* Assuming an average of 6 edges per vertex in a triangulated mesh. */
|
||||
const int max_preview_verts = SCULPT_vertex_count_get(ss) * 3 * 2;
|
||||
@ -595,14 +594,13 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float
|
||||
ss->preview_vert_list = MEM_cnew_array<PBVHVertRef>(max_preview_verts, __func__);
|
||||
}
|
||||
|
||||
GSQueue *non_visited_verts = BLI_gsqueue_new(sizeof(PBVHVertRef));
|
||||
PBVHVertRef active_v = SCULPT_active_vertex_get(ss);
|
||||
BLI_gsqueue_push(non_visited_verts, &active_v);
|
||||
std::queue<PBVHVertRef> non_visited_verts;
|
||||
non_visited_verts.push(SCULPT_active_vertex_get(ss));
|
||||
|
||||
while (!BLI_gsqueue_is_empty(non_visited_verts)) {
|
||||
PBVHVertRef from_v;
|
||||
while (!non_visited_verts.empty()) {
|
||||
PBVHVertRef from_v = non_visited_verts.front();
|
||||
non_visited_verts.pop();
|
||||
|
||||
BLI_gsqueue_pop(non_visited_verts, &from_v);
|
||||
SculptVertexNeighborIter ni;
|
||||
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) {
|
||||
if (totpoints + (ni.size * 2) < max_preview_verts) {
|
||||
@ -612,23 +610,19 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float
|
||||
totpoints++;
|
||||
ss->preview_vert_list[totpoints] = to_v;
|
||||
totpoints++;
|
||||
if (BLI_BITMAP_TEST(visited_verts, to_v_i)) {
|
||||
if (visited_verts[to_v_i]) {
|
||||
continue;
|
||||
}
|
||||
BLI_BITMAP_ENABLE(visited_verts, to_v_i);
|
||||
visited_verts[to_v_i].set();
|
||||
const float *co = SCULPT_vertex_co_for_grab_active_get(ss, to_v);
|
||||
if (len_squared_v3v3(brush_co, co) < radius * radius) {
|
||||
BLI_gsqueue_push(non_visited_verts, &to_v);
|
||||
non_visited_verts.push(to_v);
|
||||
}
|
||||
}
|
||||
}
|
||||
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
|
||||
}
|
||||
|
||||
BLI_gsqueue_free(non_visited_verts);
|
||||
|
||||
MEM_freeN(visited_verts);
|
||||
|
||||
ss->preview_vert_count = totpoints;
|
||||
}
|
||||
|
||||
@ -830,7 +824,6 @@ static void sculpt_mask_by_color_contiguous(Object *object,
|
||||
copy_v3_v3(ffd.initial_color, color);
|
||||
|
||||
flood_fill::execute(ss, &flood, sculpt_mask_by_color_contiguous_floodfill, &ffd);
|
||||
flood_fill::free_fill(&flood);
|
||||
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(ss->pbvh, {});
|
||||
const SculptMaskWriteInfo mask_write = SCULPT_mask_get_for_write(ss);
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_brush_types.h"
|
||||
|
||||
#include "BLI_hash.h"
|
||||
#include "BLI_math_color_blend.h"
|
||||
#include "BLI_task.h"
|
||||
|
@ -5,6 +5,7 @@
|
||||
/* Paint a color made from hash of node pointer. */
|
||||
//#define DEBUG_PIXEL_NODES
|
||||
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_image_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
|
@ -361,7 +361,7 @@ struct PoseFloodFillData {
|
||||
GSet *visited_face_sets;
|
||||
|
||||
/* In face sets origin mode, each vertex can only be assigned to one face set. */
|
||||
BLI_bitmap *is_weighted;
|
||||
MutableBoundedBitSpan is_weighted;
|
||||
|
||||
bool is_first_iteration;
|
||||
|
||||
@ -435,7 +435,7 @@ static bool pose_face_sets_floodfill_cb(
|
||||
if (data->current_face_set == SCULPT_FACE_SET_NONE) {
|
||||
|
||||
data->pose_factor[index] = 1.0f;
|
||||
BLI_BITMAP_ENABLE(data->is_weighted, index);
|
||||
data->is_weighted[index].set();
|
||||
|
||||
if (sculpt_pose_brush_is_vertex_inside_brush_radius(
|
||||
co, data->pose_initial_co, data->radius, data->symm))
|
||||
@ -469,9 +469,9 @@ static bool pose_face_sets_floodfill_cb(
|
||||
return visit_next;
|
||||
}
|
||||
|
||||
if (!BLI_BITMAP_TEST(data->is_weighted, index)) {
|
||||
if (!data->is_weighted[index]) {
|
||||
data->pose_factor[index] = 1.0f;
|
||||
BLI_BITMAP_ENABLE(data->is_weighted, index);
|
||||
data->is_weighted[index].set();
|
||||
visit_next = true;
|
||||
}
|
||||
|
||||
@ -543,7 +543,6 @@ void calc_pose_data(Sculpt *sd,
|
||||
copy_v3_v3(fdata.pose_initial_co, initial_location);
|
||||
copy_v3_v3(fdata.fallback_floodfill_origin, initial_location);
|
||||
flood_fill::execute(ss, &flood, pose_topology_floodfill_cb, &fdata);
|
||||
flood_fill::free_fill(&flood);
|
||||
|
||||
if (fdata.tot_co > 0) {
|
||||
mul_v3_fl(fdata.pose_origin, 1.0f / float(fdata.tot_co));
|
||||
@ -728,7 +727,7 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets(
|
||||
|
||||
GSet *visited_face_sets = BLI_gset_int_new_ex("visited_face_sets", ik_chain->tot_segments);
|
||||
|
||||
BLI_bitmap *is_weighted = BLI_BITMAP_NEW(totvert, "weighted");
|
||||
BitVector<> is_weighted(totvert);
|
||||
|
||||
int current_face_set = SCULPT_FACE_SET_NONE;
|
||||
int prev_face_set = SCULPT_FACE_SET_NONE;
|
||||
@ -760,7 +759,6 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets(
|
||||
zero_v3(fdata.fallback_origin);
|
||||
copy_v3_v3(fdata.pose_initial_co, SCULPT_vertex_co_get(ss, current_vertex));
|
||||
flood_fill::execute(ss, &flood, pose_face_sets_floodfill_cb, &fdata);
|
||||
flood_fill::free_fill(&flood);
|
||||
|
||||
if (fdata.tot_co > 0) {
|
||||
mul_v3_fl(fdata.pose_origin, 1.0f / float(fdata.tot_co));
|
||||
@ -783,8 +781,6 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets(
|
||||
|
||||
pose_ik_chain_origin_heads_init(ik_chain, SCULPT_active_vertex_co_get(ss));
|
||||
|
||||
MEM_SAFE_FREE(is_weighted);
|
||||
|
||||
return ik_chain;
|
||||
}
|
||||
|
||||
@ -864,7 +860,6 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets_fk(
|
||||
fdata.masked_face_set_it = 0;
|
||||
fdata.visited_face_sets = BLI_gset_int_new_ex("visited_face_sets", 3);
|
||||
flood_fill::execute(ss, &flood, pose_face_sets_fk_find_masked_floodfill_cb, &fdata);
|
||||
flood_fill::free_fill(&flood);
|
||||
BLI_gset_free(fdata.visited_face_sets, nullptr);
|
||||
|
||||
int origin_count = 0;
|
||||
@ -920,7 +915,6 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets_fk(
|
||||
flood_fill::add_active(sd, ob, ss, &flood, radius);
|
||||
fdata.fk_weights = ik_chain->segments[0].weights;
|
||||
flood_fill::execute(ss, &flood, pose_face_sets_fk_set_weights_floodfill_cb, &fdata);
|
||||
flood_fill::free_fill(&flood);
|
||||
|
||||
pose_ik_chain_origin_heads_init(ik_chain, ik_chain->segments[0].head);
|
||||
return ik_chain;
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_task.h"
|
||||
|
||||
#include "BKE_brush.hh"
|
||||
#include "BKE_context.hh"
|
||||
|
@ -40,7 +40,7 @@
|
||||
#include "BLI_threads.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
@ -54,7 +54,6 @@
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_mesh_runtime.hh"
|
||||
#include "BKE_multires.hh"
|
||||
#include "BKE_object.hh"
|
||||
#include "BKE_paint.hh"
|
||||
@ -1221,14 +1220,14 @@ static Node *alloc_node(Object *ob, PBVHNode *node, Type type)
|
||||
}
|
||||
else {
|
||||
unode->vert_hidden.resize(unode->vert_indices.size());
|
||||
usculpt->undo_size += BLI_BITMAP_SIZE(unode->vert_indices.size());
|
||||
usculpt->undo_size += unode->vert_hidden.size() / 8;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case Type::HideFace: {
|
||||
unode->face_hidden.resize(unode->face_indices.size());
|
||||
usculpt->undo_size += BLI_BITMAP_SIZE(unode->face_indices.size());
|
||||
usculpt->undo_size += unode->face_hidden.size() / 8;
|
||||
break;
|
||||
}
|
||||
case Type::Mask: {
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_object.hh"
|
||||
|
@ -32,7 +32,6 @@
|
||||
|
||||
#include "render_types.h"
|
||||
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_mesh.h"
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "BLI_listbase.h"
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_geometry_fields.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_attribute_math.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_mesh_mapping.hh"
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_material.h"
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "BLI_vector_set.hh"
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_mesh_runtime.hh"
|
||||
|
@ -68,17 +68,24 @@ typedef struct CustomDataExternal {
|
||||
} CustomDataExternal;
|
||||
|
||||
/**
|
||||
* Structure which stores custom element data associated with mesh elements
|
||||
* (vertices, edges or faces). The custom data is organized into a series of
|
||||
* layers, each with a data type (e.g. MTFace, MDeformVert, etc.).
|
||||
* #CustomData stores an arbitrary number of typed data "layers" for multiple elements.
|
||||
* The layers are typically geometry attributes, and the elements are typically geometry
|
||||
* elements like vertices, edges, or curves.
|
||||
*
|
||||
* Each layer has a type, often with certain semantics beyond the type of the raw data. However,
|
||||
* a subset of the layer types are exposed as attributes and accessed with a higher level API
|
||||
* built around #AttributeAccessor.
|
||||
*
|
||||
* For #BMesh, #CustomData is adapted to store the data from all layers in a single "block" which
|
||||
* is allocated for each element. Each layer's data is stored at a certain offset into every
|
||||
* block's data.
|
||||
*/
|
||||
typedef struct CustomData {
|
||||
/** CustomDataLayers, ordered by type. */
|
||||
/** Layers ordered by type. */
|
||||
CustomDataLayer *layers;
|
||||
/**
|
||||
* runtime only! - maps types to indices of first layer of that type,
|
||||
* MUST be >= CD_NUMTYPES, but we can't use a define here.
|
||||
* Correct size is ensured in CustomData_update_typemap assert().
|
||||
* Runtime only map from types to indices of first layer of that type,
|
||||
* Correct size of #CD_NUMTYPES is ensured by CustomData_update_typemap.
|
||||
*/
|
||||
int typemap[53];
|
||||
/** Number of layers, size of layers array. */
|
||||
@ -91,11 +98,11 @@ typedef struct CustomData {
|
||||
CustomDataExternal *external;
|
||||
} CustomData;
|
||||
|
||||
/** #CustomData.type */
|
||||
/** #CustomDataLayer.type */
|
||||
typedef enum eCustomDataType {
|
||||
/* Used by GLSL attributes in the cases when we need a delayed CD type
|
||||
* assignment (in the cases when we don't know in advance which layer
|
||||
* we are addressing).
|
||||
/**
|
||||
* Used by GPU attributes in the cases when we don't know which layer
|
||||
* we are addressing in advance.
|
||||
*/
|
||||
CD_AUTO_FROM_NAME = -1,
|
||||
|
||||
@ -103,7 +110,7 @@ typedef enum eCustomDataType {
|
||||
CD_MVERT = 0,
|
||||
CD_MSTICKY = 1,
|
||||
#endif
|
||||
CD_MDEFORMVERT = 2, /* Array of `MDeformVert`. */
|
||||
CD_MDEFORMVERT = 2, /* Array of #MDeformVert. */
|
||||
#ifdef DNA_DEPRECATED_ALLOW
|
||||
CD_MEDGE = 3,
|
||||
#endif
|
||||
@ -112,8 +119,8 @@ typedef enum eCustomDataType {
|
||||
CD_MCOL = 6,
|
||||
CD_ORIGINDEX = 7,
|
||||
/**
|
||||
* Used for derived face corner normals on mesh `ldata`, since currently they are not computed
|
||||
* lazily. Derived vertex and polygon normals are stored in #Mesh_Runtime.
|
||||
* Used as temporary storage for some areas that support interpolating custom normals.
|
||||
* Using a separate type from generic 3D vectors is a simple way of keeping values normalized.
|
||||
*/
|
||||
CD_NORMAL = 8,
|
||||
#ifdef DNA_DEPRECATED_ALLOW
|
||||
@ -183,6 +190,10 @@ typedef enum eCustomDataType {
|
||||
CD_NUMTYPES = 53,
|
||||
} eCustomDataType;
|
||||
|
||||
#ifdef __cplusplus
|
||||
using eCustomDataMask = uint64_t;
|
||||
#endif
|
||||
|
||||
/* Bits for eCustomDataMask */
|
||||
#define CD_MASK_MDEFORMVERT (1 << CD_MDEFORMVERT)
|
||||
#define CD_MASK_MFACE (1 << CD_MFACE)
|
||||
|
@ -60,7 +60,6 @@ set(SRC_BLENLIB
|
||||
../../blenlib/intern/hash_mm2a.c
|
||||
|
||||
# Dependencies of BLI_mempool.c when ASAN is enabled.
|
||||
../../blenlib/intern/gsqueue.c
|
||||
../../blenlib/intern/threads.cc
|
||||
../../blenlib/intern/time.c
|
||||
)
|
||||
|
@ -198,13 +198,15 @@ static float rna_CurvePoint_radius_get(PointerRNA *ptr)
|
||||
|
||||
static void rna_CurvePoint_radius_set(PointerRNA *ptr, float value)
|
||||
{
|
||||
using namespace blender;
|
||||
Curves *curves = rna_curves(ptr);
|
||||
float *radii = static_cast<float *>(CustomData_get_layer_named_for_write(
|
||||
&curves->geometry.point_data, CD_PROP_FLOAT, "radius", curves->geometry.point_num));
|
||||
if (radii == nullptr) {
|
||||
bke::MutableAttributeAccessor attributes = curves->geometry.wrap().attributes_for_write();
|
||||
bke::AttributeWriter radii = attributes.lookup_or_add_for_write<float>("radius",
|
||||
bke::AttrDomain::Point);
|
||||
if (!radii) {
|
||||
return;
|
||||
}
|
||||
radii[rna_CurvePoint_index_get_const(ptr)] = value;
|
||||
radii.varray.set(rna_CurvePoint_index_get_const(ptr), value);
|
||||
}
|
||||
|
||||
static char *rna_CurvePoint_path(const PointerRNA *ptr)
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_curveprofile.h"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_data_transfer.h"
|
||||
#include "BKE_dynamicpaint.h"
|
||||
#include "BKE_effect.h"
|
||||
|
@ -141,6 +141,7 @@ static const EnumPropertyItem part_fluid_type_items[] = {
|
||||
# include "BKE_boids.h"
|
||||
# include "BKE_cloth.hh"
|
||||
# include "BKE_context.hh"
|
||||
# include "BKE_customdata.hh"
|
||||
# include "BKE_deform.h"
|
||||
# include "BKE_effect.h"
|
||||
# include "BKE_material.h"
|
||||
|
@ -33,6 +33,8 @@
|
||||
#include "WM_api.hh"
|
||||
#include "WM_types.hh"
|
||||
|
||||
#include "bmesh.hh"
|
||||
|
||||
const EnumPropertyItem rna_enum_particle_edit_hair_brush_items[] = {
|
||||
{PE_BRUSH_COMB, "COMB", 0, "Comb", "Comb hairs"},
|
||||
{PE_BRUSH_SMOOTH, "SMOOTH", 0, "Smooth", "Smooth hairs"},
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_curve.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_displist.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_lib_query.h"
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "DEG_depsgraph_query.hh"
|
||||
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_modifier.hh"
|
||||
#include "BKE_particle.h"
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include "BKE_cloth.hh"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_effect.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_key.h"
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_lattice.hh"
|
||||
#include "BKE_lib_id.h"
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "BKE_cdderivedmesh.h"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_modifier.hh"
|
||||
#include "BKE_multires.hh"
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_lib_query.h"
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_modifier.hh"
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_effect.h"
|
||||
#include "BKE_lattice.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_mesh.hh"
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_particle.h"
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_particle.h"
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_camera.h"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_mesh.hh"
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "BKE_action.h" /* BKE_pose_channel_find_name */
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_mesh.hh"
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include "BKE_colortools.hh" /* CurveMapping. */
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_mesh.hh"
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_modifier.hh"
|
||||
#include "BKE_screen.hh"
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "DNA_pointcloud_types.h"
|
||||
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_grease_pencil.hh"
|
||||
#include "BKE_instances.hh"
|
||||
#include "BKE_pointcloud.h"
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "DNA_mesh_types.h"
|
||||
|
||||
#include "BKE_attribute_math.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_mesh_mapping.hh"
|
||||
#include "BKE_mesh_runtime.hh"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user