Compare commits
187 Commits
soc-2021-u
...
temp-llvm-
Author | SHA1 | Date | |
---|---|---|---|
dbc8b52752 | |||
ab6a116334 | |||
077debe17f | |||
33d6b09d3d | |||
f92a1e20bc | |||
c1e014f2a1 | |||
6a69a32c6d | |||
cc32f73a29 | |||
d4367fa8e0 | |||
bb0da7dbbd | |||
5e8b42bf86 | |||
a94d80716e | |||
a836ded990 | |||
279085e18e | |||
d5b77fd522 | |||
![]() |
1c7d7c9150 | ||
d786b48aab | |||
![]() |
465bd66519 | ||
![]() |
b7f6377e38 | ||
bdcc258305 | |||
4bf74afacc | |||
dc0bf9b702 | |||
ba38b06a97 | |||
b92ef379b7 | |||
53ed7ec7f2 | |||
c34ea3323a | |||
7006d4f0fb | |||
1464eff375 | |||
c32ce881e8 | |||
![]() |
1e9175e1d7 | ||
2668f9181c | |||
715e0faabc | |||
955748ab1e | |||
4cbcfd22f5 | |||
d7c556de32 | |||
2e6ae11326 | |||
1a721c5dbe | |||
0e38002dd5 | |||
bd9d09ca82 | |||
9bacd54312 | |||
23ac79f2c2 | |||
44db9f192e | |||
a7dca135dc | |||
b29e33caa2 | |||
e28222966b | |||
d25fa3250a | |||
f6699bfccf | |||
0a68fa8e14 | |||
8c4edd1b37 | |||
d5b72fb06c | |||
336f6f4bbd | |||
d6dd2f51bb | |||
5814de65f9 | |||
11ac276caa | |||
1c9d8fcb47 | |||
644e6c7a3e | |||
eed45d2a23 | |||
31e120ef49 | |||
51a131ddbc | |||
594438ef0d | |||
7cf5f4cc63 | |||
52585b39a1 | |||
20b438d523 | |||
5cf993f951 | |||
28a8d434d5 | |||
dd3a72f275 | |||
ceed8f7c06 | |||
85abac7e87 | |||
![]() |
f7ddb1ed8a | ||
![]() |
fbd01624e3 | ||
![]() |
c5862da5ad | ||
![]() |
9085b4a731 | ||
e505957b47 | |||
28df0107d4 | |||
f1e04116f0 | |||
67525b88d2 | |||
95c7e8aa13 | |||
fc45b00720 | |||
6e0cf86e73 | |||
79012c6784 | |||
26c7be71d7 | |||
291d2a2222 | |||
d48fc7d156 | |||
dd01ce2cd0 | |||
ba4b7b4319 | |||
c0db8a9a3b | |||
81b3933abb | |||
35bd6fe993 | |||
2df912466c | |||
582f6032fc | |||
05f900e346 | |||
43f5e761a6 | |||
![]() |
7a71a95f32 | ||
d71009d980 | |||
025c921416 | |||
00965c98cb | |||
710e279b19 | |||
41f3164e57 | |||
1931387799 | |||
8f89196be2 | |||
60c59d7d61 | |||
c593db5a2f | |||
6b662ebdb9 | |||
9033d270d5 | |||
dca5be9b94 | |||
14621e7720 | |||
![]() |
c6e7fc9744 | ||
0fd72a98ac | |||
b4f978e901 | |||
586e2face6 | |||
e2a9e7e803 | |||
6a71b2af66 | |||
3579a9e0fc | |||
921708fc76 | |||
f577abc5cd | |||
8d3e57f338 | |||
902318f0fd | |||
978a930d9c | |||
aba91a745a | |||
dbbf0e7f66 | |||
fdc4a1a590 | |||
d6224db8f1 | |||
2ce2bffc4d | |||
d2bf60cc17 | |||
![]() |
6db0919724 | ||
aa7105f759 | |||
bdbd0cffda | |||
8cf1994455 | |||
d66a6525c3 | |||
7e712b2d6a | |||
1abf2f3c7c | |||
d13970de86 | |||
fac42e3fa1 | |||
68f1b2c671 | |||
bb4de77b82 | |||
c0f06ba614 | |||
e4de5b4657 | |||
5457b66301 | |||
7acd3ad7d8 | |||
59221476b0 | |||
399f84d479 | |||
d93dd85951 | |||
![]() |
e9092110ff | ||
bdb5852e28 | |||
![]() |
70de992afe | ||
76cb11e332 | |||
82fa2bdf3f | |||
cb96435047 | |||
1d25ba175e | |||
6c33a0f6d6 | |||
edb3ab0617 | |||
e2e7f7ea52 | |||
![]() |
5adc06d2d8 | ||
deb3d566a5 | |||
ffd1a7d8c8 | |||
fdb2167b4a | |||
5c63c0a58c | |||
528fc35fed | |||
0b69793487 | |||
34fac7a670 | |||
cc367908cd | |||
0966eab8e9 | |||
c27d0cb7b9 | |||
eac6aff741 | |||
6878897a6d | |||
8a91673562 | |||
491b9cd2b9 | |||
b9861055ad | |||
d15d512a68 | |||
4c3f57ffa7 | |||
3471b0016c | |||
214a56ce8c | |||
![]() |
8e31e53aa0 | ||
76fd2ff9fa | |||
4b21067aea | |||
2648d920d8 | |||
![]() |
0aabaa4583 | ||
552dce0de7 | |||
77760194fe | |||
a3ad5abf2f | |||
![]() |
c0d96ca9a5 | ||
![]() |
3b965ba10b | ||
b386f960f6 | |||
![]() |
67734d1853 | ||
f3c1d0e3a3 | |||
7b4867d1ba | |||
468bba3d2b |
@@ -2083,9 +2083,9 @@ compile_OIIO() {
|
||||
cmake_d="$cmake_d -D OPENEXR_VERSION=$OPENEXR_VERSION"
|
||||
|
||||
if [ "$_with_built_openexr" = true ]; then
|
||||
cmake_d="$cmake_d -D ILMBASE_HOME=$INST/openexr"
|
||||
cmake_d="$cmake_d -D OPENEXR_HOME=$INST/openexr"
|
||||
INFO "ILMBASE_HOME=$INST/openexr"
|
||||
cmake_d="$cmake_d -D ILMBASE_ROOT=$INST/openexr"
|
||||
cmake_d="$cmake_d -D OPENEXR_ROOT=$INST/openexr"
|
||||
INFO "Ilmbase_ROOT=$INST/openexr"
|
||||
fi
|
||||
|
||||
# ptex is only needed when nicholas bishop is ready
|
||||
@@ -2374,9 +2374,9 @@ compile_OSL() {
|
||||
#~ cmake_d="$cmake_d -D ILMBASE_VERSION=$ILMBASE_VERSION"
|
||||
|
||||
if [ "$_with_built_openexr" = true ]; then
|
||||
INFO "ILMBASE_HOME=$INST/openexr"
|
||||
cmake_d="$cmake_d -D OPENEXR_ROOT_DIR=$INST/openexr"
|
||||
cmake_d="$cmake_d -D ILMBASE_ROOT_DIR=$INST/openexr"
|
||||
cmake_d="$cmake_d -D ILMBASE_ROOT=$INST/openexr"
|
||||
cmake_d="$cmake_d -D OPENEXR_ROOT=$INST/openexr"
|
||||
INFO "Ilmbase_ROOT=$INST/openexr"
|
||||
# XXX Temp workaround... sigh, ILMBase really messed the things up by defining their custom names ON by default :(
|
||||
fi
|
||||
|
||||
|
@@ -197,3 +197,38 @@ index 67ec0d15f..6dc3e85a0 100644
|
||||
#else
|
||||
#error Unknown architecture.
|
||||
#endif
|
||||
|
||||
diff --git a/pxr/base/arch/demangle.cpp b/pxr/base/arch/demangle.cpp
|
||||
index 67ec0d15f..6dc3e85a0 100644
|
||||
--- a/pxr/base/arch/demangle.cpp
|
||||
+++ b/pxr/base/arch/demangle.cpp
|
||||
@@ -36,6 +36,7 @@
|
||||
#if (ARCH_COMPILER_GCC_MAJOR == 3 && ARCH_COMPILER_GCC_MINOR >= 1) || \
|
||||
ARCH_COMPILER_GCC_MAJOR > 3 || defined(ARCH_COMPILER_CLANG)
|
||||
#define _AT_LEAST_GCC_THREE_ONE_OR_CLANG
|
||||
+#include <cxxabi.h>
|
||||
#endif
|
||||
|
||||
PXR_NAMESPACE_OPEN_SCOPE
|
||||
@@ -138,7 +139,6 @@
|
||||
#endif
|
||||
|
||||
#if defined(_AT_LEAST_GCC_THREE_ONE_OR_CLANG)
|
||||
-#include <cxxabi.h>
|
||||
|
||||
/*
|
||||
* This routine doesn't work when you get to gcc3.4.
|
||||
|
||||
diff --git a/pxr/base/work/singularTask.h b/pxr/base/work/singularTask.h
|
||||
index 67ec0d15f..6dc3e85a0 100644
|
||||
--- a/pxr/base/work/singularTask.h
|
||||
+++ b/pxr/base/work/singularTask.h
|
||||
@@ -120,7 +120,7 @@
|
||||
// case we go again to ensure the task can do whatever it
|
||||
// was awakened to do. Once we successfully take the count
|
||||
// to zero, we stop.
|
||||
- size_t old = count;
|
||||
+ std::size_t old = count;
|
||||
do { _fn(); } while (
|
||||
!count.compare_exchange_strong(old, 0));
|
||||
});
|
||||
|
@@ -656,24 +656,24 @@ bool BVHBuild::range_within_max_leaf_size(const BVHRange &range,
|
||||
for (int i = 0; i < size; i++) {
|
||||
const BVHReference &ref = references[range.start() + i];
|
||||
|
||||
if (ref.prim_type() & PRIMITIVE_ALL_CURVE) {
|
||||
if (ref.prim_type() & PRIMITIVE_ALL_MOTION) {
|
||||
if (ref.prim_type() & PRIMITIVE_CURVE) {
|
||||
if (ref.prim_type() & PRIMITIVE_MOTION) {
|
||||
num_motion_curves++;
|
||||
}
|
||||
else {
|
||||
num_curves++;
|
||||
}
|
||||
}
|
||||
else if (ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) {
|
||||
if (ref.prim_type() & PRIMITIVE_ALL_MOTION) {
|
||||
else if (ref.prim_type() & PRIMITIVE_TRIANGLE) {
|
||||
if (ref.prim_type() & PRIMITIVE_MOTION) {
|
||||
num_motion_triangles++;
|
||||
}
|
||||
else {
|
||||
num_triangles++;
|
||||
}
|
||||
}
|
||||
else if (ref.prim_type() & PRIMITIVE_ALL_POINT) {
|
||||
if (ref.prim_type() & PRIMITIVE_ALL_MOTION) {
|
||||
else if (ref.prim_type() & PRIMITIVE_POINT) {
|
||||
if (ref.prim_type() & PRIMITIVE_MOTION) {
|
||||
num_motion_points++;
|
||||
}
|
||||
else {
|
||||
@@ -973,7 +973,7 @@ BVHNode *BVHBuild::create_leaf_node(const BVHRange &range, const vector<BVHRefer
|
||||
for (int i = 0; i < range.size(); i++) {
|
||||
const BVHReference &ref = references[range.start() + i];
|
||||
if (ref.prim_index() != -1) {
|
||||
uint32_t type_index = bitscan((uint32_t)(ref.prim_type() & PRIMITIVE_ALL));
|
||||
uint32_t type_index = PRIMITIVE_INDEX(ref.prim_type() & PRIMITIVE_ALL);
|
||||
p_ref[type_index].push_back(ref);
|
||||
p_type[type_index].push_back(ref.prim_type());
|
||||
p_index[type_index].push_back(ref.prim_index());
|
||||
|
@@ -387,7 +387,7 @@ void BVH2::refit_primitives(int start, int end, BoundBox &bbox, uint &visibility
|
||||
}
|
||||
else {
|
||||
/* Primitives. */
|
||||
if (pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) {
|
||||
if (pack.prim_type[prim] & PRIMITIVE_CURVE) {
|
||||
/* Curves. */
|
||||
const Hair *hair = static_cast<const Hair *>(ob->get_geometry());
|
||||
int prim_offset = (params.top_level) ? hair->prim_offset : 0;
|
||||
@@ -410,7 +410,7 @@ void BVH2::refit_primitives(int start, int end, BoundBox &bbox, uint &visibility
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pack.prim_type[prim] & PRIMITIVE_ALL_POINT) {
|
||||
else if (pack.prim_type[prim] & PRIMITIVE_POINT) {
|
||||
/* Points. */
|
||||
const PointCloud *pointcloud = static_cast<const PointCloud *>(ob->get_geometry());
|
||||
int prim_offset = (params.top_level) ? pointcloud->prim_offset : 0;
|
||||
@@ -590,13 +590,7 @@ void BVH2::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
|
||||
float2 *bvh_prim_time = bvh->pack.prim_time.size() ? &bvh->pack.prim_time[0] : NULL;
|
||||
|
||||
for (size_t i = 0; i < bvh_prim_index_size; i++) {
|
||||
if (bvh->pack.prim_type[i] & PRIMITIVE_ALL_CURVE) {
|
||||
pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + geom_prim_offset;
|
||||
}
|
||||
else {
|
||||
pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + geom_prim_offset;
|
||||
}
|
||||
|
||||
pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + geom_prim_offset;
|
||||
pack_prim_type[pack_prim_index_offset] = bvh_prim_type[i];
|
||||
pack_prim_visibility[pack_prim_index_offset] = bvh_prim_visibility[i];
|
||||
pack_prim_object[pack_prim_index_offset] = 0; // unused for instances
|
||||
|
@@ -91,7 +91,7 @@ static void rtc_filter_occluded_func(const RTCFilterFunctionNArguments *args)
|
||||
++ctx->num_hits;
|
||||
|
||||
/* Always use baked shadow transparency for curves. */
|
||||
if (current_isect.type & PRIMITIVE_ALL_CURVE) {
|
||||
if (current_isect.type & PRIMITIVE_CURVE) {
|
||||
ctx->throughput *= intersection_curve_shadow_transparency(
|
||||
kg, current_isect.object, current_isect.prim, current_isect.u);
|
||||
|
||||
|
@@ -535,15 +535,15 @@ void BVHSpatialSplit::split_reference(const BVHBuild &builder,
|
||||
/* loop over vertices/edges. */
|
||||
const Object *ob = builder.objects[ref.prim_object()];
|
||||
|
||||
if (ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) {
|
||||
if (ref.prim_type() & PRIMITIVE_TRIANGLE) {
|
||||
Mesh *mesh = static_cast<Mesh *>(ob->get_geometry());
|
||||
split_triangle_reference(ref, mesh, dim, pos, left_bounds, right_bounds);
|
||||
}
|
||||
else if (ref.prim_type() & PRIMITIVE_ALL_CURVE) {
|
||||
else if (ref.prim_type() & PRIMITIVE_CURVE) {
|
||||
Hair *hair = static_cast<Hair *>(ob->get_geometry());
|
||||
split_curve_reference(ref, hair, dim, pos, left_bounds, right_bounds);
|
||||
}
|
||||
else if (ref.prim_type() & PRIMITIVE_ALL_POINT) {
|
||||
else if (ref.prim_type() & PRIMITIVE_POINT) {
|
||||
PointCloud *pointcloud = static_cast<PointCloud *>(ob->get_geometry());
|
||||
split_point_reference(ref, pointcloud, dim, pos, left_bounds, right_bounds);
|
||||
}
|
||||
|
@@ -69,7 +69,7 @@ bool BVHUnaligned::compute_aligned_space(const BVHReference &ref, Transform *ali
|
||||
const int packed_type = ref.prim_type();
|
||||
const int type = (packed_type & PRIMITIVE_ALL);
|
||||
/* No motion blur curves here, we can't fit them to aligned boxes well. */
|
||||
if (type & (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_CURVE_THICK)) {
|
||||
if ((type & PRIMITIVE_CURVE) && !(type & PRIMITIVE_MOTION)) {
|
||||
const int curve_index = ref.prim_index();
|
||||
const int segment = PRIMITIVE_UNPACK_SEGMENT(packed_type);
|
||||
const Hair *hair = static_cast<const Hair *>(object->get_geometry());
|
||||
@@ -95,7 +95,7 @@ BoundBox BVHUnaligned::compute_aligned_prim_boundbox(const BVHReference &prim,
|
||||
const int packed_type = prim.prim_type();
|
||||
const int type = (packed_type & PRIMITIVE_ALL);
|
||||
/* No motion blur curves here, we can't fit them to aligned boxes well. */
|
||||
if (type & (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_CURVE_THICK)) {
|
||||
if ((type & PRIMITIVE_CURVE) && !(type & PRIMITIVE_MOTION)) {
|
||||
const int curve_index = prim.prim_index();
|
||||
const int segment = PRIMITIVE_UNPACK_SEGMENT(packed_type);
|
||||
const Hair *hair = static_cast<const Hair *>(object->get_geometry());
|
||||
|
@@ -174,7 +174,7 @@ ccl_device_inline
|
||||
case PRIMITIVE_MOTION_CURVE_THICK:
|
||||
case PRIMITIVE_CURVE_RIBBON:
|
||||
case PRIMITIVE_MOTION_CURVE_RIBBON: {
|
||||
if ((type & PRIMITIVE_ALL_MOTION) && kernel_data.bvh.use_bvh_steps) {
|
||||
if ((type & PRIMITIVE_MOTION) && kernel_data.bvh.use_bvh_steps) {
|
||||
const float2 prim_time = kernel_tex_fetch(__prim_time, prim_addr);
|
||||
if (ray->time < prim_time.x || ray->time > prim_time.y) {
|
||||
hit = false;
|
||||
@@ -203,7 +203,7 @@ ccl_device_inline
|
||||
#if BVH_FEATURE(BVH_POINTCLOUD)
|
||||
case PRIMITIVE_POINT:
|
||||
case PRIMITIVE_MOTION_POINT: {
|
||||
if ((type & PRIMITIVE_ALL_MOTION) && kernel_data.bvh.use_bvh_steps) {
|
||||
if ((type & PRIMITIVE_MOTION) && kernel_data.bvh.use_bvh_steps) {
|
||||
const float2 prim_time = kernel_tex_fetch(__prim_time, prim_addr);
|
||||
if (ray->time < prim_time.x || ray->time > prim_time.y) {
|
||||
hit = false;
|
||||
@@ -255,7 +255,7 @@ ccl_device_inline
|
||||
bool record_intersection = true;
|
||||
|
||||
/* Always use baked shadow transparency for curves. */
|
||||
if (isect.type & PRIMITIVE_ALL_CURVE) {
|
||||
if (isect.type & PRIMITIVE_CURVE) {
|
||||
*throughput *= intersection_curve_shadow_transparency(
|
||||
kg, isect.object, isect.prim, isect.u);
|
||||
|
||||
|
@@ -166,7 +166,7 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals kg,
|
||||
case PRIMITIVE_CURVE_RIBBON:
|
||||
case PRIMITIVE_MOTION_CURVE_RIBBON: {
|
||||
for (; prim_addr < prim_addr2; prim_addr++) {
|
||||
if ((type & PRIMITIVE_ALL_MOTION) && kernel_data.bvh.use_bvh_steps) {
|
||||
if ((type & PRIMITIVE_MOTION) && kernel_data.bvh.use_bvh_steps) {
|
||||
const float2 prim_time = kernel_tex_fetch(__prim_time, prim_addr);
|
||||
if (ray->time < prim_time.x || ray->time > prim_time.y) {
|
||||
continue;
|
||||
@@ -193,7 +193,7 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals kg,
|
||||
case PRIMITIVE_POINT:
|
||||
case PRIMITIVE_MOTION_POINT: {
|
||||
for (; prim_addr < prim_addr2; prim_addr++) {
|
||||
if ((type & PRIMITIVE_ALL_MOTION) && kernel_data.bvh.use_bvh_steps) {
|
||||
if ((type & PRIMITIVE_MOTION) && kernel_data.bvh.use_bvh_steps) {
|
||||
const float2 prim_time = kernel_tex_fetch(__prim_time, prim_addr);
|
||||
if (ray->time < prim_time.x || ray->time > prim_time.y) {
|
||||
continue;
|
||||
|
@@ -118,16 +118,16 @@ ccl_device_forceinline int intersection_get_shader_flags(KernelGlobals kg,
|
||||
{
|
||||
int shader = 0;
|
||||
|
||||
if (type & PRIMITIVE_ALL_TRIANGLE) {
|
||||
if (type & PRIMITIVE_TRIANGLE) {
|
||||
shader = kernel_tex_fetch(__tri_shader, prim);
|
||||
}
|
||||
#ifdef __POINTCLOUD__
|
||||
else if (type & PRIMITIVE_ALL_POINT) {
|
||||
else if (type & PRIMITIVE_POINT) {
|
||||
shader = kernel_tex_fetch(__points_shader, prim);
|
||||
}
|
||||
#endif
|
||||
#ifdef __HAIR__
|
||||
else if (type & PRIMITIVE_ALL_CURVE) {
|
||||
else if (type & PRIMITIVE_CURVE) {
|
||||
shader = kernel_tex_fetch(__curves, prim).shader_id;
|
||||
}
|
||||
#endif
|
||||
@@ -141,16 +141,16 @@ ccl_device_forceinline int intersection_get_shader_from_isect_prim(KernelGlobals
|
||||
{
|
||||
int shader = 0;
|
||||
|
||||
if (isect_type & PRIMITIVE_ALL_TRIANGLE) {
|
||||
if (isect_type & PRIMITIVE_TRIANGLE) {
|
||||
shader = kernel_tex_fetch(__tri_shader, prim);
|
||||
}
|
||||
#ifdef __POINTCLOUD__
|
||||
else if (isect_type & PRIMITIVE_ALL_POINT) {
|
||||
else if (isect_type & PRIMITIVE_POINT) {
|
||||
shader = kernel_tex_fetch(__points_shader, prim);
|
||||
}
|
||||
#endif
|
||||
#ifdef __HAIR__
|
||||
else if (isect_type & PRIMITIVE_ALL_CURVE) {
|
||||
else if (isect_type & PRIMITIVE_CURVE) {
|
||||
shader = kernel_tex_fetch(__curves, prim).shader_id;
|
||||
}
|
||||
#endif
|
||||
|
@@ -124,7 +124,7 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
|
||||
/* For curves use the smooth normal, particularly for ribbons the geometric
|
||||
* normal gives too much darkening otherwise. */
|
||||
int label;
|
||||
const float3 Ng = (sd->type & PRIMITIVE_ALL_CURVE) ? sc->N : sd->Ng;
|
||||
const float3 Ng = (sd->type & PRIMITIVE_CURVE) ? sc->N : sd->Ng;
|
||||
|
||||
switch (sc->type) {
|
||||
case CLOSURE_BSDF_DIFFUSE_ID:
|
||||
|
@@ -213,9 +213,7 @@ ccl_device int bsdf_principled_hair_setup(ccl_private ShaderData *sd,
|
||||
|
||||
/* TODO: we convert this value to a cosine later and discard the sign, so
|
||||
* we could probably save some operations. */
|
||||
float h = (sd->type & (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_MOTION_CURVE_RIBBON)) ?
|
||||
-sd->v :
|
||||
dot(cross(sd->Ng, X), Z);
|
||||
float h = (sd->type & PRIMITIVE_CURVE_RIBBON) ? -sd->v : dot(cross(sd->Ng, X), Z);
|
||||
|
||||
kernel_assert(fabsf(h) < 1.0f + 1e-4f);
|
||||
kernel_assert(isfinite3_safe(Y));
|
||||
|
@@ -211,7 +211,7 @@ bool metalrt_shadow_all_hit(constant KernelParamsMetal &launch_params_metal,
|
||||
}
|
||||
|
||||
/* Always use baked shadow transparency for curves. */
|
||||
if (type & PRIMITIVE_ALL_CURVE) {
|
||||
if (type & PRIMITIVE_CURVE) {
|
||||
float throughput = payload.throughput;
|
||||
throughput *= context.intersection_curve_shadow_transparency(nullptr, object, prim, u);
|
||||
payload.throughput = throughput;
|
||||
@@ -476,7 +476,7 @@ __intersection__curve_ribbon(constant KernelParamsMetal &launch_params_metal [[b
|
||||
result.continue_search = true;
|
||||
result.distance = ray_tmax;
|
||||
|
||||
if (segment.type & (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_MOTION_CURVE_RIBBON)) {
|
||||
if (segment.type & PRIMITIVE_CURVE_RIBBON) {
|
||||
metalrt_intersection_curve(launch_params_metal, payload, object, segment.prim, segment.type, ray_origin, ray_direction,
|
||||
# if defined(__METALRT_MOTION__)
|
||||
payload.time,
|
||||
@@ -507,7 +507,7 @@ __intersection__curve_ribbon_shadow(constant KernelParamsMetal &launch_params_me
|
||||
result.continue_search = true;
|
||||
result.distance = ray_tmax;
|
||||
|
||||
if (segment.type & (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_MOTION_CURVE_RIBBON)) {
|
||||
if (segment.type & PRIMITIVE_CURVE_RIBBON) {
|
||||
metalrt_intersection_curve_shadow(launch_params_metal, payload, object, segment.prim, segment.type, ray_origin, ray_direction,
|
||||
# if defined(__METALRT_MOTION__)
|
||||
payload.time,
|
||||
|
@@ -194,7 +194,7 @@ extern "C" __global__ void __anyhit__kernel_optix_shadow_all_hit()
|
||||
type = kernel_tex_fetch(__objects, object).primitive_type;
|
||||
}
|
||||
# ifdef __HAIR__
|
||||
else if (optixGetHitKind() & PRIMITIVE_ALL_CURVE) {
|
||||
else if ((optixGetHitKind() & (~PRIMITIVE_MOTION)) != PRIMITIVE_POINT) {
|
||||
u = __uint_as_float(optixGetAttribute_0());
|
||||
v = __uint_as_float(optixGetAttribute_1());
|
||||
|
||||
@@ -234,7 +234,7 @@ extern "C" __global__ void __anyhit__kernel_optix_shadow_all_hit()
|
||||
}
|
||||
|
||||
/* Always use baked shadow transparency for curves. */
|
||||
if (type & PRIMITIVE_ALL_CURVE) {
|
||||
if (type & PRIMITIVE_CURVE) {
|
||||
float throughput = __uint_as_float(optixGetPayload_1());
|
||||
throughput *= intersection_curve_shadow_transparency(nullptr, object, prim, u);
|
||||
optixSetPayload_1(__float_as_uint(throughput));
|
||||
@@ -320,7 +320,7 @@ extern "C" __global__ void __anyhit__kernel_optix_visibility_test()
|
||||
{
|
||||
#ifdef __HAIR__
|
||||
# if OPTIX_ABI_VERSION < 55
|
||||
if (optixGetHitKind() & PRIMITIVE_ALL_CURVE) {
|
||||
if (optixGetPrimitiveType() == OPTIX_PRIMITIVE_TYPE_ROUND_CUBIC_BSPLINE) {
|
||||
/* Filter out curve endcaps. */
|
||||
const float u = __uint_as_float(optixGetAttribute_0());
|
||||
if (u == 0.0f || u == 1.0f) {
|
||||
@@ -359,7 +359,7 @@ extern "C" __global__ void __closesthit__kernel_optix_hit()
|
||||
optixSetPayload_3(prim);
|
||||
optixSetPayload_5(kernel_tex_fetch(__objects, object).primitive_type);
|
||||
}
|
||||
else if (optixGetHitKind() & PRIMITIVE_ALL_CURVE) {
|
||||
else if ((optixGetHitKind() & (~PRIMITIVE_MOTION)) != PRIMITIVE_POINT) {
|
||||
const KernelCurveSegment segment = kernel_tex_fetch(__curve_segments, prim);
|
||||
optixSetPayload_1(optixGetAttribute_0()); /* Same as 'optixGetCurveParameter()' */
|
||||
optixSetPayload_2(optixGetAttribute_1());
|
||||
@@ -406,6 +406,7 @@ ccl_device_inline void optix_intersection_curve(const int prim, const int type)
|
||||
isect.t *= len;
|
||||
|
||||
if (curve_intersect(NULL, &isect, P, dir, isect.t, object, prim, time, type)) {
|
||||
static_assert(PRIMITIVE_ALL < 128, "Values >= 128 are reserved for OptiX internal use");
|
||||
optixReportIntersection(isect.t / len,
|
||||
type & PRIMITIVE_ALL,
|
||||
__float_as_int(isect.u), /* Attribute_0 */
|
||||
@@ -418,7 +419,7 @@ extern "C" __global__ void __intersection__curve_ribbon()
|
||||
const KernelCurveSegment segment = kernel_tex_fetch(__curve_segments, optixGetPrimitiveIndex());
|
||||
const int prim = segment.prim;
|
||||
const int type = segment.type;
|
||||
if (type & (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_MOTION_CURVE_RIBBON)) {
|
||||
if (type & PRIMITIVE_CURVE_RIBBON) {
|
||||
optix_intersection_curve(prim, type);
|
||||
}
|
||||
}
|
||||
@@ -460,6 +461,7 @@ extern "C" __global__ void __intersection__point()
|
||||
}
|
||||
|
||||
if (point_intersect(NULL, &isect, P, dir, isect.t, object, prim, time, type)) {
|
||||
static_assert(PRIMITIVE_ALL < 128, "Values >= 128 are reserved for OptiX internal use");
|
||||
optixReportIntersection(isect.t / len, type & PRIMITIVE_ALL);
|
||||
}
|
||||
}
|
||||
|
@@ -36,7 +36,7 @@ ccl_device_inline uint subd_triangle_patch(KernelGlobals kg, ccl_private const S
|
||||
|
||||
ccl_device_inline uint attribute_primitive_type(KernelGlobals kg, ccl_private const ShaderData *sd)
|
||||
{
|
||||
if ((sd->type & PRIMITIVE_ALL_TRIANGLE) && subd_triangle_patch(kg, sd) != ~0) {
|
||||
if ((sd->type & PRIMITIVE_TRIANGLE) && subd_triangle_patch(kg, sd) != ~0) {
|
||||
return ATTR_PRIM_SUBD;
|
||||
}
|
||||
else {
|
||||
|
@@ -205,14 +205,14 @@ ccl_device float curve_thickness(KernelGlobals kg, ccl_private const ShaderData
|
||||
{
|
||||
float r = 0.0f;
|
||||
|
||||
if (sd->type & PRIMITIVE_ALL_CURVE) {
|
||||
if (sd->type & PRIMITIVE_CURVE) {
|
||||
KernelCurve curve = kernel_tex_fetch(__curves, sd->prim);
|
||||
int k0 = curve.first_key + PRIMITIVE_UNPACK_SEGMENT(sd->type);
|
||||
int k1 = k0 + 1;
|
||||
|
||||
float4 P_curve[2];
|
||||
|
||||
if (!(sd->type & PRIMITIVE_ALL_MOTION)) {
|
||||
if (!(sd->type & PRIMITIVE_MOTION)) {
|
||||
P_curve[0] = kernel_tex_fetch(__curve_keys, k0);
|
||||
P_curve[1] = kernel_tex_fetch(__curve_keys, k1);
|
||||
}
|
||||
@@ -249,7 +249,7 @@ ccl_device float3 curve_tangent_normal(KernelGlobals kg, ccl_private const Shade
|
||||
{
|
||||
float3 tgN = make_float3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
if (sd->type & PRIMITIVE_ALL_CURVE) {
|
||||
if (sd->type & PRIMITIVE_CURVE) {
|
||||
|
||||
tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu, -sd->I) / len_squared(sd->dPdu)));
|
||||
tgN = normalize(tgN);
|
||||
|
@@ -635,7 +635,7 @@ ccl_device_forceinline bool curve_intersect(KernelGlobals kg,
|
||||
float time,
|
||||
int type)
|
||||
{
|
||||
const bool is_motion = (type & PRIMITIVE_ALL_MOTION);
|
||||
const bool is_motion = (type & PRIMITIVE_MOTION);
|
||||
|
||||
KernelCurve kcurve = kernel_tex_fetch(__curves, prim);
|
||||
|
||||
@@ -655,7 +655,7 @@ ccl_device_forceinline bool curve_intersect(KernelGlobals kg,
|
||||
motion_curve_keys(kg, object, prim, time, ka, k0, k1, kb, curve);
|
||||
}
|
||||
|
||||
if (type & (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_MOTION_CURVE_RIBBON)) {
|
||||
if (type & PRIMITIVE_CURVE_RIBBON) {
|
||||
/* todo: adaptive number of subdivisions could help performance here. */
|
||||
const int subdivisions = kernel_data.bvh.curve_subdivisions;
|
||||
if (ribbon_intersect(P, dir, tmax, subdivisions, curve, isect)) {
|
||||
@@ -704,7 +704,7 @@ ccl_device_inline void curve_shader_setup(KernelGlobals kg,
|
||||
|
||||
float4 P_curve[4];
|
||||
|
||||
if (!(sd->type & PRIMITIVE_ALL_MOTION)) {
|
||||
if (!(sd->type & PRIMITIVE_MOTION)) {
|
||||
P_curve[0] = kernel_tex_fetch(__curve_keys, ka);
|
||||
P_curve[1] = kernel_tex_fetch(__curve_keys, k0);
|
||||
P_curve[2] = kernel_tex_fetch(__curve_keys, k1);
|
||||
@@ -719,7 +719,7 @@ ccl_device_inline void curve_shader_setup(KernelGlobals kg,
|
||||
const float4 dPdu4 = catmull_rom_basis_derivative(P_curve, sd->u);
|
||||
const float3 dPdu = float4_to_float3(dPdu4);
|
||||
|
||||
if (sd->type & (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_MOTION_CURVE_RIBBON)) {
|
||||
if (sd->type & PRIMITIVE_CURVE_RIBBON) {
|
||||
/* Rounded smooth normals for ribbons, to approximate thick curve shape. */
|
||||
const float3 tangent = normalize(dPdu);
|
||||
const float3 bitangent = normalize(cross(tangent, -D));
|
||||
@@ -727,8 +727,6 @@ ccl_device_inline void curve_shader_setup(KernelGlobals kg,
|
||||
const float cosine = safe_sqrtf(1.0f - sine * sine);
|
||||
|
||||
sd->N = normalize(sine * bitangent - cosine * normalize(cross(tangent, bitangent)));
|
||||
sd->Ng = -D;
|
||||
|
||||
# if 0
|
||||
/* This approximates the position and geometric normal of a thick curve too,
|
||||
* but gives too many issues with wrong self intersections. */
|
||||
@@ -744,25 +742,27 @@ ccl_device_inline void curve_shader_setup(KernelGlobals kg,
|
||||
/* NOTE: It is possible that P will be the same as P_inside (precision issues, or very small
|
||||
* radius). In this case use the view direction to approximate the normal. */
|
||||
const float3 P_inside = float4_to_float3(catmull_rom_basis_eval(P_curve, sd->u));
|
||||
const float3 Ng = (!isequal_float3(P, P_inside)) ? normalize(P - P_inside) : -sd->I;
|
||||
const float3 N = (!isequal_float3(P, P_inside)) ? normalize(P - P_inside) : -sd->I;
|
||||
|
||||
sd->N = Ng;
|
||||
sd->Ng = Ng;
|
||||
sd->N = N;
|
||||
sd->v = 0.0f;
|
||||
}
|
||||
|
||||
# ifdef __DPDU__
|
||||
/* dPdu/dPdv */
|
||||
sd->dPdu = dPdu;
|
||||
sd->dPdv = cross(dPdu, sd->Ng);
|
||||
# endif
|
||||
|
||||
/* Convert to world space. */
|
||||
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
|
||||
const Transform tfm = object_get_transform(kg, sd);
|
||||
P = transform_point(&tfm, P);
|
||||
object_position_transform_auto(kg, sd, &P);
|
||||
object_normal_transform_auto(kg, sd, &sd->N);
|
||||
object_dir_transform_auto(kg, sd, &sd->dPdu);
|
||||
}
|
||||
|
||||
sd->P = P;
|
||||
sd->Ng = (sd->type & PRIMITIVE_CURVE_RIBBON) ? sd->I : sd->N;
|
||||
sd->dPdv = cross(sd->dPdu, sd->Ng);
|
||||
sd->shader = kernel_tex_fetch(__curves, sd->prim).shader_id;
|
||||
}
|
||||
|
||||
|
@@ -46,8 +46,11 @@ ccl_device float point_attribute_float(KernelGlobals kg,
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device float2 point_attribute_float2(
|
||||
KernelGlobals kg, const ShaderData *sd, const AttributeDescriptor desc, float2 *dx, float2 *dy)
|
||||
ccl_device float2 point_attribute_float2(KernelGlobals kg,
|
||||
ccl_private const ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
ccl_private float2 *dx,
|
||||
ccl_private float2 *dy)
|
||||
{
|
||||
# ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx)
|
||||
@@ -64,8 +67,11 @@ ccl_device float2 point_attribute_float2(
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device float3 point_attribute_float3(
|
||||
KernelGlobals kg, const ShaderData *sd, const AttributeDescriptor desc, float3 *dx, float3 *dy)
|
||||
ccl_device float3 point_attribute_float3(KernelGlobals kg,
|
||||
ccl_private const ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
ccl_private float3 *dx,
|
||||
ccl_private float3 *dy)
|
||||
{
|
||||
# ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx)
|
||||
@@ -82,8 +88,11 @@ ccl_device float3 point_attribute_float3(
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device float4 point_attribute_float4(
|
||||
KernelGlobals kg, const ShaderData *sd, const AttributeDescriptor desc, float4 *dx, float4 *dy)
|
||||
ccl_device float4 point_attribute_float4(KernelGlobals kg,
|
||||
ccl_private const ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
ccl_private float4 *dx,
|
||||
ccl_private float4 *dy)
|
||||
{
|
||||
# ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx)
|
||||
@@ -104,7 +113,7 @@ ccl_device float4 point_attribute_float4(
|
||||
|
||||
ccl_device float point_radius(KernelGlobals kg, ccl_private const ShaderData *sd)
|
||||
{
|
||||
if (sd->type & PRIMITIVE_ALL_POINT) {
|
||||
if (sd->type & PRIMITIVE_POINT) {
|
||||
return kernel_tex_fetch(__points, sd->prim).w;
|
||||
}
|
||||
|
||||
|
@@ -23,7 +23,7 @@ CCL_NAMESPACE_BEGIN
|
||||
#ifdef __POINTCLOUD__
|
||||
|
||||
ccl_device_forceinline bool point_intersect_test(
|
||||
const float4 point, const float3 P, const float3 dir, const float tmax, float *t)
|
||||
const float4 point, const float3 P, const float3 dir, const float tmax, ccl_private float *t)
|
||||
{
|
||||
const float3 center = float4_to_float3(point);
|
||||
const float radius = point.w;
|
||||
@@ -75,8 +75,8 @@ ccl_device_forceinline bool point_intersect(KernelGlobals kg,
|
||||
const float time,
|
||||
const int type)
|
||||
{
|
||||
const float4 point = (type & PRIMITIVE_ALL_MOTION) ? motion_point(kg, object, prim, time) :
|
||||
kernel_tex_fetch(__points, prim);
|
||||
const float4 point = (type & PRIMITIVE_MOTION) ? motion_point(kg, object, prim, time) :
|
||||
kernel_tex_fetch(__points, prim);
|
||||
|
||||
if (!point_intersect_test(point, P, dir, tmax, &isect->t)) {
|
||||
return false;
|
||||
@@ -93,7 +93,7 @@ ccl_device_forceinline bool point_intersect(KernelGlobals kg,
|
||||
ccl_device_inline void point_shader_setup(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private const Intersection *isect,
|
||||
const Ray *ray)
|
||||
ccl_private const Ray *ray)
|
||||
{
|
||||
sd->shader = kernel_tex_fetch(__points_shader, isect->prim);
|
||||
sd->P = ray->P + ray->D * isect->t;
|
||||
@@ -104,17 +104,12 @@ ccl_device_inline void point_shader_setup(KernelGlobals kg,
|
||||
sd->v = isect->v;
|
||||
# endif
|
||||
|
||||
/* Computer point center for normal. */
|
||||
float3 center = float4_to_float3((isect->type & PRIMITIVE_ALL_MOTION) ?
|
||||
/* Compute point center for normal. */
|
||||
float3 center = float4_to_float3((isect->type & PRIMITIVE_MOTION) ?
|
||||
motion_point(kg, sd->object, sd->prim, sd->time) :
|
||||
kernel_tex_fetch(__points, sd->prim));
|
||||
|
||||
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
|
||||
const Transform tfm = object_get_transform(kg, sd);
|
||||
|
||||
# ifndef __KERNEL_OPTIX__
|
||||
center = transform_point(&tfm, center);
|
||||
# endif
|
||||
object_position_transform_auto(kg, sd, ¢er);
|
||||
}
|
||||
|
||||
/* Normal */
|
||||
|
@@ -37,19 +37,19 @@ ccl_device_inline float primitive_surface_attribute_float(KernelGlobals kg,
|
||||
ccl_private float *dx,
|
||||
ccl_private float *dy)
|
||||
{
|
||||
if (sd->type & PRIMITIVE_ALL_TRIANGLE) {
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
if (subd_triangle_patch(kg, sd) == ~0)
|
||||
return triangle_attribute_float(kg, sd, desc, dx, dy);
|
||||
else
|
||||
return subd_triangle_attribute_float(kg, sd, desc, dx, dy);
|
||||
}
|
||||
#ifdef __HAIR__
|
||||
else if (sd->type & PRIMITIVE_ALL_CURVE) {
|
||||
else if (sd->type & PRIMITIVE_CURVE) {
|
||||
return curve_attribute_float(kg, sd, desc, dx, dy);
|
||||
}
|
||||
#endif
|
||||
#ifdef __POINTCLOUD__
|
||||
else if (sd->type & PRIMITIVE_ALL_POINT) {
|
||||
else if (sd->type & PRIMITIVE_POINT) {
|
||||
return point_attribute_float(kg, sd, desc, dx, dy);
|
||||
}
|
||||
#endif
|
||||
@@ -68,19 +68,19 @@ ccl_device_inline float2 primitive_surface_attribute_float2(KernelGlobals kg,
|
||||
ccl_private float2 *dx,
|
||||
ccl_private float2 *dy)
|
||||
{
|
||||
if (sd->type & PRIMITIVE_ALL_TRIANGLE) {
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
if (subd_triangle_patch(kg, sd) == ~0)
|
||||
return triangle_attribute_float2(kg, sd, desc, dx, dy);
|
||||
else
|
||||
return subd_triangle_attribute_float2(kg, sd, desc, dx, dy);
|
||||
}
|
||||
#ifdef __HAIR__
|
||||
else if (sd->type & PRIMITIVE_ALL_CURVE) {
|
||||
else if (sd->type & PRIMITIVE_CURVE) {
|
||||
return curve_attribute_float2(kg, sd, desc, dx, dy);
|
||||
}
|
||||
#endif
|
||||
#ifdef __POINTCLOUD__
|
||||
else if (sd->type & PRIMITIVE_ALL_POINT) {
|
||||
else if (sd->type & PRIMITIVE_POINT) {
|
||||
return point_attribute_float2(kg, sd, desc, dx, dy);
|
||||
}
|
||||
#endif
|
||||
@@ -99,19 +99,19 @@ ccl_device_inline float3 primitive_surface_attribute_float3(KernelGlobals kg,
|
||||
ccl_private float3 *dx,
|
||||
ccl_private float3 *dy)
|
||||
{
|
||||
if (sd->type & PRIMITIVE_ALL_TRIANGLE) {
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
if (subd_triangle_patch(kg, sd) == ~0)
|
||||
return triangle_attribute_float3(kg, sd, desc, dx, dy);
|
||||
else
|
||||
return subd_triangle_attribute_float3(kg, sd, desc, dx, dy);
|
||||
}
|
||||
#ifdef __HAIR__
|
||||
else if (sd->type & PRIMITIVE_ALL_CURVE) {
|
||||
else if (sd->type & PRIMITIVE_CURVE) {
|
||||
return curve_attribute_float3(kg, sd, desc, dx, dy);
|
||||
}
|
||||
#endif
|
||||
#ifdef __POINTCLOUD__
|
||||
else if (sd->type & PRIMITIVE_ALL_POINT) {
|
||||
else if (sd->type & PRIMITIVE_POINT) {
|
||||
return point_attribute_float3(kg, sd, desc, dx, dy);
|
||||
}
|
||||
#endif
|
||||
@@ -130,19 +130,19 @@ ccl_device_forceinline float4 primitive_surface_attribute_float4(KernelGlobals k
|
||||
ccl_private float4 *dx,
|
||||
ccl_private float4 *dy)
|
||||
{
|
||||
if (sd->type & PRIMITIVE_ALL_TRIANGLE) {
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
if (subd_triangle_patch(kg, sd) == ~0)
|
||||
return triangle_attribute_float4(kg, sd, desc, dx, dy);
|
||||
else
|
||||
return subd_triangle_attribute_float4(kg, sd, desc, dx, dy);
|
||||
}
|
||||
#ifdef __HAIR__
|
||||
else if (sd->type & PRIMITIVE_ALL_CURVE) {
|
||||
else if (sd->type & PRIMITIVE_CURVE) {
|
||||
return curve_attribute_float4(kg, sd, desc, dx, dy);
|
||||
}
|
||||
#endif
|
||||
#ifdef __POINTCLOUD__
|
||||
else if (sd->type & PRIMITIVE_ALL_POINT) {
|
||||
else if (sd->type & PRIMITIVE_POINT) {
|
||||
return point_attribute_float4(kg, sd, desc, dx, dy);
|
||||
}
|
||||
#endif
|
||||
@@ -246,7 +246,7 @@ ccl_device bool primitive_ptex(KernelGlobals kg,
|
||||
ccl_device float3 primitive_tangent(KernelGlobals kg, ccl_private ShaderData *sd)
|
||||
{
|
||||
#if defined(__HAIR__) || defined(__POINTCLOUD__)
|
||||
if (sd->type & (PRIMITIVE_ALL_CURVE | PRIMITIVE_ALL_POINT))
|
||||
if (sd->type & (PRIMITIVE_CURVE | PRIMITIVE_POINT))
|
||||
# ifdef __DPDU__
|
||||
return normalize(sd->dPdu);
|
||||
# else
|
||||
@@ -282,16 +282,16 @@ ccl_device_inline float4 primitive_motion_vector(KernelGlobals kg,
|
||||
float3 center;
|
||||
|
||||
#if defined(__HAIR__) || defined(__POINTCLOUD__)
|
||||
bool is_curve_or_point = sd->type & (PRIMITIVE_ALL_CURVE | PRIMITIVE_ALL_POINT);
|
||||
bool is_curve_or_point = sd->type & (PRIMITIVE_CURVE | PRIMITIVE_POINT);
|
||||
if (is_curve_or_point) {
|
||||
center = make_float3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
if (sd->type & PRIMITIVE_ALL_CURVE) {
|
||||
if (sd->type & PRIMITIVE_CURVE) {
|
||||
# if defined(__HAIR__)
|
||||
center = curve_motion_center_location(kg, sd);
|
||||
# endif
|
||||
}
|
||||
else if (sd->type & PRIMITIVE_ALL_POINT) {
|
||||
else if (sd->type & PRIMITIVE_POINT) {
|
||||
# if defined(__POINTCLOUD__)
|
||||
center = point_motion_center_location(kg, sd);
|
||||
# endif
|
||||
@@ -331,7 +331,7 @@ ccl_device_inline float4 primitive_motion_vector(KernelGlobals kg,
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (sd->type & PRIMITIVE_ALL_TRIANGLE) {
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
/* Triangle */
|
||||
if (subd_triangle_patch(kg, sd) == ~0) {
|
||||
motion_pre = triangle_attribute_float3(kg, sd, desc, NULL, NULL);
|
||||
|
@@ -69,56 +69,58 @@ ccl_device_inline void shader_setup_from_ray(KernelGlobals kg,
|
||||
sd->I = -ray->D;
|
||||
|
||||
#ifdef __HAIR__
|
||||
if (sd->type & PRIMITIVE_ALL_CURVE) {
|
||||
if (sd->type & PRIMITIVE_CURVE) {
|
||||
/* curve */
|
||||
curve_shader_setup(kg, sd, ray->P, ray->D, isect->t, isect->object, isect->prim);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef __POINTCLOUD__
|
||||
if (sd->type & PRIMITIVE_ALL_POINT) {
|
||||
if (sd->type & PRIMITIVE_POINT) {
|
||||
/* point */
|
||||
point_shader_setup(kg, sd, isect, ray);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
/* static triangle */
|
||||
float3 Ng = triangle_normal(kg, sd);
|
||||
sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
|
||||
{
|
||||
if (sd->type == PRIMITIVE_TRIANGLE) {
|
||||
/* static triangle */
|
||||
float3 Ng = triangle_normal(kg, sd);
|
||||
sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
|
||||
|
||||
/* vectors */
|
||||
sd->P = triangle_refine(kg, sd, ray->P, ray->D, isect->t, isect->object, isect->prim);
|
||||
sd->Ng = Ng;
|
||||
sd->N = Ng;
|
||||
/* vectors */
|
||||
sd->P = triangle_refine(kg, sd, ray->P, ray->D, isect->t, isect->object, isect->prim);
|
||||
sd->Ng = Ng;
|
||||
sd->N = Ng;
|
||||
|
||||
/* smooth normal */
|
||||
if (sd->shader & SHADER_SMOOTH_NORMAL)
|
||||
sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v);
|
||||
/* smooth normal */
|
||||
if (sd->shader & SHADER_SMOOTH_NORMAL)
|
||||
sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v);
|
||||
|
||||
#ifdef __DPDU__
|
||||
/* dPdu/dPdv */
|
||||
triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
|
||||
/* dPdu/dPdv */
|
||||
triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
/* motion triangle */
|
||||
motion_triangle_shader_setup(
|
||||
kg, sd, ray->P, ray->D, isect->t, isect->object, isect->prim, false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* motion triangle */
|
||||
motion_triangle_shader_setup(
|
||||
kg, sd, ray->P, ray->D, isect->t, isect->object, isect->prim, false);
|
||||
}
|
||||
|
||||
sd->flag |= kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
|
||||
|
||||
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
|
||||
/* instance transform */
|
||||
object_normal_transform_auto(kg, sd, &sd->N);
|
||||
object_normal_transform_auto(kg, sd, &sd->Ng);
|
||||
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
|
||||
/* instance transform */
|
||||
object_normal_transform_auto(kg, sd, &sd->N);
|
||||
object_normal_transform_auto(kg, sd, &sd->Ng);
|
||||
#ifdef __DPDU__
|
||||
object_dir_transform_auto(kg, sd, &sd->dPdu);
|
||||
object_dir_transform_auto(kg, sd, &sd->dPdv);
|
||||
object_dir_transform_auto(kg, sd, &sd->dPdu);
|
||||
object_dir_transform_auto(kg, sd, &sd->dPdv);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
sd->flag = kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
|
||||
|
||||
/* backfacing test */
|
||||
bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
|
||||
|
||||
@@ -201,7 +203,7 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals kg,
|
||||
object_dir_transform_auto(kg, sd, &sd->I);
|
||||
}
|
||||
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
if (sd->type == PRIMITIVE_TRIANGLE) {
|
||||
/* smooth normal */
|
||||
if (sd->shader & SHADER_SMOOTH_NORMAL) {
|
||||
sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v);
|
||||
|
@@ -82,7 +82,7 @@ ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg,
|
||||
|
||||
# ifdef __HAIR__
|
||||
if (!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS) &&
|
||||
(sd->type & PRIMITIVE_ALL_TRIANGLE))
|
||||
(sd->type & PRIMITIVE_TRIANGLE))
|
||||
# else
|
||||
if (!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS))
|
||||
# endif
|
||||
|
@@ -191,7 +191,7 @@ ccl_device_inline float3 shadow_ray_offset(KernelGlobals kg,
|
||||
float3 Ng = (transmit ? -sd->Ng : sd->Ng);
|
||||
float3 P = ray_offset(sd->P, Ng);
|
||||
|
||||
if ((sd->type & PRIMITIVE_ALL_TRIANGLE) && (sd->shader & SHADER_SMOOTH_NORMAL)) {
|
||||
if ((sd->type & PRIMITIVE_TRIANGLE) && (sd->shader & SHADER_SMOOTH_NORMAL)) {
|
||||
const float offset_cutoff =
|
||||
kernel_tex_fetch(__objects, sd->object).shadow_terminator_geometry_offset;
|
||||
/* Do ray offset (heavy stuff) only for close to be terminated triangles:
|
||||
|
@@ -960,13 +960,15 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
|
||||
return set_attribute_int(3, type, derivatives, val);
|
||||
}
|
||||
else if ((name == u_geom_trianglevertices || name == u_geom_polyvertices) &&
|
||||
sd->type & PRIMITIVE_ALL_TRIANGLE) {
|
||||
sd->type & PRIMITIVE_TRIANGLE) {
|
||||
float3 P[3];
|
||||
|
||||
if (sd->type & PRIMITIVE_TRIANGLE)
|
||||
triangle_vertices(kg, sd->prim, P);
|
||||
else
|
||||
if (sd->type & PRIMITIVE_MOTION) {
|
||||
motion_triangle_vertices(kg, sd->object, sd->prim, sd->time, P);
|
||||
}
|
||||
else {
|
||||
triangle_vertices(kg, sd->prim, P);
|
||||
}
|
||||
|
||||
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
|
||||
object_position_transform(kg, sd, &P[0]);
|
||||
@@ -986,7 +988,7 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
|
||||
}
|
||||
/* Hair Attributes */
|
||||
else if (name == u_is_curve) {
|
||||
float f = (sd->type & PRIMITIVE_ALL_CURVE) != 0;
|
||||
float f = (sd->type & PRIMITIVE_CURVE) != 0;
|
||||
return set_attribute_float(f, type, derivatives, val);
|
||||
}
|
||||
else if (name == u_curve_thickness) {
|
||||
@@ -999,7 +1001,7 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
|
||||
}
|
||||
/* point attributes */
|
||||
else if (name == u_is_point) {
|
||||
float f = (sd->type & PRIMITIVE_ALL_POINT) != 0;
|
||||
float f = (sd->type & PRIMITIVE_POINT) != 0;
|
||||
return set_attribute_float(f, type, derivatives, val);
|
||||
}
|
||||
else if (name == u_point_radius) {
|
||||
@@ -1007,7 +1009,7 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
|
||||
return set_attribute_float(f, type, derivatives, val);
|
||||
}
|
||||
else if (name == u_normal_map_normal) {
|
||||
if (sd->type & PRIMITIVE_ALL_TRIANGLE) {
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
float3 f = triangle_smooth_normal_unnormalized(kg, sd, sd->Ng, sd->prim, sd->u, sd->v);
|
||||
return set_attribute_float3(f, type, derivatives, val);
|
||||
}
|
||||
|
@@ -206,12 +206,12 @@ ccl_device float3 svm_bevel(
|
||||
for (int hit = 0; hit < num_eval_hits; hit++) {
|
||||
/* Quickly retrieve P and Ng without setting up ShaderData. */
|
||||
float3 hit_P;
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
if (sd->type == PRIMITIVE_TRIANGLE) {
|
||||
hit_P = triangle_refine_local(
|
||||
kg, sd, ray.P, ray.D, ray.t, isect.hits[hit].object, isect.hits[hit].prim);
|
||||
}
|
||||
# ifdef __OBJECT_MOTION__
|
||||
else if (sd->type & PRIMITIVE_MOTION_TRIANGLE) {
|
||||
else if (sd->type == PRIMITIVE_MOTION_TRIANGLE) {
|
||||
float3 verts[3];
|
||||
motion_triangle_vertices(kg, sd->object, isect.hits[hit].prim, sd->time, verts);
|
||||
hit_P = motion_triangle_refine_local(
|
||||
@@ -236,11 +236,11 @@ ccl_device float3 svm_bevel(
|
||||
float u = isect.hits[hit].u;
|
||||
float v = isect.hits[hit].v;
|
||||
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
if (sd->type == PRIMITIVE_TRIANGLE) {
|
||||
N = triangle_smooth_normal(kg, N, prim, u, v);
|
||||
}
|
||||
# ifdef __OBJECT_MOTION__
|
||||
else if (sd->type & PRIMITIVE_MOTION_TRIANGLE) {
|
||||
else if (sd->type == PRIMITIVE_MOTION_TRIANGLE) {
|
||||
N = motion_triangle_smooth_normal(kg, N, sd->object, prim, u, v, sd->time);
|
||||
}
|
||||
# endif /* __OBJECT_MOTION__ */
|
||||
|
@@ -107,7 +107,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
||||
}
|
||||
|
||||
float3 N = stack_valid(data_node.x) ? stack_load_float3(stack, data_node.x) : sd->N;
|
||||
if (!(sd->type & PRIMITIVE_ALL_CURVE)) {
|
||||
if (!(sd->type & PRIMITIVE_CURVE)) {
|
||||
N = ensure_valid_reflection(sd->Ng, sd->I, N);
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
||||
float3 clearcoat_normal = stack_valid(data_cn_ssr.x) ?
|
||||
stack_load_float3(stack, data_cn_ssr.x) :
|
||||
sd->N;
|
||||
if (!(sd->type & PRIMITIVE_ALL_CURVE)) {
|
||||
if (!(sd->type & PRIMITIVE_CURVE)) {
|
||||
clearcoat_normal = ensure_valid_reflection(sd->Ng, sd->I, clearcoat_normal);
|
||||
}
|
||||
float3 subsurface_radius = stack_valid(data_cn_ssr.y) ?
|
||||
@@ -902,7 +902,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
||||
if (stack_valid(data_node.y)) {
|
||||
bsdf->T = normalize(stack_load_float3(stack, data_node.y));
|
||||
}
|
||||
else if (!(sd->type & PRIMITIVE_ALL_CURVE)) {
|
||||
else if (!(sd->type & PRIMITIVE_CURVE)) {
|
||||
bsdf->T = normalize(sd->dPdv);
|
||||
bsdf->offset = 0.0f;
|
||||
}
|
||||
|
@@ -227,7 +227,7 @@ ccl_device_noinline void svm_node_hair_info(KernelGlobals kg,
|
||||
|
||||
switch (type) {
|
||||
case NODE_INFO_CURVE_IS_STRAND: {
|
||||
data = (sd->type & PRIMITIVE_ALL_CURVE) != 0;
|
||||
data = (sd->type & PRIMITIVE_CURVE) != 0;
|
||||
stack_store_float(stack, out_offset, data);
|
||||
break;
|
||||
}
|
||||
|
@@ -291,7 +291,7 @@ ccl_device_noinline void svm_node_normal_map(KernelGlobals kg,
|
||||
|
||||
if (space == NODE_NORMAL_MAP_TANGENT) {
|
||||
/* tangent space */
|
||||
if (sd->object == OBJECT_NONE || (sd->type & PRIMITIVE_ALL_TRIANGLE) == 0) {
|
||||
if (sd->object == OBJECT_NONE || (sd->type & PRIMITIVE_TRIANGLE) == 0) {
|
||||
/* Fallback to unperturbed normal. */
|
||||
stack_store_float3(stack, normal_offset, sd->N);
|
||||
return;
|
||||
|
@@ -43,7 +43,7 @@ ccl_device_inline float wireframe(KernelGlobals kg,
|
||||
ccl_private float3 *P)
|
||||
{
|
||||
#if defined(__HAIR__) || defined(__POINTCLOUD__)
|
||||
if (sd->prim != PRIM_NONE && sd->type & PRIMITIVE_ALL_TRIANGLE)
|
||||
if (sd->prim != PRIM_NONE && sd->type & PRIMITIVE_TRIANGLE)
|
||||
#else
|
||||
if (sd->prim != PRIM_NONE)
|
||||
#endif
|
||||
@@ -54,10 +54,12 @@ ccl_device_inline float wireframe(KernelGlobals kg,
|
||||
/* Triangles */
|
||||
int np = 3;
|
||||
|
||||
if (sd->type & PRIMITIVE_TRIANGLE)
|
||||
triangle_vertices(kg, sd->prim, Co);
|
||||
else
|
||||
if (sd->type & PRIMITIVE_MOTION) {
|
||||
motion_triangle_vertices(kg, sd->object, sd->prim, sd->time, Co);
|
||||
}
|
||||
else {
|
||||
triangle_vertices(kg, sd->prim, Co);
|
||||
}
|
||||
|
||||
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
|
||||
object_position_transform(kg, sd, &Co[0]);
|
||||
|
@@ -537,31 +537,34 @@ typedef struct Intersection {
|
||||
typedef enum PrimitiveType {
|
||||
PRIMITIVE_NONE = 0,
|
||||
PRIMITIVE_TRIANGLE = (1 << 0),
|
||||
PRIMITIVE_MOTION_TRIANGLE = (1 << 1),
|
||||
PRIMITIVE_CURVE_THICK = (1 << 2),
|
||||
PRIMITIVE_MOTION_CURVE_THICK = (1 << 3),
|
||||
PRIMITIVE_CURVE_RIBBON = (1 << 4),
|
||||
PRIMITIVE_MOTION_CURVE_RIBBON = (1 << 5),
|
||||
PRIMITIVE_POINT = (1 << 6),
|
||||
PRIMITIVE_MOTION_POINT = (1 << 7),
|
||||
PRIMITIVE_VOLUME = (1 << 8),
|
||||
PRIMITIVE_LAMP = (1 << 9),
|
||||
PRIMITIVE_CURVE_THICK = (1 << 1),
|
||||
PRIMITIVE_CURVE_RIBBON = (1 << 2),
|
||||
PRIMITIVE_POINT = (1 << 3),
|
||||
PRIMITIVE_VOLUME = (1 << 4),
|
||||
PRIMITIVE_LAMP = (1 << 5),
|
||||
|
||||
PRIMITIVE_ALL_TRIANGLE = (PRIMITIVE_TRIANGLE | PRIMITIVE_MOTION_TRIANGLE),
|
||||
PRIMITIVE_ALL_CURVE = (PRIMITIVE_CURVE_THICK | PRIMITIVE_MOTION_CURVE_THICK |
|
||||
PRIMITIVE_CURVE_RIBBON | PRIMITIVE_MOTION_CURVE_RIBBON),
|
||||
PRIMITIVE_ALL_POINT = (PRIMITIVE_POINT | PRIMITIVE_MOTION_POINT),
|
||||
PRIMITIVE_ALL_VOLUME = (PRIMITIVE_VOLUME),
|
||||
PRIMITIVE_ALL_MOTION = (PRIMITIVE_MOTION_TRIANGLE | PRIMITIVE_MOTION_CURVE_THICK |
|
||||
PRIMITIVE_MOTION_CURVE_RIBBON | PRIMITIVE_MOTION_POINT),
|
||||
PRIMITIVE_ALL = (PRIMITIVE_ALL_TRIANGLE | PRIMITIVE_ALL_CURVE | PRIMITIVE_ALL_VOLUME |
|
||||
PRIMITIVE_LAMP | PRIMITIVE_ALL_POINT),
|
||||
PRIMITIVE_MOTION = (1 << 6),
|
||||
PRIMITIVE_MOTION_TRIANGLE = (PRIMITIVE_TRIANGLE | PRIMITIVE_MOTION),
|
||||
PRIMITIVE_MOTION_CURVE_THICK = (PRIMITIVE_CURVE_THICK | PRIMITIVE_MOTION),
|
||||
PRIMITIVE_MOTION_CURVE_RIBBON = (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_MOTION),
|
||||
PRIMITIVE_MOTION_POINT = (PRIMITIVE_POINT | PRIMITIVE_MOTION),
|
||||
|
||||
PRIMITIVE_NUM = 10,
|
||||
PRIMITIVE_CURVE = (PRIMITIVE_CURVE_THICK | PRIMITIVE_CURVE_RIBBON),
|
||||
|
||||
PRIMITIVE_ALL = (PRIMITIVE_TRIANGLE | PRIMITIVE_CURVE | PRIMITIVE_POINT | PRIMITIVE_VOLUME |
|
||||
PRIMITIVE_LAMP | PRIMITIVE_MOTION),
|
||||
|
||||
PRIMITIVE_NUM_SHAPES = 6,
|
||||
PRIMITIVE_NUM_BITS = PRIMITIVE_NUM_SHAPES + 1, /* All shapes + motion bit. */
|
||||
PRIMITIVE_NUM = PRIMITIVE_NUM_SHAPES * 2, /* With and without motion. */
|
||||
} PrimitiveType;
|
||||
|
||||
#define PRIMITIVE_PACK_SEGMENT(type, segment) ((segment << PRIMITIVE_NUM) | (type))
|
||||
#define PRIMITIVE_UNPACK_SEGMENT(type) (type >> PRIMITIVE_NUM)
|
||||
/* Convert type to index in range 0..PRIMITIVE_NUM-1. */
|
||||
#define PRIMITIVE_INDEX(type) (bitscan((uint32_t)(type)) * 2 + (((type)&PRIMITIVE_MOTION) ? 1 : 0))
|
||||
|
||||
/* Pack segment into type value to save space. */
|
||||
#define PRIMITIVE_PACK_SEGMENT(type, segment) ((segment << PRIMITIVE_NUM_BITS) | (type))
|
||||
#define PRIMITIVE_UNPACK_SEGMENT(type) (type >> PRIMITIVE_NUM_BITS)
|
||||
|
||||
typedef enum CurveShapeType {
|
||||
CURVE_RIBBON = 0,
|
||||
|
@@ -1370,22 +1370,22 @@ enum {
|
||||
DEVICE_MESH_DATA_MODIFIED = (1 << 1),
|
||||
DEVICE_POINT_DATA_MODIFIED = (1 << 2),
|
||||
|
||||
ATTR_FLOAT_MODIFIED = (1 << 2),
|
||||
ATTR_FLOAT2_MODIFIED = (1 << 3),
|
||||
ATTR_FLOAT3_MODIFIED = (1 << 4),
|
||||
ATTR_FLOAT4_MODIFIED = (1 << 5),
|
||||
ATTR_UCHAR4_MODIFIED = (1 << 6),
|
||||
ATTR_FLOAT_MODIFIED = (1 << 3),
|
||||
ATTR_FLOAT2_MODIFIED = (1 << 4),
|
||||
ATTR_FLOAT3_MODIFIED = (1 << 5),
|
||||
ATTR_FLOAT4_MODIFIED = (1 << 6),
|
||||
ATTR_UCHAR4_MODIFIED = (1 << 7),
|
||||
|
||||
CURVE_DATA_NEED_REALLOC = (1 << 7),
|
||||
MESH_DATA_NEED_REALLOC = (1 << 8),
|
||||
POINT_DATA_NEED_REALLOC = (1 << 9),
|
||||
CURVE_DATA_NEED_REALLOC = (1 << 8),
|
||||
MESH_DATA_NEED_REALLOC = (1 << 9),
|
||||
POINT_DATA_NEED_REALLOC = (1 << 10),
|
||||
|
||||
ATTR_FLOAT_NEEDS_REALLOC = (1 << 10),
|
||||
ATTR_FLOAT2_NEEDS_REALLOC = (1 << 11),
|
||||
ATTR_FLOAT3_NEEDS_REALLOC = (1 << 12),
|
||||
ATTR_FLOAT4_NEEDS_REALLOC = (1 << 13),
|
||||
ATTR_FLOAT_NEEDS_REALLOC = (1 << 11),
|
||||
ATTR_FLOAT2_NEEDS_REALLOC = (1 << 12),
|
||||
ATTR_FLOAT3_NEEDS_REALLOC = (1 << 13),
|
||||
ATTR_FLOAT4_NEEDS_REALLOC = (1 << 14),
|
||||
|
||||
ATTR_UCHAR4_NEEDS_REALLOC = (1 << 14),
|
||||
ATTR_UCHAR4_NEEDS_REALLOC = (1 << 15),
|
||||
|
||||
ATTRS_NEED_REALLOC = (ATTR_FLOAT_NEEDS_REALLOC | ATTR_FLOAT2_NEEDS_REALLOC |
|
||||
ATTR_FLOAT3_NEEDS_REALLOC | ATTR_FLOAT4_NEEDS_REALLOC |
|
||||
|
@@ -259,6 +259,50 @@ void MEM_use_guarded_allocator(void);
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
# include <new>
|
||||
# include <type_traits>
|
||||
# include <utility>
|
||||
|
||||
/**
|
||||
* Allocate new memory for and constructs an object of type #T.
|
||||
* #MEM_delete should be used to delete the object. Just calling #MEM_freeN is not enough when #T
|
||||
* is not a trivial type.
|
||||
*/
|
||||
template<typename T, typename... Args>
|
||||
inline T *MEM_new(const char *allocation_name, Args &&...args)
|
||||
{
|
||||
void *buffer = MEM_mallocN(sizeof(T), allocation_name);
|
||||
return new (buffer) T(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates zero-initialized memory for an object of type #T. The constructor of #T is not called,
|
||||
* therefor this should only used with trivial types (like all C types).
|
||||
* It's valid to call #MEM_freeN on a pointer returned by this, because a destructor call is not
|
||||
* necessary, because the type is trivial.
|
||||
*/
|
||||
template<typename T> inline T *MEM_cnew(const char *allocation_name)
|
||||
{
|
||||
static_assert(std::is_trivial_v<T>, "For non-trivial types, MEM_new should be used.");
|
||||
return static_cast<T *>(MEM_callocN(sizeof(T), allocation_name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructs and deallocates an object previously allocated with any `MEM_*` function.
|
||||
* Passing in null does nothing.
|
||||
*/
|
||||
template<typename T> inline void MEM_delete(const T *ptr)
|
||||
{
|
||||
if (ptr == nullptr) {
|
||||
/* Support #ptr being null, because C++ `delete` supports that as well. */
|
||||
return;
|
||||
}
|
||||
/* C++ allows destruction of const objects, so the pointer is allowed to be const. */
|
||||
ptr->~T();
|
||||
MEM_freeN(const_cast<T *>(ptr));
|
||||
}
|
||||
|
||||
/* Allocation functions (for C++ only). */
|
||||
# define MEM_CXX_CLASS_ALLOC_FUNCS(_id) \
|
||||
public: \
|
||||
@@ -292,36 +336,6 @@ void MEM_use_guarded_allocator(void);
|
||||
{ \
|
||||
}
|
||||
|
||||
/* Needed when type includes a namespace, then the namespace should not be
|
||||
* specified after ~, so using a macro fails. */
|
||||
template<class T> inline void OBJECT_GUARDED_DESTRUCTOR(T *what)
|
||||
{
|
||||
what->~T();
|
||||
}
|
||||
|
||||
# if defined __GNUC__
|
||||
# define OBJECT_GUARDED_NEW(type, args...) new (MEM_mallocN(sizeof(type), __func__)) type(args)
|
||||
# else
|
||||
# define OBJECT_GUARDED_NEW(type, ...) \
|
||||
new (MEM_mallocN(sizeof(type), __FUNCTION__)) type(__VA_ARGS__)
|
||||
# endif
|
||||
# define OBJECT_GUARDED_DELETE(what, type) \
|
||||
{ \
|
||||
if (what) { \
|
||||
OBJECT_GUARDED_DESTRUCTOR((type *)what); \
|
||||
MEM_freeN(what); \
|
||||
} \
|
||||
} \
|
||||
(void)0
|
||||
# define OBJECT_GUARDED_SAFE_DELETE(what, type) \
|
||||
{ \
|
||||
if (what) { \
|
||||
OBJECT_GUARDED_DESTRUCTOR((type *)what); \
|
||||
MEM_freeN(what); \
|
||||
what = NULL; \
|
||||
} \
|
||||
} \
|
||||
(void)0
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __MEM_GUARDEDALLOC_H__ */
|
||||
|
@@ -27,9 +27,21 @@
|
||||
|
||||
#ifdef WITH_LIBMV_GUARDED_ALLOC
|
||||
# include "MEM_guardedalloc.h"
|
||||
# define LIBMV_OBJECT_NEW OBJECT_GUARDED_NEW
|
||||
# define LIBMV_OBJECT_DELETE OBJECT_GUARDED_DELETE
|
||||
# define LIBMV_OBJECT_DELETE OBJECT_GUARDED_DELETE
|
||||
# if defined __GNUC__
|
||||
# define LIBMV_OBJECT_NEW(type, args...) \
|
||||
new (MEM_mallocN(sizeof(type), __func__)) type(args)
|
||||
# else
|
||||
# define LIBMV_OBJECT_NEW(type, ...) \
|
||||
new (MEM_mallocN(sizeof(type), __FUNCTION__)) type(__VA_ARGS__)
|
||||
# endif
|
||||
# define LIBMV_OBJECT_DELETE(what, type) \
|
||||
{ \
|
||||
if (what) { \
|
||||
((type*)what)->~type(); \
|
||||
MEM_freeN(what); \
|
||||
} \
|
||||
} \
|
||||
(void)0
|
||||
# define LIBMV_STRUCT_NEW(type, count) \
|
||||
(type*)MEM_mallocN(sizeof(type) * count, __func__)
|
||||
# define LIBMV_STRUCT_DELETE(what) MEM_freeN(what)
|
||||
|
@@ -485,8 +485,8 @@ OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(float *data,
|
||||
long xStrideBytes,
|
||||
long yStrideBytes)
|
||||
{
|
||||
OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription *)MEM_callocN(
|
||||
sizeof(OCIO_PackedImageDescription), "OCIO_PackedImageDescription");
|
||||
OCIO_PackedImageDescription *desc = MEM_cnew<OCIO_PackedImageDescription>(
|
||||
"OCIO_PackedImageDescription");
|
||||
desc->data = data;
|
||||
desc->width = width;
|
||||
desc->height = height;
|
||||
|
@@ -67,7 +67,7 @@ static void OCIO_reportException(Exception &exception)
|
||||
|
||||
OCIO_ConstConfigRcPtr *OCIOImpl::getCurrentConfig(void)
|
||||
{
|
||||
ConstConfigRcPtr *config = OBJECT_GUARDED_NEW(ConstConfigRcPtr);
|
||||
ConstConfigRcPtr *config = MEM_new<ConstConfigRcPtr>(__func__);
|
||||
|
||||
try {
|
||||
*config = GetCurrentConfig();
|
||||
@@ -79,7 +79,7 @@ OCIO_ConstConfigRcPtr *OCIOImpl::getCurrentConfig(void)
|
||||
OCIO_reportException(exception);
|
||||
}
|
||||
|
||||
OBJECT_GUARDED_DELETE(config, ConstConfigRcPtr);
|
||||
MEM_delete(config);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -96,7 +96,7 @@ void OCIOImpl::setCurrentConfig(const OCIO_ConstConfigRcPtr *config)
|
||||
|
||||
OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromEnv(void)
|
||||
{
|
||||
ConstConfigRcPtr *config = OBJECT_GUARDED_NEW(ConstConfigRcPtr);
|
||||
ConstConfigRcPtr *config = MEM_new<ConstConfigRcPtr>(__func__);
|
||||
|
||||
try {
|
||||
*config = Config::CreateFromEnv();
|
||||
@@ -108,14 +108,14 @@ OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromEnv(void)
|
||||
OCIO_reportException(exception);
|
||||
}
|
||||
|
||||
OBJECT_GUARDED_DELETE(config, ConstConfigRcPtr);
|
||||
MEM_delete(config);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromFile(const char *filename)
|
||||
{
|
||||
ConstConfigRcPtr *config = OBJECT_GUARDED_NEW(ConstConfigRcPtr);
|
||||
ConstConfigRcPtr *config = MEM_new<ConstConfigRcPtr>(__func__);
|
||||
|
||||
try {
|
||||
*config = Config::CreateFromFile(filename);
|
||||
@@ -127,14 +127,14 @@ OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromFile(const char *filename)
|
||||
OCIO_reportException(exception);
|
||||
}
|
||||
|
||||
OBJECT_GUARDED_DELETE(config, ConstConfigRcPtr);
|
||||
MEM_delete(config);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void OCIOImpl::configRelease(OCIO_ConstConfigRcPtr *config)
|
||||
{
|
||||
OBJECT_GUARDED_DELETE((ConstConfigRcPtr *)config, ConstConfigRcPtr);
|
||||
MEM_delete((ConstConfigRcPtr *)config);
|
||||
}
|
||||
|
||||
int OCIOImpl::configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config)
|
||||
@@ -164,7 +164,7 @@ const char *OCIOImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *conf
|
||||
OCIO_ConstColorSpaceRcPtr *OCIOImpl::configGetColorSpace(OCIO_ConstConfigRcPtr *config,
|
||||
const char *name)
|
||||
{
|
||||
ConstColorSpaceRcPtr *cs = OBJECT_GUARDED_NEW(ConstColorSpaceRcPtr);
|
||||
ConstColorSpaceRcPtr *cs = MEM_new<ConstColorSpaceRcPtr>(__func__);
|
||||
|
||||
try {
|
||||
*cs = (*(ConstConfigRcPtr *)config)->getColorSpace(name);
|
||||
@@ -176,7 +176,7 @@ OCIO_ConstColorSpaceRcPtr *OCIOImpl::configGetColorSpace(OCIO_ConstConfigRcPtr *
|
||||
OCIO_reportException(exception);
|
||||
}
|
||||
|
||||
OBJECT_GUARDED_DELETE(cs, ConstColorSpaceRcPtr);
|
||||
MEM_delete(cs);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -380,7 +380,7 @@ const char *OCIOImpl::configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, in
|
||||
|
||||
OCIO_ConstLookRcPtr *OCIOImpl::configGetLook(OCIO_ConstConfigRcPtr *config, const char *name)
|
||||
{
|
||||
ConstLookRcPtr *look = OBJECT_GUARDED_NEW(ConstLookRcPtr);
|
||||
ConstLookRcPtr *look = MEM_new<ConstLookRcPtr>(__func__);
|
||||
|
||||
try {
|
||||
*look = (*(ConstConfigRcPtr *)config)->getLook(name);
|
||||
@@ -392,7 +392,7 @@ OCIO_ConstLookRcPtr *OCIOImpl::configGetLook(OCIO_ConstConfigRcPtr *config, cons
|
||||
OCIO_reportException(exception);
|
||||
}
|
||||
|
||||
OBJECT_GUARDED_DELETE(look, ConstLookRcPtr);
|
||||
MEM_delete(look);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -404,7 +404,7 @@ const char *OCIOImpl::lookGetProcessSpace(OCIO_ConstLookRcPtr *look)
|
||||
|
||||
void OCIOImpl::lookRelease(OCIO_ConstLookRcPtr *look)
|
||||
{
|
||||
OBJECT_GUARDED_DELETE((ConstLookRcPtr *)look, ConstLookRcPtr);
|
||||
MEM_delete((ConstLookRcPtr *)look);
|
||||
}
|
||||
|
||||
int OCIOImpl::colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs_)
|
||||
@@ -521,14 +521,14 @@ void OCIOImpl::colorSpaceIsBuiltin(OCIO_ConstConfigRcPtr *config_,
|
||||
|
||||
void OCIOImpl::colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs)
|
||||
{
|
||||
OBJECT_GUARDED_DELETE((ConstColorSpaceRcPtr *)cs, ConstColorSpaceRcPtr);
|
||||
MEM_delete((ConstColorSpaceRcPtr *)cs);
|
||||
}
|
||||
|
||||
OCIO_ConstProcessorRcPtr *OCIOImpl::configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config,
|
||||
const char *srcName,
|
||||
const char *dstName)
|
||||
{
|
||||
ConstProcessorRcPtr *processor = OBJECT_GUARDED_NEW(ConstProcessorRcPtr);
|
||||
ConstProcessorRcPtr *processor = MEM_new<ConstProcessorRcPtr>(__func__);
|
||||
|
||||
try {
|
||||
*processor = (*(ConstConfigRcPtr *)config)->getProcessor(srcName, dstName);
|
||||
@@ -540,20 +540,20 @@ OCIO_ConstProcessorRcPtr *OCIOImpl::configGetProcessorWithNames(OCIO_ConstConfig
|
||||
OCIO_reportException(exception);
|
||||
}
|
||||
|
||||
OBJECT_GUARDED_DELETE(processor, ConstProcessorRcPtr);
|
||||
MEM_delete(processor);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OCIOImpl::processorRelease(OCIO_ConstProcessorRcPtr *processor)
|
||||
{
|
||||
OBJECT_GUARDED_DELETE(processor, ConstProcessorRcPtr);
|
||||
MEM_delete(processor);
|
||||
}
|
||||
|
||||
OCIO_ConstCPUProcessorRcPtr *OCIOImpl::processorGetCPUProcessor(
|
||||
OCIO_ConstProcessorRcPtr *processor)
|
||||
{
|
||||
ConstCPUProcessorRcPtr *cpu_processor = OBJECT_GUARDED_NEW(ConstCPUProcessorRcPtr);
|
||||
ConstCPUProcessorRcPtr *cpu_processor = MEM_new<ConstCPUProcessorRcPtr>(__func__);
|
||||
*cpu_processor = (*(ConstProcessorRcPtr *)processor)->getDefaultCPUProcessor();
|
||||
return (OCIO_ConstCPUProcessorRcPtr *)cpu_processor;
|
||||
}
|
||||
@@ -636,7 +636,7 @@ void OCIOImpl::cpuProcessorApplyRGBA_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_
|
||||
|
||||
void OCIOImpl::cpuProcessorRelease(OCIO_ConstCPUProcessorRcPtr *cpu_processor)
|
||||
{
|
||||
OBJECT_GUARDED_DELETE(cpu_processor, ConstCPUProcessorRcPtr);
|
||||
MEM_delete(cpu_processor);
|
||||
}
|
||||
|
||||
const char *OCIOImpl::colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs)
|
||||
@@ -725,7 +725,7 @@ OCIO_ConstProcessorRcPtr *OCIOImpl::createDisplayProcessor(OCIO_ConstConfigRcPtr
|
||||
|
||||
/* Create processor from transform. This is the moment were OCIO validates
|
||||
* the entire transform, no need to check for the validity of inputs above. */
|
||||
ConstProcessorRcPtr *p = OBJECT_GUARDED_NEW(ConstProcessorRcPtr);
|
||||
ConstProcessorRcPtr *p = MEM_new<ConstProcessorRcPtr>(__func__);
|
||||
|
||||
try {
|
||||
*p = config->getProcessor(group);
|
||||
@@ -737,7 +737,7 @@ OCIO_ConstProcessorRcPtr *OCIOImpl::createDisplayProcessor(OCIO_ConstConfigRcPtr
|
||||
OCIO_reportException(exception);
|
||||
}
|
||||
|
||||
OBJECT_GUARDED_DELETE(p, ConstProcessorRcPtr);
|
||||
MEM_delete(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -771,7 +771,7 @@ OCIO_PackedImageDesc *OCIOImpl::createOCIO_PackedImageDesc(float *data,
|
||||
|
||||
void OCIOImpl::OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *id)
|
||||
{
|
||||
OBJECT_GUARDED_DELETE((PackedImageDesc *)id, PackedImageDesc);
|
||||
MEM_delete((PackedImageDesc *)id);
|
||||
}
|
||||
|
||||
const char *OCIOImpl::getVersionString(void)
|
||||
|
@@ -72,9 +72,20 @@ if(WITH_OPENSUBDIV)
|
||||
internal/device/device_context_openmp.h
|
||||
|
||||
# Evaluator.
|
||||
internal/evaluator/eval_output.cc
|
||||
internal/evaluator/eval_output.h
|
||||
internal/evaluator/eval_output_cpu.cc
|
||||
internal/evaluator/eval_output_cpu.h
|
||||
internal/evaluator/eval_output_gpu.cc
|
||||
internal/evaluator/eval_output_gpu.h
|
||||
internal/evaluator/evaluator_cache_impl.cc
|
||||
internal/evaluator/evaluator_cache_impl.h
|
||||
internal/evaluator/evaluator_capi.cc
|
||||
internal/evaluator/evaluator_impl.cc
|
||||
internal/evaluator/evaluator_impl.h
|
||||
internal/evaluator/patch_map.cc
|
||||
internal/evaluator/patch_map.h
|
||||
|
||||
|
||||
# Topology.
|
||||
internal/topology/mesh_topology.cc
|
||||
|
35
intern/opensubdiv/internal/evaluator/eval_output.cc
Normal file
35
intern/opensubdiv/internal/evaluator/eval_output.cc
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright 2021 Blender Foundation. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// Author: Sergey Sharybin
|
||||
|
||||
#include "internal/evaluator/eval_output.h"
|
||||
|
||||
namespace blender {
|
||||
namespace opensubdiv {
|
||||
|
||||
bool is_adaptive(CpuPatchTable *patch_table)
|
||||
{
|
||||
return patch_table->GetPatchArrayBuffer()[0].GetDescriptor().IsAdaptive();
|
||||
}
|
||||
|
||||
bool is_adaptive(GLPatchTable *patch_table)
|
||||
{
|
||||
return patch_table->GetPatchArrays()[0].GetDescriptor().IsAdaptive();
|
||||
}
|
||||
|
||||
} // namespace opensubdiv
|
||||
} // namespace blender
|
582
intern/opensubdiv/internal/evaluator/eval_output.h
Normal file
582
intern/opensubdiv/internal/evaluator/eval_output.h
Normal file
@@ -0,0 +1,582 @@
|
||||
// Copyright 2021 Blender Foundation. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// Author: Sergey Sharybin
|
||||
|
||||
#ifndef OPENSUBDIV_EVAL_OUTPUT_H_
|
||||
#define OPENSUBDIV_EVAL_OUTPUT_H_
|
||||
|
||||
#include <opensubdiv/osd/cpuPatchTable.h>
|
||||
#include <opensubdiv/osd/glPatchTable.h>
|
||||
#include <opensubdiv/osd/mesh.h>
|
||||
#include <opensubdiv/osd/types.h>
|
||||
|
||||
#include "internal/base/type.h"
|
||||
#include "internal/evaluator/evaluator_impl.h"
|
||||
|
||||
using OpenSubdiv::Far::PatchTable;
|
||||
using OpenSubdiv::Far::StencilTable;
|
||||
using OpenSubdiv::Osd::BufferDescriptor;
|
||||
using OpenSubdiv::Osd::CpuPatchTable;
|
||||
using OpenSubdiv::Osd::GLPatchTable;
|
||||
using OpenSubdiv::Osd::PatchCoord;
|
||||
|
||||
namespace blender {
|
||||
namespace opensubdiv {
|
||||
|
||||
// Base class for the implementation of the evaluators.
|
||||
class EvalOutputAPI::EvalOutput {
|
||||
public:
|
||||
virtual ~EvalOutput() = default;
|
||||
|
||||
virtual void updateData(const float *src, int start_vertex, int num_vertices) = 0;
|
||||
|
||||
virtual void updateVaryingData(const float *src, int start_vertex, int num_vertices) = 0;
|
||||
|
||||
virtual void updateFaceVaryingData(const int face_varying_channel,
|
||||
const float *src,
|
||||
int start_vertex,
|
||||
int num_vertices) = 0;
|
||||
|
||||
virtual void refine() = 0;
|
||||
|
||||
// NOTE: P must point to a memory of at least float[3]*num_patch_coords.
|
||||
virtual void evalPatches(const PatchCoord *patch_coord,
|
||||
const int num_patch_coords,
|
||||
float *P) = 0;
|
||||
|
||||
// NOTE: P, dPdu, dPdv must point to a memory of at least float[3]*num_patch_coords.
|
||||
virtual void evalPatchesWithDerivatives(const PatchCoord *patch_coord,
|
||||
const int num_patch_coords,
|
||||
float *P,
|
||||
float *dPdu,
|
||||
float *dPdv) = 0;
|
||||
|
||||
// NOTE: varying must point to a memory of at least float[3]*num_patch_coords.
|
||||
virtual void evalPatchesVarying(const PatchCoord *patch_coord,
|
||||
const int num_patch_coords,
|
||||
float *varying) = 0;
|
||||
|
||||
virtual void evalPatchesFaceVarying(const int face_varying_channel,
|
||||
const PatchCoord *patch_coord,
|
||||
const int num_patch_coords,
|
||||
float face_varying[2]) = 0;
|
||||
|
||||
// The following interfaces are dependant on the actual evaluator type (CPU, OpenGL, etc.) which
|
||||
// have slightly different APIs to access patch arrays, as well as different types for their
|
||||
// data structure. They need to be overridden in the specific instances of the EvalOutput derived
|
||||
// classes if needed, while the interfaces above are overriden through VolatileEvalOutput.
|
||||
|
||||
virtual void fillPatchArraysBuffer(OpenSubdiv_Buffer * /*patch_arrays_buffer*/)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void wrapPatchIndexBuffer(OpenSubdiv_Buffer * /*patch_index_buffer*/)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void wrapPatchParamBuffer(OpenSubdiv_Buffer * /*patch_param_buffer*/)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void wrapSrcBuffer(OpenSubdiv_Buffer * /*src_buffer*/)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void fillFVarPatchArraysBuffer(const int /*face_varying_channel*/,
|
||||
OpenSubdiv_Buffer * /*patch_arrays_buffer*/)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void wrapFVarPatchIndexBuffer(const int /*face_varying_channel*/,
|
||||
OpenSubdiv_Buffer * /*patch_index_buffer*/)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void wrapFVarPatchParamBuffer(const int /*face_varying_channel*/,
|
||||
OpenSubdiv_Buffer * /*patch_param_buffer*/)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void wrapFVarSrcBuffer(const int /*face_varying_channel*/,
|
||||
OpenSubdiv_Buffer * /*src_buffer*/)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
// Buffer which implements API required by OpenSubdiv and uses an existing memory as an underlying
|
||||
// storage.
|
||||
template<typename T> class RawDataWrapperBuffer {
|
||||
public:
|
||||
RawDataWrapperBuffer(T *data) : data_(data)
|
||||
{
|
||||
}
|
||||
|
||||
T *BindCpuBuffer()
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
|
||||
int BindVBO()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO(sergey): Support UpdateData().
|
||||
|
||||
protected:
|
||||
T *data_;
|
||||
};
|
||||
|
||||
template<typename T> class RawDataWrapperVertexBuffer : public RawDataWrapperBuffer<T> {
|
||||
public:
|
||||
RawDataWrapperVertexBuffer(T *data, int num_vertices)
|
||||
: RawDataWrapperBuffer<T>(data), num_vertices_(num_vertices)
|
||||
{
|
||||
}
|
||||
|
||||
int GetNumVertices()
|
||||
{
|
||||
return num_vertices_;
|
||||
}
|
||||
|
||||
protected:
|
||||
int num_vertices_;
|
||||
};
|
||||
|
||||
class ConstPatchCoordWrapperBuffer : public RawDataWrapperVertexBuffer<const PatchCoord> {
|
||||
public:
|
||||
ConstPatchCoordWrapperBuffer(const PatchCoord *data, int num_vertices)
|
||||
: RawDataWrapperVertexBuffer(data, num_vertices)
|
||||
{
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
// Discriminators used in FaceVaryingVolatileEval in order to detect whether we are using adaptive
|
||||
// patches as the CPU and OpenGL PatchTable have different APIs.
|
||||
bool is_adaptive(CpuPatchTable *patch_table);
|
||||
bool is_adaptive(GLPatchTable *patch_table);
|
||||
|
||||
template<typename EVAL_VERTEX_BUFFER,
|
||||
typename STENCIL_TABLE,
|
||||
typename PATCH_TABLE,
|
||||
typename EVALUATOR,
|
||||
typename DEVICE_CONTEXT = void>
|
||||
class FaceVaryingVolatileEval {
|
||||
public:
|
||||
typedef OpenSubdiv::Osd::EvaluatorCacheT<EVALUATOR> EvaluatorCache;
|
||||
|
||||
FaceVaryingVolatileEval(int face_varying_channel,
|
||||
const StencilTable *face_varying_stencils,
|
||||
int face_varying_width,
|
||||
PATCH_TABLE *patch_table,
|
||||
EvaluatorCache *evaluator_cache = NULL,
|
||||
DEVICE_CONTEXT *device_context = NULL)
|
||||
: face_varying_channel_(face_varying_channel),
|
||||
src_face_varying_desc_(0, face_varying_width, face_varying_width),
|
||||
patch_table_(patch_table),
|
||||
evaluator_cache_(evaluator_cache),
|
||||
device_context_(device_context)
|
||||
{
|
||||
using OpenSubdiv::Osd::convertToCompatibleStencilTable;
|
||||
num_coarse_face_varying_vertices_ = face_varying_stencils->GetNumControlVertices();
|
||||
const int num_total_face_varying_vertices = face_varying_stencils->GetNumControlVertices() +
|
||||
face_varying_stencils->GetNumStencils();
|
||||
src_face_varying_data_ = EVAL_VERTEX_BUFFER::Create(
|
||||
2, num_total_face_varying_vertices, device_context);
|
||||
face_varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(face_varying_stencils,
|
||||
device_context_);
|
||||
}
|
||||
|
||||
~FaceVaryingVolatileEval()
|
||||
{
|
||||
delete src_face_varying_data_;
|
||||
delete face_varying_stencils_;
|
||||
}
|
||||
|
||||
void updateData(const float *src, int start_vertex, int num_vertices)
|
||||
{
|
||||
src_face_varying_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
|
||||
}
|
||||
|
||||
void refine()
|
||||
{
|
||||
BufferDescriptor dst_face_varying_desc = src_face_varying_desc_;
|
||||
dst_face_varying_desc.offset += num_coarse_face_varying_vertices_ *
|
||||
src_face_varying_desc_.stride;
|
||||
const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
|
||||
evaluator_cache_, src_face_varying_desc_, dst_face_varying_desc, device_context_);
|
||||
// in and out points to same buffer so output is put directly after coarse vertices, needed in
|
||||
// adaptive mode
|
||||
EVALUATOR::EvalStencils(src_face_varying_data_,
|
||||
src_face_varying_desc_,
|
||||
src_face_varying_data_,
|
||||
dst_face_varying_desc,
|
||||
face_varying_stencils_,
|
||||
eval_instance,
|
||||
device_context_);
|
||||
}
|
||||
|
||||
// NOTE: face_varying must point to a memory of at least float[2]*num_patch_coords.
|
||||
void evalPatches(const PatchCoord *patch_coord, const int num_patch_coords, float *face_varying)
|
||||
{
|
||||
RawDataWrapperBuffer<float> face_varying_data(face_varying);
|
||||
BufferDescriptor face_varying_desc(0, 2, 2);
|
||||
ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
|
||||
const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
|
||||
evaluator_cache_, src_face_varying_desc_, face_varying_desc, device_context_);
|
||||
|
||||
BufferDescriptor src_desc = get_src_varying_desc();
|
||||
|
||||
EVALUATOR::EvalPatchesFaceVarying(src_face_varying_data_,
|
||||
src_desc,
|
||||
&face_varying_data,
|
||||
face_varying_desc,
|
||||
patch_coord_buffer.GetNumVertices(),
|
||||
&patch_coord_buffer,
|
||||
patch_table_,
|
||||
face_varying_channel_,
|
||||
eval_instance,
|
||||
device_context_);
|
||||
}
|
||||
|
||||
EVAL_VERTEX_BUFFER *getSrcBuffer() const
|
||||
{
|
||||
return src_face_varying_data_;
|
||||
}
|
||||
|
||||
int getFVarSrcBufferOffset() const
|
||||
{
|
||||
BufferDescriptor src_desc = get_src_varying_desc();
|
||||
return src_desc.offset;
|
||||
}
|
||||
|
||||
PATCH_TABLE *getPatchTable() const
|
||||
{
|
||||
return patch_table_;
|
||||
}
|
||||
|
||||
private:
|
||||
BufferDescriptor get_src_varying_desc() const
|
||||
{
|
||||
// src_face_varying_data_ always contains coarse vertices at the beginning.
|
||||
// In adaptive mode they are followed by number of blocks for intermediate
|
||||
// subdivision levels, and this is what OSD expects in this mode.
|
||||
// In non-adaptive mode (generateIntermediateLevels == false),
|
||||
// they are followed by max subdivision level, but they break interpolation as OSD
|
||||
// expects only one subd level in this buffer.
|
||||
// So in non-adaptive mode we put offset into buffer descriptor to skip over coarse vertices.
|
||||
BufferDescriptor src_desc = src_face_varying_desc_;
|
||||
if (!is_adaptive(patch_table_)) {
|
||||
src_desc.offset += num_coarse_face_varying_vertices_ * src_face_varying_desc_.stride;
|
||||
}
|
||||
return src_desc;
|
||||
}
|
||||
|
||||
protected:
|
||||
int face_varying_channel_;
|
||||
|
||||
BufferDescriptor src_face_varying_desc_;
|
||||
|
||||
int num_coarse_face_varying_vertices_;
|
||||
EVAL_VERTEX_BUFFER *src_face_varying_data_;
|
||||
const STENCIL_TABLE *face_varying_stencils_;
|
||||
|
||||
// NOTE: We reference this, do not own it.
|
||||
PATCH_TABLE *patch_table_;
|
||||
|
||||
EvaluatorCache *evaluator_cache_;
|
||||
DEVICE_CONTEXT *device_context_;
|
||||
};
|
||||
|
||||
// Volatile evaluator which can be used from threads.
|
||||
//
|
||||
// TODO(sergey): Make it possible to evaluate coordinates in chunks.
|
||||
// TODO(sergey): Make it possible to evaluate multiple face varying layers.
|
||||
// (or maybe, it's cheap to create new evaluator for existing
|
||||
// topology to evaluate all needed face varying layers?)
|
||||
template<typename SRC_VERTEX_BUFFER,
|
||||
typename EVAL_VERTEX_BUFFER,
|
||||
typename STENCIL_TABLE,
|
||||
typename PATCH_TABLE,
|
||||
typename EVALUATOR,
|
||||
typename DEVICE_CONTEXT = void>
|
||||
class VolatileEvalOutput : public EvalOutputAPI::EvalOutput {
|
||||
public:
|
||||
typedef OpenSubdiv::Osd::EvaluatorCacheT<EVALUATOR> EvaluatorCache;
|
||||
typedef FaceVaryingVolatileEval<EVAL_VERTEX_BUFFER,
|
||||
STENCIL_TABLE,
|
||||
PATCH_TABLE,
|
||||
EVALUATOR,
|
||||
DEVICE_CONTEXT>
|
||||
FaceVaryingEval;
|
||||
|
||||
VolatileEvalOutput(const StencilTable *vertex_stencils,
|
||||
const StencilTable *varying_stencils,
|
||||
const vector<const StencilTable *> &all_face_varying_stencils,
|
||||
const int face_varying_width,
|
||||
const PatchTable *patch_table,
|
||||
EvaluatorCache *evaluator_cache = NULL,
|
||||
DEVICE_CONTEXT *device_context = NULL)
|
||||
: src_desc_(0, 3, 3),
|
||||
src_varying_desc_(0, 3, 3),
|
||||
face_varying_width_(face_varying_width),
|
||||
evaluator_cache_(evaluator_cache),
|
||||
device_context_(device_context)
|
||||
{
|
||||
// Total number of vertices = coarse points + refined points + local points.
|
||||
int num_total_vertices = vertex_stencils->GetNumControlVertices() +
|
||||
vertex_stencils->GetNumStencils();
|
||||
num_coarse_vertices_ = vertex_stencils->GetNumControlVertices();
|
||||
using OpenSubdiv::Osd::convertToCompatibleStencilTable;
|
||||
src_data_ = SRC_VERTEX_BUFFER::Create(3, num_total_vertices, device_context_);
|
||||
src_varying_data_ = SRC_VERTEX_BUFFER::Create(3, num_total_vertices, device_context_);
|
||||
patch_table_ = PATCH_TABLE::Create(patch_table, device_context_);
|
||||
vertex_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(vertex_stencils,
|
||||
device_context_);
|
||||
varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(varying_stencils,
|
||||
device_context_);
|
||||
// Create evaluators for every face varying channel.
|
||||
face_varying_evaluators.reserve(all_face_varying_stencils.size());
|
||||
int face_varying_channel = 0;
|
||||
for (const StencilTable *face_varying_stencils : all_face_varying_stencils) {
|
||||
face_varying_evaluators.push_back(new FaceVaryingEval(face_varying_channel,
|
||||
face_varying_stencils,
|
||||
face_varying_width,
|
||||
patch_table_,
|
||||
evaluator_cache_,
|
||||
device_context_));
|
||||
++face_varying_channel;
|
||||
}
|
||||
}
|
||||
|
||||
~VolatileEvalOutput() override
|
||||
{
|
||||
delete src_data_;
|
||||
delete src_varying_data_;
|
||||
delete patch_table_;
|
||||
delete vertex_stencils_;
|
||||
delete varying_stencils_;
|
||||
for (FaceVaryingEval *face_varying_evaluator : face_varying_evaluators) {
|
||||
delete face_varying_evaluator;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(sergey): Implement binding API.
|
||||
|
||||
void updateData(const float *src, int start_vertex, int num_vertices) override
|
||||
{
|
||||
src_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
|
||||
}
|
||||
|
||||
void updateVaryingData(const float *src, int start_vertex, int num_vertices) override
|
||||
{
|
||||
src_varying_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
|
||||
}
|
||||
|
||||
void updateFaceVaryingData(const int face_varying_channel,
|
||||
const float *src,
|
||||
int start_vertex,
|
||||
int num_vertices) override
|
||||
{
|
||||
assert(face_varying_channel >= 0);
|
||||
assert(face_varying_channel < face_varying_evaluators.size());
|
||||
face_varying_evaluators[face_varying_channel]->updateData(src, start_vertex, num_vertices);
|
||||
}
|
||||
|
||||
bool hasVaryingData() const
|
||||
{
|
||||
// return varying_stencils_ != NULL;
|
||||
// TODO(sergey): Check this based on actual topology.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hasFaceVaryingData() const
|
||||
{
|
||||
return face_varying_evaluators.size() != 0;
|
||||
}
|
||||
|
||||
void refine() override
|
||||
{
|
||||
// Evaluate vertex positions.
|
||||
BufferDescriptor dst_desc = src_desc_;
|
||||
dst_desc.offset += num_coarse_vertices_ * src_desc_.stride;
|
||||
const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
|
||||
evaluator_cache_, src_desc_, dst_desc, device_context_);
|
||||
EVALUATOR::EvalStencils(src_data_,
|
||||
src_desc_,
|
||||
src_data_,
|
||||
dst_desc,
|
||||
vertex_stencils_,
|
||||
eval_instance,
|
||||
device_context_);
|
||||
// Evaluate varying data.
|
||||
if (hasVaryingData()) {
|
||||
BufferDescriptor dst_varying_desc = src_varying_desc_;
|
||||
dst_varying_desc.offset += num_coarse_vertices_ * src_varying_desc_.stride;
|
||||
eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
|
||||
evaluator_cache_, src_varying_desc_, dst_varying_desc, device_context_);
|
||||
EVALUATOR::EvalStencils(src_varying_data_,
|
||||
src_varying_desc_,
|
||||
src_varying_data_,
|
||||
dst_varying_desc,
|
||||
varying_stencils_,
|
||||
eval_instance,
|
||||
device_context_);
|
||||
}
|
||||
// Evaluate face-varying data.
|
||||
if (hasFaceVaryingData()) {
|
||||
for (FaceVaryingEval *face_varying_evaluator : face_varying_evaluators) {
|
||||
face_varying_evaluator->refine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: P must point to a memory of at least float[3]*num_patch_coords.
|
||||
void evalPatches(const PatchCoord *patch_coord, const int num_patch_coords, float *P) override
|
||||
{
|
||||
RawDataWrapperBuffer<float> P_data(P);
|
||||
// TODO(sergey): Support interleaved vertex-varying data.
|
||||
BufferDescriptor P_desc(0, 3, 3);
|
||||
ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
|
||||
const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
|
||||
evaluator_cache_, src_desc_, P_desc, device_context_);
|
||||
EVALUATOR::EvalPatches(src_data_,
|
||||
src_desc_,
|
||||
&P_data,
|
||||
P_desc,
|
||||
patch_coord_buffer.GetNumVertices(),
|
||||
&patch_coord_buffer,
|
||||
patch_table_,
|
||||
eval_instance,
|
||||
device_context_);
|
||||
}
|
||||
|
||||
// NOTE: P, dPdu, dPdv must point to a memory of at least float[3]*num_patch_coords.
|
||||
void evalPatchesWithDerivatives(const PatchCoord *patch_coord,
|
||||
const int num_patch_coords,
|
||||
float *P,
|
||||
float *dPdu,
|
||||
float *dPdv) override
|
||||
{
|
||||
assert(dPdu);
|
||||
assert(dPdv);
|
||||
RawDataWrapperBuffer<float> P_data(P);
|
||||
RawDataWrapperBuffer<float> dPdu_data(dPdu), dPdv_data(dPdv);
|
||||
// TODO(sergey): Support interleaved vertex-varying data.
|
||||
BufferDescriptor P_desc(0, 3, 3);
|
||||
BufferDescriptor dpDu_desc(0, 3, 3), pPdv_desc(0, 3, 3);
|
||||
ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
|
||||
const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
|
||||
evaluator_cache_, src_desc_, P_desc, dpDu_desc, pPdv_desc, device_context_);
|
||||
EVALUATOR::EvalPatches(src_data_,
|
||||
src_desc_,
|
||||
&P_data,
|
||||
P_desc,
|
||||
&dPdu_data,
|
||||
dpDu_desc,
|
||||
&dPdv_data,
|
||||
pPdv_desc,
|
||||
patch_coord_buffer.GetNumVertices(),
|
||||
&patch_coord_buffer,
|
||||
patch_table_,
|
||||
eval_instance,
|
||||
device_context_);
|
||||
}
|
||||
|
||||
// NOTE: varying must point to a memory of at least float[3]*num_patch_coords.
|
||||
void evalPatchesVarying(const PatchCoord *patch_coord,
|
||||
const int num_patch_coords,
|
||||
float *varying) override
|
||||
{
|
||||
RawDataWrapperBuffer<float> varying_data(varying);
|
||||
BufferDescriptor varying_desc(3, 3, 6);
|
||||
ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
|
||||
const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
|
||||
evaluator_cache_, src_varying_desc_, varying_desc, device_context_);
|
||||
EVALUATOR::EvalPatchesVarying(src_varying_data_,
|
||||
src_varying_desc_,
|
||||
&varying_data,
|
||||
varying_desc,
|
||||
patch_coord_buffer.GetNumVertices(),
|
||||
&patch_coord_buffer,
|
||||
patch_table_,
|
||||
eval_instance,
|
||||
device_context_);
|
||||
}
|
||||
|
||||
void evalPatchesFaceVarying(const int face_varying_channel,
|
||||
const PatchCoord *patch_coord,
|
||||
const int num_patch_coords,
|
||||
float face_varying[2]) override
|
||||
{
|
||||
assert(face_varying_channel >= 0);
|
||||
assert(face_varying_channel < face_varying_evaluators.size());
|
||||
face_varying_evaluators[face_varying_channel]->evalPatches(
|
||||
patch_coord, num_patch_coords, face_varying);
|
||||
}
|
||||
|
||||
SRC_VERTEX_BUFFER *getSrcBuffer() const
|
||||
{
|
||||
return src_data_;
|
||||
}
|
||||
|
||||
PATCH_TABLE *getPatchTable() const
|
||||
{
|
||||
return patch_table_;
|
||||
}
|
||||
|
||||
SRC_VERTEX_BUFFER *getFVarSrcBuffer(const int face_varying_channel) const
|
||||
{
|
||||
return face_varying_evaluators[face_varying_channel]->getSrcBuffer();
|
||||
}
|
||||
|
||||
int getFVarSrcBufferOffset(const int face_varying_channel) const
|
||||
{
|
||||
return face_varying_evaluators[face_varying_channel]->getFVarSrcBufferOffset();
|
||||
}
|
||||
|
||||
PATCH_TABLE *getFVarPatchTable(const int face_varying_channel) const
|
||||
{
|
||||
return face_varying_evaluators[face_varying_channel]->getPatchTable();
|
||||
}
|
||||
|
||||
private:
|
||||
SRC_VERTEX_BUFFER *src_data_;
|
||||
SRC_VERTEX_BUFFER *src_varying_data_;
|
||||
PATCH_TABLE *patch_table_;
|
||||
BufferDescriptor src_desc_;
|
||||
BufferDescriptor src_varying_desc_;
|
||||
|
||||
int num_coarse_vertices_;
|
||||
|
||||
const STENCIL_TABLE *vertex_stencils_;
|
||||
const STENCIL_TABLE *varying_stencils_;
|
||||
|
||||
int face_varying_width_;
|
||||
vector<FaceVaryingEval *> face_varying_evaluators;
|
||||
|
||||
EvaluatorCache *evaluator_cache_;
|
||||
DEVICE_CONTEXT *device_context_;
|
||||
};
|
||||
|
||||
} // namespace opensubdiv
|
||||
} // namespace blender
|
||||
|
||||
#endif // OPENSUBDIV_EVAL_OUTPUT_H_
|
23
intern/opensubdiv/internal/evaluator/eval_output_cpu.cc
Normal file
23
intern/opensubdiv/internal/evaluator/eval_output_cpu.cc
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2021 Blender Foundation. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// Author: Sergey Sharybin
|
||||
|
||||
namespace blender {
|
||||
namespace opensubdiv {
|
||||
|
||||
}
|
||||
} // namespace blender
|
66
intern/opensubdiv/internal/evaluator/eval_output_cpu.h
Normal file
66
intern/opensubdiv/internal/evaluator/eval_output_cpu.h
Normal file
@@ -0,0 +1,66 @@
|
||||
// Copyright 2021 Blender Foundation. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// Author: Sergey Sharybin
|
||||
|
||||
#ifndef OPENSUBDIV_EVAL_OUTPUT_CPU_H_
|
||||
#define OPENSUBDIV_EVAL_OUTPUT_CPU_H_
|
||||
|
||||
#include "internal/evaluator/eval_output.h"
|
||||
|
||||
#include <opensubdiv/osd/cpuEvaluator.h>
|
||||
#include <opensubdiv/osd/cpuPatchTable.h>
|
||||
#include <opensubdiv/osd/cpuVertexBuffer.h>
|
||||
|
||||
using OpenSubdiv::Far::StencilTable;
|
||||
using OpenSubdiv::Osd::CpuEvaluator;
|
||||
using OpenSubdiv::Osd::CpuVertexBuffer;
|
||||
|
||||
namespace blender {
|
||||
namespace opensubdiv {
|
||||
|
||||
// Note: Define as a class instead of typedef to make it possible
|
||||
// to have anonymous class in opensubdiv_evaluator_internal.h
|
||||
class CpuEvalOutput : public VolatileEvalOutput<CpuVertexBuffer,
|
||||
CpuVertexBuffer,
|
||||
StencilTable,
|
||||
CpuPatchTable,
|
||||
CpuEvaluator> {
|
||||
public:
|
||||
CpuEvalOutput(const StencilTable *vertex_stencils,
|
||||
const StencilTable *varying_stencils,
|
||||
const vector<const StencilTable *> &all_face_varying_stencils,
|
||||
const int face_varying_width,
|
||||
const PatchTable *patch_table,
|
||||
EvaluatorCache *evaluator_cache = NULL)
|
||||
: VolatileEvalOutput<CpuVertexBuffer,
|
||||
CpuVertexBuffer,
|
||||
StencilTable,
|
||||
CpuPatchTable,
|
||||
CpuEvaluator>(vertex_stencils,
|
||||
varying_stencils,
|
||||
all_face_varying_stencils,
|
||||
face_varying_width,
|
||||
patch_table,
|
||||
evaluator_cache)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace opensubdiv
|
||||
} // namespace blender
|
||||
|
||||
#endif // OPENSUBDIV_EVAL_OUTPUT_CPU_H_
|
120
intern/opensubdiv/internal/evaluator/eval_output_gpu.cc
Normal file
120
intern/opensubdiv/internal/evaluator/eval_output_gpu.cc
Normal file
@@ -0,0 +1,120 @@
|
||||
// Copyright 2021 Blender Foundation. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// Author: Sergey Sharybin
|
||||
|
||||
#include "internal/evaluator/eval_output_gpu.h"
|
||||
|
||||
#include "opensubdiv_evaluator_capi.h"
|
||||
|
||||
using OpenSubdiv::Osd::PatchArray;
|
||||
using OpenSubdiv::Osd::PatchArrayVector;
|
||||
|
||||
namespace blender {
|
||||
namespace opensubdiv {
|
||||
|
||||
namespace {
|
||||
|
||||
static void buildPatchArraysBufferFromVector(const PatchArrayVector &patch_arrays,
|
||||
OpenSubdiv_Buffer *patch_arrays_buffer)
|
||||
{
|
||||
const size_t patch_array_size = sizeof(PatchArray);
|
||||
const size_t patch_array_byte_site = patch_array_size * patch_arrays.size();
|
||||
patch_arrays_buffer->device_alloc(patch_arrays_buffer, patch_arrays.size());
|
||||
patch_arrays_buffer->bind_gpu(patch_arrays_buffer);
|
||||
patch_arrays_buffer->device_update(
|
||||
patch_arrays_buffer, 0, patch_array_byte_site, &patch_arrays[0]);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
GpuEvalOutput::GpuEvalOutput(const StencilTable *vertex_stencils,
|
||||
const StencilTable *varying_stencils,
|
||||
const vector<const StencilTable *> &all_face_varying_stencils,
|
||||
const int face_varying_width,
|
||||
const PatchTable *patch_table,
|
||||
VolatileEvalOutput::EvaluatorCache *evaluator_cache)
|
||||
: VolatileEvalOutput<GLVertexBuffer,
|
||||
GLVertexBuffer,
|
||||
GLStencilTableSSBO,
|
||||
GLPatchTable,
|
||||
GLComputeEvaluator>(vertex_stencils,
|
||||
varying_stencils,
|
||||
all_face_varying_stencils,
|
||||
face_varying_width,
|
||||
patch_table,
|
||||
evaluator_cache)
|
||||
{
|
||||
}
|
||||
|
||||
void GpuEvalOutput::fillPatchArraysBuffer(OpenSubdiv_Buffer *patch_arrays_buffer)
|
||||
{
|
||||
GLPatchTable *patch_table = getPatchTable();
|
||||
buildPatchArraysBufferFromVector(patch_table->GetPatchArrays(), patch_arrays_buffer);
|
||||
}
|
||||
|
||||
void GpuEvalOutput::wrapPatchIndexBuffer(OpenSubdiv_Buffer *patch_index_buffer)
|
||||
{
|
||||
GLPatchTable *patch_table = getPatchTable();
|
||||
patch_index_buffer->wrap_device_handle(patch_index_buffer, patch_table->GetPatchIndexBuffer());
|
||||
}
|
||||
|
||||
void GpuEvalOutput::wrapPatchParamBuffer(OpenSubdiv_Buffer *patch_param_buffer)
|
||||
{
|
||||
GLPatchTable *patch_table = getPatchTable();
|
||||
patch_param_buffer->wrap_device_handle(patch_param_buffer, patch_table->GetPatchParamBuffer());
|
||||
}
|
||||
|
||||
void GpuEvalOutput::wrapSrcBuffer(OpenSubdiv_Buffer *src_buffer)
|
||||
{
|
||||
GLVertexBuffer *vertex_buffer = getSrcBuffer();
|
||||
src_buffer->wrap_device_handle(src_buffer, vertex_buffer->BindVBO());
|
||||
}
|
||||
|
||||
void GpuEvalOutput::fillFVarPatchArraysBuffer(const int face_varying_channel,
|
||||
OpenSubdiv_Buffer *patch_arrays_buffer)
|
||||
{
|
||||
GLPatchTable *patch_table = getFVarPatchTable(face_varying_channel);
|
||||
buildPatchArraysBufferFromVector(patch_table->GetFVarPatchArrays(face_varying_channel),
|
||||
patch_arrays_buffer);
|
||||
}
|
||||
|
||||
void GpuEvalOutput::wrapFVarPatchIndexBuffer(const int face_varying_channel,
|
||||
OpenSubdiv_Buffer *patch_index_buffer)
|
||||
{
|
||||
GLPatchTable *patch_table = getFVarPatchTable(face_varying_channel);
|
||||
patch_index_buffer->wrap_device_handle(
|
||||
patch_index_buffer, patch_table->GetFVarPatchIndexBuffer(face_varying_channel));
|
||||
}
|
||||
|
||||
void GpuEvalOutput::wrapFVarPatchParamBuffer(const int face_varying_channel,
|
||||
OpenSubdiv_Buffer *patch_param_buffer)
|
||||
{
|
||||
GLPatchTable *patch_table = getFVarPatchTable(face_varying_channel);
|
||||
patch_param_buffer->wrap_device_handle(
|
||||
patch_param_buffer, patch_table->GetFVarPatchParamBuffer(face_varying_channel));
|
||||
}
|
||||
|
||||
void GpuEvalOutput::wrapFVarSrcBuffer(const int face_varying_channel,
|
||||
OpenSubdiv_Buffer *src_buffer)
|
||||
{
|
||||
GLVertexBuffer *vertex_buffer = getFVarSrcBuffer(face_varying_channel);
|
||||
src_buffer->buffer_offset = getFVarSrcBufferOffset(face_varying_channel);
|
||||
src_buffer->wrap_device_handle(src_buffer, vertex_buffer->BindVBO());
|
||||
}
|
||||
|
||||
} // namespace opensubdiv
|
||||
} // namespace blender
|
71
intern/opensubdiv/internal/evaluator/eval_output_gpu.h
Normal file
71
intern/opensubdiv/internal/evaluator/eval_output_gpu.h
Normal file
@@ -0,0 +1,71 @@
|
||||
// Copyright 2021 Blender Foundation. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// Author: Sergey Sharybin
|
||||
|
||||
#ifndef OPENSUBDIV_EVAL_OUTPUT_GPU_H_
|
||||
#define OPENSUBDIV_EVAL_OUTPUT_GPU_H_
|
||||
|
||||
#include "internal/evaluator/eval_output.h"
|
||||
|
||||
#include <opensubdiv/osd/glComputeEvaluator.h>
|
||||
#include <opensubdiv/osd/glPatchTable.h>
|
||||
#include <opensubdiv/osd/glVertexBuffer.h>
|
||||
|
||||
using OpenSubdiv::Osd::GLComputeEvaluator;
|
||||
using OpenSubdiv::Osd::GLStencilTableSSBO;
|
||||
using OpenSubdiv::Osd::GLVertexBuffer;
|
||||
|
||||
namespace blender {
|
||||
namespace opensubdiv {
|
||||
|
||||
class GpuEvalOutput : public VolatileEvalOutput<GLVertexBuffer,
|
||||
GLVertexBuffer,
|
||||
GLStencilTableSSBO,
|
||||
GLPatchTable,
|
||||
GLComputeEvaluator> {
|
||||
public:
|
||||
GpuEvalOutput(const StencilTable *vertex_stencils,
|
||||
const StencilTable *varying_stencils,
|
||||
const vector<const StencilTable *> &all_face_varying_stencils,
|
||||
const int face_varying_width,
|
||||
const PatchTable *patch_table,
|
||||
EvaluatorCache *evaluator_cache = NULL);
|
||||
|
||||
void fillPatchArraysBuffer(OpenSubdiv_Buffer *patch_arrays_buffer) override;
|
||||
|
||||
void wrapPatchIndexBuffer(OpenSubdiv_Buffer *patch_index_buffer) override;
|
||||
|
||||
void wrapPatchParamBuffer(OpenSubdiv_Buffer *patch_param_buffer) override;
|
||||
|
||||
void wrapSrcBuffer(OpenSubdiv_Buffer *src_buffer) override;
|
||||
|
||||
void fillFVarPatchArraysBuffer(const int face_varying_channel,
|
||||
OpenSubdiv_Buffer *patch_arrays_buffer) override;
|
||||
|
||||
void wrapFVarPatchIndexBuffer(const int face_varying_channel,
|
||||
OpenSubdiv_Buffer *patch_index_buffer) override;
|
||||
|
||||
void wrapFVarPatchParamBuffer(const int face_varying_channel,
|
||||
OpenSubdiv_Buffer *patch_param_buffer) override;
|
||||
|
||||
void wrapFVarSrcBuffer(const int face_varying_channel, OpenSubdiv_Buffer *src_buffer) override;
|
||||
};
|
||||
|
||||
} // namespace opensubdiv
|
||||
} // namespace blender
|
||||
|
||||
#endif // OPENSUBDIV_EVAL_OUTPUT_GPU_H_
|
47
intern/opensubdiv/internal/evaluator/evaluator_cache_impl.cc
Normal file
47
intern/opensubdiv/internal/evaluator/evaluator_cache_impl.cc
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright 2021 Blender Foundation. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include "internal/evaluator/evaluator_cache_impl.h"
|
||||
|
||||
#include "internal/evaluator/eval_output_gpu.h"
|
||||
|
||||
OpenSubdiv_EvaluatorCacheImpl::OpenSubdiv_EvaluatorCacheImpl()
|
||||
{
|
||||
}
|
||||
|
||||
OpenSubdiv_EvaluatorCacheImpl::~OpenSubdiv_EvaluatorCacheImpl()
|
||||
{
|
||||
delete static_cast<blender::opensubdiv::GpuEvalOutput::EvaluatorCache *>(eval_cache);
|
||||
}
|
||||
|
||||
OpenSubdiv_EvaluatorCacheImpl *openSubdiv_createEvaluatorCacheInternal(
|
||||
eOpenSubdivEvaluator evaluator_type)
|
||||
{
|
||||
if (evaluator_type != eOpenSubdivEvaluator::OPENSUBDIV_EVALUATOR_GLSL_COMPUTE) {
|
||||
return nullptr;
|
||||
}
|
||||
OpenSubdiv_EvaluatorCacheImpl *evaluator_cache;
|
||||
evaluator_cache = new OpenSubdiv_EvaluatorCacheImpl;
|
||||
blender::opensubdiv::GpuEvalOutput::EvaluatorCache *eval_cache;
|
||||
eval_cache = new blender::opensubdiv::GpuEvalOutput::EvaluatorCache();
|
||||
evaluator_cache->eval_cache = eval_cache;
|
||||
return evaluator_cache;
|
||||
}
|
||||
|
||||
void openSubdiv_deleteEvaluatorCacheInternal(OpenSubdiv_EvaluatorCacheImpl *evaluator_cache)
|
||||
{
|
||||
delete evaluator_cache;
|
||||
}
|
38
intern/opensubdiv/internal/evaluator/evaluator_cache_impl.h
Normal file
38
intern/opensubdiv/internal/evaluator/evaluator_cache_impl.h
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright 2021 Blender Foundation. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef OPENSUBDIV_EVALUATOR_CACHE_IMPL_H_
|
||||
#define OPENSUBDIV_EVALUATOR_CACHE_IMPL_H_
|
||||
|
||||
#include "internal/base/memory.h"
|
||||
|
||||
#include "opensubdiv_capi_type.h"
|
||||
|
||||
struct OpenSubdiv_EvaluatorCacheImpl {
|
||||
public:
|
||||
OpenSubdiv_EvaluatorCacheImpl();
|
||||
~OpenSubdiv_EvaluatorCacheImpl();
|
||||
|
||||
void *eval_cache;
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("OpenSubdiv_EvaluatorCacheImpl");
|
||||
};
|
||||
|
||||
OpenSubdiv_EvaluatorCacheImpl *openSubdiv_createEvaluatorCacheInternal(
|
||||
eOpenSubdivEvaluator evaluator_type);
|
||||
|
||||
void openSubdiv_deleteEvaluatorCacheInternal(OpenSubdiv_EvaluatorCacheImpl *evaluator_cache);
|
||||
|
||||
#endif // OPENSUBDIV_EVALUATOR_CACHE_IMPL_H_
|
@@ -18,9 +18,12 @@
|
||||
|
||||
#include "opensubdiv_evaluator_capi.h"
|
||||
|
||||
#include <opensubdiv/osd/glslPatchShaderSource.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include <new>
|
||||
|
||||
#include "internal/evaluator/evaluator_cache_impl.h"
|
||||
#include "internal/evaluator/evaluator_impl.h"
|
||||
|
||||
namespace {
|
||||
@@ -132,6 +135,74 @@ void evaluateFaceVarying(OpenSubdiv_Evaluator *evaluator,
|
||||
face_varying_channel, ptex_face_index, face_u, face_v, face_varying);
|
||||
}
|
||||
|
||||
void getPatchMap(struct OpenSubdiv_Evaluator *evaluator,
|
||||
struct OpenSubdiv_Buffer *patch_map_handles,
|
||||
struct OpenSubdiv_Buffer *patch_map_quadtree,
|
||||
int *min_patch_face,
|
||||
int *max_patch_face,
|
||||
int *max_depth,
|
||||
int *patches_are_triangular)
|
||||
{
|
||||
evaluator->impl->eval_output->getPatchMap(patch_map_handles,
|
||||
patch_map_quadtree,
|
||||
min_patch_face,
|
||||
max_patch_face,
|
||||
max_depth,
|
||||
patches_are_triangular);
|
||||
}
|
||||
|
||||
void fillPatchArraysBuffer(struct OpenSubdiv_Evaluator *evaluator,
|
||||
struct OpenSubdiv_Buffer *patch_array_buffer)
|
||||
{
|
||||
evaluator->impl->eval_output->fillPatchArraysBuffer(patch_array_buffer);
|
||||
}
|
||||
|
||||
void wrapPatchIndexBuffer(struct OpenSubdiv_Evaluator *evaluator,
|
||||
struct OpenSubdiv_Buffer *patch_index_buffer)
|
||||
{
|
||||
evaluator->impl->eval_output->wrapPatchIndexBuffer(patch_index_buffer);
|
||||
}
|
||||
|
||||
void wrapPatchParamBuffer(struct OpenSubdiv_Evaluator *evaluator,
|
||||
struct OpenSubdiv_Buffer *patch_param_buffer)
|
||||
{
|
||||
evaluator->impl->eval_output->wrapPatchParamBuffer(patch_param_buffer);
|
||||
}
|
||||
|
||||
void wrapSrcBuffer(struct OpenSubdiv_Evaluator *evaluator, struct OpenSubdiv_Buffer *src_buffer)
|
||||
{
|
||||
evaluator->impl->eval_output->wrapSrcBuffer(src_buffer);
|
||||
}
|
||||
|
||||
void fillFVarPatchArraysBuffer(struct OpenSubdiv_Evaluator *evaluator,
|
||||
const int face_varying_channel,
|
||||
struct OpenSubdiv_Buffer *patch_array_buffer)
|
||||
{
|
||||
evaluator->impl->eval_output->fillFVarPatchArraysBuffer(face_varying_channel,
|
||||
patch_array_buffer);
|
||||
}
|
||||
|
||||
void wrapFVarPatchIndexBuffer(struct OpenSubdiv_Evaluator *evaluator,
|
||||
const int face_varying_channel,
|
||||
struct OpenSubdiv_Buffer *patch_index_buffer)
|
||||
{
|
||||
evaluator->impl->eval_output->wrapFVarPatchIndexBuffer(face_varying_channel, patch_index_buffer);
|
||||
}
|
||||
|
||||
void wrapFVarPatchParamBuffer(struct OpenSubdiv_Evaluator *evaluator,
|
||||
const int face_varying_channel,
|
||||
struct OpenSubdiv_Buffer *patch_param_buffer)
|
||||
{
|
||||
evaluator->impl->eval_output->wrapFVarPatchParamBuffer(face_varying_channel, patch_param_buffer);
|
||||
}
|
||||
|
||||
void wrapFVarSrcBuffer(struct OpenSubdiv_Evaluator *evaluator,
|
||||
const int face_varying_channel,
|
||||
struct OpenSubdiv_Buffer *src_buffer)
|
||||
{
|
||||
evaluator->impl->eval_output->wrapFVarSrcBuffer(face_varying_channel, src_buffer);
|
||||
}
|
||||
|
||||
void assignFunctionPointers(OpenSubdiv_Evaluator *evaluator)
|
||||
{
|
||||
evaluator->setCoarsePositions = setCoarsePositions;
|
||||
@@ -149,21 +220,64 @@ void assignFunctionPointers(OpenSubdiv_Evaluator *evaluator)
|
||||
evaluator->evaluateFaceVarying = evaluateFaceVarying;
|
||||
|
||||
evaluator->evaluatePatchesLimit = evaluatePatchesLimit;
|
||||
|
||||
evaluator->getPatchMap = getPatchMap;
|
||||
|
||||
evaluator->fillPatchArraysBuffer = fillPatchArraysBuffer;
|
||||
evaluator->wrapPatchIndexBuffer = wrapPatchIndexBuffer;
|
||||
evaluator->wrapPatchParamBuffer = wrapPatchParamBuffer;
|
||||
evaluator->wrapSrcBuffer = wrapSrcBuffer;
|
||||
|
||||
evaluator->fillFVarPatchArraysBuffer = fillFVarPatchArraysBuffer;
|
||||
evaluator->wrapFVarPatchIndexBuffer = wrapFVarPatchIndexBuffer;
|
||||
evaluator->wrapFVarPatchParamBuffer = wrapFVarPatchParamBuffer;
|
||||
evaluator->wrapFVarSrcBuffer = wrapFVarSrcBuffer;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
OpenSubdiv_Evaluator *openSubdiv_createEvaluatorFromTopologyRefiner(
|
||||
OpenSubdiv_TopologyRefiner *topology_refiner)
|
||||
OpenSubdiv_TopologyRefiner *topology_refiner,
|
||||
eOpenSubdivEvaluator evaluator_type,
|
||||
OpenSubdiv_EvaluatorCache *evaluator_cache)
|
||||
{
|
||||
OpenSubdiv_Evaluator *evaluator = OBJECT_GUARDED_NEW(OpenSubdiv_Evaluator);
|
||||
OpenSubdiv_Evaluator *evaluator = MEM_new<OpenSubdiv_Evaluator>(__func__);
|
||||
assignFunctionPointers(evaluator);
|
||||
evaluator->impl = openSubdiv_createEvaluatorInternal(topology_refiner);
|
||||
evaluator->impl = openSubdiv_createEvaluatorInternal(
|
||||
topology_refiner, evaluator_type, evaluator_cache ? evaluator_cache->impl : nullptr);
|
||||
evaluator->type = evaluator->impl ? evaluator_type : static_cast<eOpenSubdivEvaluator>(0);
|
||||
return evaluator;
|
||||
}
|
||||
|
||||
void openSubdiv_deleteEvaluator(OpenSubdiv_Evaluator *evaluator)
|
||||
{
|
||||
openSubdiv_deleteEvaluatorInternal(evaluator->impl);
|
||||
OBJECT_GUARDED_DELETE(evaluator, OpenSubdiv_Evaluator);
|
||||
MEM_delete(evaluator);
|
||||
}
|
||||
|
||||
OpenSubdiv_EvaluatorCache *openSubdiv_createEvaluatorCache(eOpenSubdivEvaluator evaluator_type)
|
||||
{
|
||||
OpenSubdiv_EvaluatorCache *evaluator_cache = MEM_new<OpenSubdiv_EvaluatorCache>(__func__);
|
||||
evaluator_cache->impl = openSubdiv_createEvaluatorCacheInternal(evaluator_type);
|
||||
return evaluator_cache;
|
||||
}
|
||||
|
||||
void openSubdiv_deleteEvaluatorCache(OpenSubdiv_EvaluatorCache *evaluator_cache)
|
||||
{
|
||||
if (!evaluator_cache) {
|
||||
return;
|
||||
}
|
||||
|
||||
openSubdiv_deleteEvaluatorCacheInternal(evaluator_cache->impl);
|
||||
MEM_delete(evaluator_cache);
|
||||
}
|
||||
|
||||
const char *openSubdiv_getGLSLPatchBasisSource(void)
|
||||
{
|
||||
/* Using a global string to avoid dealing with memory allocation/ownership. */
|
||||
static std::string patch_basis_source;
|
||||
if (patch_basis_source.empty()) {
|
||||
patch_basis_source = OpenSubdiv::Osd::GLSLPatchShaderSource::GetPatchBasisShaderSource();
|
||||
}
|
||||
return patch_basis_source.c_str();
|
||||
}
|
||||
|
@@ -28,9 +28,6 @@
|
||||
#include <opensubdiv/far/patchMap.h>
|
||||
#include <opensubdiv/far/patchTable.h>
|
||||
#include <opensubdiv/far/patchTableFactory.h>
|
||||
#include <opensubdiv/osd/cpuEvaluator.h>
|
||||
#include <opensubdiv/osd/cpuPatchTable.h>
|
||||
#include <opensubdiv/osd/cpuVertexBuffer.h>
|
||||
#include <opensubdiv/osd/mesh.h>
|
||||
#include <opensubdiv/osd/types.h>
|
||||
#include <opensubdiv/version.h>
|
||||
@@ -38,19 +35,20 @@
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "internal/base/type.h"
|
||||
#include "internal/evaluator/eval_output_cpu.h"
|
||||
#include "internal/evaluator/eval_output_gpu.h"
|
||||
#include "internal/evaluator/evaluator_cache_impl.h"
|
||||
#include "internal/evaluator/patch_map.h"
|
||||
#include "internal/topology/topology_refiner_impl.h"
|
||||
#include "opensubdiv_evaluator_capi.h"
|
||||
#include "opensubdiv_topology_refiner_capi.h"
|
||||
|
||||
using OpenSubdiv::Far::PatchMap;
|
||||
using OpenSubdiv::Far::PatchTable;
|
||||
using OpenSubdiv::Far::PatchTableFactory;
|
||||
using OpenSubdiv::Far::StencilTable;
|
||||
using OpenSubdiv::Far::StencilTableFactory;
|
||||
using OpenSubdiv::Far::TopologyRefiner;
|
||||
using OpenSubdiv::Osd::BufferDescriptor;
|
||||
using OpenSubdiv::Osd::CpuEvaluator;
|
||||
using OpenSubdiv::Osd::CpuPatchTable;
|
||||
using OpenSubdiv::Osd::CpuVertexBuffer;
|
||||
using OpenSubdiv::Osd::PatchArray;
|
||||
using OpenSubdiv::Osd::PatchCoord;
|
||||
|
||||
namespace blender {
|
||||
@@ -140,407 +138,9 @@ template<typename T, int kNumMaxElementsOnStack> class StackOrHeapArray {
|
||||
// 32 is a number of inner vertices along the patch size at subdivision level 6.
|
||||
typedef StackOrHeapArray<PatchCoord, 32 * 32> StackOrHeapPatchCoordArray;
|
||||
|
||||
// Buffer which implements API required by OpenSubdiv and uses an existing memory as an underlying
|
||||
// storage.
|
||||
template<typename T> class RawDataWrapperBuffer {
|
||||
public:
|
||||
RawDataWrapperBuffer(T *data) : data_(data)
|
||||
{
|
||||
}
|
||||
|
||||
T *BindCpuBuffer()
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
|
||||
// TODO(sergey): Support UpdateData().
|
||||
|
||||
protected:
|
||||
T *data_;
|
||||
};
|
||||
|
||||
template<typename T> class RawDataWrapperVertexBuffer : public RawDataWrapperBuffer<T> {
|
||||
public:
|
||||
RawDataWrapperVertexBuffer(T *data, int num_vertices)
|
||||
: RawDataWrapperBuffer<T>(data), num_vertices_(num_vertices)
|
||||
{
|
||||
}
|
||||
|
||||
int GetNumVertices()
|
||||
{
|
||||
return num_vertices_;
|
||||
}
|
||||
|
||||
protected:
|
||||
int num_vertices_;
|
||||
};
|
||||
|
||||
class ConstPatchCoordWrapperBuffer : public RawDataWrapperVertexBuffer<const PatchCoord> {
|
||||
public:
|
||||
ConstPatchCoordWrapperBuffer(const PatchCoord *data, int num_vertices)
|
||||
: RawDataWrapperVertexBuffer(data, num_vertices)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<typename EVAL_VERTEX_BUFFER,
|
||||
typename STENCIL_TABLE,
|
||||
typename PATCH_TABLE,
|
||||
typename EVALUATOR,
|
||||
typename DEVICE_CONTEXT = void>
|
||||
class FaceVaryingVolatileEval {
|
||||
public:
|
||||
typedef OpenSubdiv::Osd::EvaluatorCacheT<EVALUATOR> EvaluatorCache;
|
||||
|
||||
FaceVaryingVolatileEval(int face_varying_channel,
|
||||
const StencilTable *face_varying_stencils,
|
||||
int face_varying_width,
|
||||
PATCH_TABLE *patch_table,
|
||||
EvaluatorCache *evaluator_cache = NULL,
|
||||
DEVICE_CONTEXT *device_context = NULL)
|
||||
: face_varying_channel_(face_varying_channel),
|
||||
src_face_varying_desc_(0, face_varying_width, face_varying_width),
|
||||
patch_table_(patch_table),
|
||||
evaluator_cache_(evaluator_cache),
|
||||
device_context_(device_context)
|
||||
{
|
||||
using OpenSubdiv::Osd::convertToCompatibleStencilTable;
|
||||
num_coarse_face_varying_vertices_ = face_varying_stencils->GetNumControlVertices();
|
||||
const int num_total_face_varying_vertices = face_varying_stencils->GetNumControlVertices() +
|
||||
face_varying_stencils->GetNumStencils();
|
||||
src_face_varying_data_ = EVAL_VERTEX_BUFFER::Create(
|
||||
2, num_total_face_varying_vertices, device_context);
|
||||
face_varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(face_varying_stencils,
|
||||
device_context_);
|
||||
}
|
||||
|
||||
~FaceVaryingVolatileEval()
|
||||
{
|
||||
delete src_face_varying_data_;
|
||||
delete face_varying_stencils_;
|
||||
}
|
||||
|
||||
void updateData(const float *src, int start_vertex, int num_vertices)
|
||||
{
|
||||
src_face_varying_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
|
||||
}
|
||||
|
||||
void refine()
|
||||
{
|
||||
BufferDescriptor dst_face_varying_desc = src_face_varying_desc_;
|
||||
dst_face_varying_desc.offset += num_coarse_face_varying_vertices_ *
|
||||
src_face_varying_desc_.stride;
|
||||
const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
|
||||
evaluator_cache_, src_face_varying_desc_, dst_face_varying_desc, device_context_);
|
||||
// in and out points to same buffer so output is put directly after coarse vertices, needed in
|
||||
// adaptive mode
|
||||
EVALUATOR::EvalStencils(src_face_varying_data_,
|
||||
src_face_varying_desc_,
|
||||
src_face_varying_data_,
|
||||
dst_face_varying_desc,
|
||||
face_varying_stencils_,
|
||||
eval_instance,
|
||||
device_context_);
|
||||
}
|
||||
|
||||
// NOTE: face_varying must point to a memory of at least float[2]*num_patch_coords.
|
||||
void evalPatches(const PatchCoord *patch_coord, const int num_patch_coords, float *face_varying)
|
||||
{
|
||||
RawDataWrapperBuffer<float> face_varying_data(face_varying);
|
||||
BufferDescriptor face_varying_desc(0, 2, 2);
|
||||
ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
|
||||
const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
|
||||
evaluator_cache_, src_face_varying_desc_, face_varying_desc, device_context_);
|
||||
|
||||
// src_face_varying_data_ always contains coarse vertices at the beginning.
|
||||
// In adaptive mode they are followed by number of blocks for intermediate
|
||||
// subdivision levels, and this is what OSD expects in this mode.
|
||||
// In non-adaptive mode (generateIntermediateLevels == false),
|
||||
// they are followed by max subdivision level, but they break interpolation as OSD
|
||||
// expects only one subd level in this buffer.
|
||||
// So in non-adaptive mode we put offset into buffer descriptor to skip over coarse vertices.
|
||||
BufferDescriptor src_desc = src_face_varying_desc_;
|
||||
if (!patch_table_->GetPatchArrayBuffer()[0].GetDescriptor().IsAdaptive()) {
|
||||
src_desc.offset += num_coarse_face_varying_vertices_ * src_face_varying_desc_.stride;
|
||||
}
|
||||
|
||||
EVALUATOR::EvalPatchesFaceVarying(src_face_varying_data_,
|
||||
src_desc,
|
||||
&face_varying_data,
|
||||
face_varying_desc,
|
||||
patch_coord_buffer.GetNumVertices(),
|
||||
&patch_coord_buffer,
|
||||
patch_table_,
|
||||
face_varying_channel_,
|
||||
eval_instance,
|
||||
device_context_);
|
||||
}
|
||||
|
||||
protected:
|
||||
int face_varying_channel_;
|
||||
|
||||
BufferDescriptor src_face_varying_desc_;
|
||||
|
||||
int num_coarse_face_varying_vertices_;
|
||||
EVAL_VERTEX_BUFFER *src_face_varying_data_;
|
||||
const STENCIL_TABLE *face_varying_stencils_;
|
||||
|
||||
// NOTE: We reference this, do not own it.
|
||||
PATCH_TABLE *patch_table_;
|
||||
|
||||
EvaluatorCache *evaluator_cache_;
|
||||
DEVICE_CONTEXT *device_context_;
|
||||
};
|
||||
|
||||
// Volatile evaluator which can be used from threads.
|
||||
//
|
||||
// TODO(sergey): Make it possible to evaluate coordinates in chunks.
|
||||
// TODO(sergey): Make it possible to evaluate multiple face varying layers.
|
||||
// (or maybe, it's cheap to create new evaluator for existing
|
||||
// topology to evaluate all needed face varying layers?)
|
||||
template<typename SRC_VERTEX_BUFFER,
|
||||
typename EVAL_VERTEX_BUFFER,
|
||||
typename STENCIL_TABLE,
|
||||
typename PATCH_TABLE,
|
||||
typename EVALUATOR,
|
||||
typename DEVICE_CONTEXT = void>
|
||||
class VolatileEvalOutput {
|
||||
public:
|
||||
typedef OpenSubdiv::Osd::EvaluatorCacheT<EVALUATOR> EvaluatorCache;
|
||||
typedef FaceVaryingVolatileEval<EVAL_VERTEX_BUFFER,
|
||||
STENCIL_TABLE,
|
||||
PATCH_TABLE,
|
||||
EVALUATOR,
|
||||
DEVICE_CONTEXT>
|
||||
FaceVaryingEval;
|
||||
|
||||
VolatileEvalOutput(const StencilTable *vertex_stencils,
|
||||
const StencilTable *varying_stencils,
|
||||
const vector<const StencilTable *> &all_face_varying_stencils,
|
||||
const int face_varying_width,
|
||||
const PatchTable *patch_table,
|
||||
EvaluatorCache *evaluator_cache = NULL,
|
||||
DEVICE_CONTEXT *device_context = NULL)
|
||||
: src_desc_(0, 3, 3),
|
||||
src_varying_desc_(0, 3, 3),
|
||||
face_varying_width_(face_varying_width),
|
||||
evaluator_cache_(evaluator_cache),
|
||||
device_context_(device_context)
|
||||
{
|
||||
// Total number of vertices = coarse points + refined points + local points.
|
||||
int num_total_vertices = vertex_stencils->GetNumControlVertices() +
|
||||
vertex_stencils->GetNumStencils();
|
||||
num_coarse_vertices_ = vertex_stencils->GetNumControlVertices();
|
||||
using OpenSubdiv::Osd::convertToCompatibleStencilTable;
|
||||
src_data_ = SRC_VERTEX_BUFFER::Create(3, num_total_vertices, device_context_);
|
||||
src_varying_data_ = SRC_VERTEX_BUFFER::Create(3, num_total_vertices, device_context_);
|
||||
patch_table_ = PATCH_TABLE::Create(patch_table, device_context_);
|
||||
vertex_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(vertex_stencils,
|
||||
device_context_);
|
||||
varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(varying_stencils,
|
||||
device_context_);
|
||||
// Create evaluators for every face varying channel.
|
||||
face_varying_evaluators.reserve(all_face_varying_stencils.size());
|
||||
int face_varying_channel = 0;
|
||||
for (const StencilTable *face_varying_stencils : all_face_varying_stencils) {
|
||||
face_varying_evaluators.push_back(new FaceVaryingEval(face_varying_channel,
|
||||
face_varying_stencils,
|
||||
face_varying_width,
|
||||
patch_table_,
|
||||
evaluator_cache_,
|
||||
device_context_));
|
||||
++face_varying_channel;
|
||||
}
|
||||
}
|
||||
|
||||
~VolatileEvalOutput()
|
||||
{
|
||||
delete src_data_;
|
||||
delete src_varying_data_;
|
||||
delete patch_table_;
|
||||
delete vertex_stencils_;
|
||||
delete varying_stencils_;
|
||||
for (FaceVaryingEval *face_varying_evaluator : face_varying_evaluators) {
|
||||
delete face_varying_evaluator;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(sergey): Implement binding API.
|
||||
|
||||
void updateData(const float *src, int start_vertex, int num_vertices)
|
||||
{
|
||||
src_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
|
||||
}
|
||||
|
||||
void updateVaryingData(const float *src, int start_vertex, int num_vertices)
|
||||
{
|
||||
src_varying_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
|
||||
}
|
||||
|
||||
void updateFaceVaryingData(const int face_varying_channel,
|
||||
const float *src,
|
||||
int start_vertex,
|
||||
int num_vertices)
|
||||
{
|
||||
assert(face_varying_channel >= 0);
|
||||
assert(face_varying_channel < face_varying_evaluators.size());
|
||||
face_varying_evaluators[face_varying_channel]->updateData(src, start_vertex, num_vertices);
|
||||
}
|
||||
|
||||
bool hasVaryingData() const
|
||||
{
|
||||
// return varying_stencils_ != NULL;
|
||||
// TODO(sergey): Check this based on actual topology.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hasFaceVaryingData() const
|
||||
{
|
||||
return face_varying_evaluators.size() != 0;
|
||||
}
|
||||
|
||||
void refine()
|
||||
{
|
||||
// Evaluate vertex positions.
|
||||
BufferDescriptor dst_desc = src_desc_;
|
||||
dst_desc.offset += num_coarse_vertices_ * src_desc_.stride;
|
||||
const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
|
||||
evaluator_cache_, src_desc_, dst_desc, device_context_);
|
||||
EVALUATOR::EvalStencils(src_data_,
|
||||
src_desc_,
|
||||
src_data_,
|
||||
dst_desc,
|
||||
vertex_stencils_,
|
||||
eval_instance,
|
||||
device_context_);
|
||||
// Evaluate varying data.
|
||||
if (hasVaryingData()) {
|
||||
BufferDescriptor dst_varying_desc = src_varying_desc_;
|
||||
dst_varying_desc.offset += num_coarse_vertices_ * src_varying_desc_.stride;
|
||||
eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
|
||||
evaluator_cache_, src_varying_desc_, dst_varying_desc, device_context_);
|
||||
EVALUATOR::EvalStencils(src_varying_data_,
|
||||
src_varying_desc_,
|
||||
src_varying_data_,
|
||||
dst_varying_desc,
|
||||
varying_stencils_,
|
||||
eval_instance,
|
||||
device_context_);
|
||||
}
|
||||
// Evaluate face-varying data.
|
||||
if (hasFaceVaryingData()) {
|
||||
for (FaceVaryingEval *face_varying_evaluator : face_varying_evaluators) {
|
||||
face_varying_evaluator->refine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: P must point to a memory of at least float[3]*num_patch_coords.
|
||||
void evalPatches(const PatchCoord *patch_coord, const int num_patch_coords, float *P)
|
||||
{
|
||||
RawDataWrapperBuffer<float> P_data(P);
|
||||
// TODO(sergey): Support interleaved vertex-varying data.
|
||||
BufferDescriptor P_desc(0, 3, 3);
|
||||
ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
|
||||
const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
|
||||
evaluator_cache_, src_desc_, P_desc, device_context_);
|
||||
EVALUATOR::EvalPatches(src_data_,
|
||||
src_desc_,
|
||||
&P_data,
|
||||
P_desc,
|
||||
patch_coord_buffer.GetNumVertices(),
|
||||
&patch_coord_buffer,
|
||||
patch_table_,
|
||||
eval_instance,
|
||||
device_context_);
|
||||
}
|
||||
|
||||
// NOTE: P, dPdu, dPdv must point to a memory of at least float[3]*num_patch_coords.
|
||||
void evalPatchesWithDerivatives(const PatchCoord *patch_coord,
|
||||
const int num_patch_coords,
|
||||
float *P,
|
||||
float *dPdu,
|
||||
float *dPdv)
|
||||
{
|
||||
assert(dPdu);
|
||||
assert(dPdv);
|
||||
RawDataWrapperBuffer<float> P_data(P);
|
||||
RawDataWrapperBuffer<float> dPdu_data(dPdu), dPdv_data(dPdv);
|
||||
// TODO(sergey): Support interleaved vertex-varying data.
|
||||
BufferDescriptor P_desc(0, 3, 3);
|
||||
BufferDescriptor dpDu_desc(0, 3, 3), pPdv_desc(0, 3, 3);
|
||||
ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
|
||||
const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
|
||||
evaluator_cache_, src_desc_, P_desc, dpDu_desc, pPdv_desc, device_context_);
|
||||
EVALUATOR::EvalPatches(src_data_,
|
||||
src_desc_,
|
||||
&P_data,
|
||||
P_desc,
|
||||
&dPdu_data,
|
||||
dpDu_desc,
|
||||
&dPdv_data,
|
||||
pPdv_desc,
|
||||
patch_coord_buffer.GetNumVertices(),
|
||||
&patch_coord_buffer,
|
||||
patch_table_,
|
||||
eval_instance,
|
||||
device_context_);
|
||||
}
|
||||
|
||||
// NOTE: varying must point to a memory of at least float[3]*num_patch_coords.
|
||||
void evalPatchesVarying(const PatchCoord *patch_coord,
|
||||
const int num_patch_coords,
|
||||
float *varying)
|
||||
{
|
||||
RawDataWrapperBuffer<float> varying_data(varying);
|
||||
BufferDescriptor varying_desc(3, 3, 6);
|
||||
ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
|
||||
const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
|
||||
evaluator_cache_, src_varying_desc_, varying_desc, device_context_);
|
||||
EVALUATOR::EvalPatchesVarying(src_varying_data_,
|
||||
src_varying_desc_,
|
||||
&varying_data,
|
||||
varying_desc,
|
||||
patch_coord_buffer.GetNumVertices(),
|
||||
&patch_coord_buffer,
|
||||
patch_table_,
|
||||
eval_instance,
|
||||
device_context_);
|
||||
}
|
||||
|
||||
void evalPatchesFaceVarying(const int face_varying_channel,
|
||||
const PatchCoord *patch_coord,
|
||||
const int num_patch_coords,
|
||||
float face_varying[2])
|
||||
{
|
||||
assert(face_varying_channel >= 0);
|
||||
assert(face_varying_channel < face_varying_evaluators.size());
|
||||
face_varying_evaluators[face_varying_channel]->evalPatches(
|
||||
patch_coord, num_patch_coords, face_varying);
|
||||
}
|
||||
|
||||
private:
|
||||
SRC_VERTEX_BUFFER *src_data_;
|
||||
SRC_VERTEX_BUFFER *src_varying_data_;
|
||||
PATCH_TABLE *patch_table_;
|
||||
BufferDescriptor src_desc_;
|
||||
BufferDescriptor src_varying_desc_;
|
||||
|
||||
int num_coarse_vertices_;
|
||||
|
||||
const STENCIL_TABLE *vertex_stencils_;
|
||||
const STENCIL_TABLE *varying_stencils_;
|
||||
|
||||
int face_varying_width_;
|
||||
vector<FaceVaryingEval *> face_varying_evaluators;
|
||||
|
||||
EvaluatorCache *evaluator_cache_;
|
||||
DEVICE_CONTEXT *device_context_;
|
||||
};
|
||||
|
||||
void convertPatchCoordsToArray(const OpenSubdiv_PatchCoord *patch_coords,
|
||||
const int num_patch_coords,
|
||||
const OpenSubdiv::Far::PatchMap *patch_map,
|
||||
const PatchMap *patch_map,
|
||||
StackOrHeapPatchCoordArray *array)
|
||||
{
|
||||
array->resize(num_patch_coords);
|
||||
@@ -553,79 +153,50 @@ void convertPatchCoordsToArray(const OpenSubdiv_PatchCoord *patch_coords,
|
||||
|
||||
} // namespace
|
||||
|
||||
// Note: Define as a class instead of typedef to make it possible
|
||||
// to have anonymous class in opensubdiv_evaluator_internal.h
|
||||
class CpuEvalOutput : public VolatileEvalOutput<CpuVertexBuffer,
|
||||
CpuVertexBuffer,
|
||||
StencilTable,
|
||||
CpuPatchTable,
|
||||
CpuEvaluator> {
|
||||
public:
|
||||
CpuEvalOutput(const StencilTable *vertex_stencils,
|
||||
const StencilTable *varying_stencils,
|
||||
const vector<const StencilTable *> &all_face_varying_stencils,
|
||||
const int face_varying_width,
|
||||
const PatchTable *patch_table,
|
||||
EvaluatorCache *evaluator_cache = NULL)
|
||||
: VolatileEvalOutput<CpuVertexBuffer,
|
||||
CpuVertexBuffer,
|
||||
StencilTable,
|
||||
CpuPatchTable,
|
||||
CpuEvaluator>(vertex_stencils,
|
||||
varying_stencils,
|
||||
all_face_varying_stencils,
|
||||
face_varying_width,
|
||||
patch_table,
|
||||
evaluator_cache)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Evaluator wrapper for anonymous API.
|
||||
|
||||
CpuEvalOutputAPI::CpuEvalOutputAPI(CpuEvalOutput *implementation,
|
||||
OpenSubdiv::Far::PatchMap *patch_map)
|
||||
: implementation_(implementation), patch_map_(patch_map)
|
||||
EvalOutputAPI::EvalOutputAPI(EvalOutput *implementation, PatchMap *patch_map)
|
||||
: patch_map_(patch_map), implementation_(implementation)
|
||||
{
|
||||
}
|
||||
|
||||
CpuEvalOutputAPI::~CpuEvalOutputAPI()
|
||||
EvalOutputAPI::~EvalOutputAPI()
|
||||
{
|
||||
delete implementation_;
|
||||
}
|
||||
|
||||
void CpuEvalOutputAPI::setCoarsePositions(const float *positions,
|
||||
const int start_vertex_index,
|
||||
const int num_vertices)
|
||||
void EvalOutputAPI::setCoarsePositions(const float *positions,
|
||||
const int start_vertex_index,
|
||||
const int num_vertices)
|
||||
{
|
||||
// TODO(sergey): Add sanity check on indices.
|
||||
implementation_->updateData(positions, start_vertex_index, num_vertices);
|
||||
}
|
||||
|
||||
void CpuEvalOutputAPI::setVaryingData(const float *varying_data,
|
||||
const int start_vertex_index,
|
||||
const int num_vertices)
|
||||
void EvalOutputAPI::setVaryingData(const float *varying_data,
|
||||
const int start_vertex_index,
|
||||
const int num_vertices)
|
||||
{
|
||||
// TODO(sergey): Add sanity check on indices.
|
||||
implementation_->updateVaryingData(varying_data, start_vertex_index, num_vertices);
|
||||
}
|
||||
|
||||
void CpuEvalOutputAPI::setFaceVaryingData(const int face_varying_channel,
|
||||
const float *face_varying_data,
|
||||
const int start_vertex_index,
|
||||
const int num_vertices)
|
||||
void EvalOutputAPI::setFaceVaryingData(const int face_varying_channel,
|
||||
const float *face_varying_data,
|
||||
const int start_vertex_index,
|
||||
const int num_vertices)
|
||||
{
|
||||
// TODO(sergey): Add sanity check on indices.
|
||||
implementation_->updateFaceVaryingData(
|
||||
face_varying_channel, face_varying_data, start_vertex_index, num_vertices);
|
||||
}
|
||||
|
||||
void CpuEvalOutputAPI::setCoarsePositionsFromBuffer(const void *buffer,
|
||||
const int start_offset,
|
||||
const int stride,
|
||||
const int start_vertex_index,
|
||||
const int num_vertices)
|
||||
void EvalOutputAPI::setCoarsePositionsFromBuffer(const void *buffer,
|
||||
const int start_offset,
|
||||
const int stride,
|
||||
const int start_vertex_index,
|
||||
const int num_vertices)
|
||||
{
|
||||
// TODO(sergey): Add sanity check on indices.
|
||||
const unsigned char *current_buffer = (unsigned char *)buffer;
|
||||
@@ -638,11 +209,11 @@ void CpuEvalOutputAPI::setCoarsePositionsFromBuffer(const void *buffer,
|
||||
}
|
||||
}
|
||||
|
||||
void CpuEvalOutputAPI::setVaryingDataFromBuffer(const void *buffer,
|
||||
const int start_offset,
|
||||
const int stride,
|
||||
const int start_vertex_index,
|
||||
const int num_vertices)
|
||||
void EvalOutputAPI::setVaryingDataFromBuffer(const void *buffer,
|
||||
const int start_offset,
|
||||
const int stride,
|
||||
const int start_vertex_index,
|
||||
const int num_vertices)
|
||||
{
|
||||
// TODO(sergey): Add sanity check on indices.
|
||||
const unsigned char *current_buffer = (unsigned char *)buffer;
|
||||
@@ -655,12 +226,12 @@ void CpuEvalOutputAPI::setVaryingDataFromBuffer(const void *buffer,
|
||||
}
|
||||
}
|
||||
|
||||
void CpuEvalOutputAPI::setFaceVaryingDataFromBuffer(const int face_varying_channel,
|
||||
const void *buffer,
|
||||
const int start_offset,
|
||||
const int stride,
|
||||
const int start_vertex_index,
|
||||
const int num_vertices)
|
||||
void EvalOutputAPI::setFaceVaryingDataFromBuffer(const int face_varying_channel,
|
||||
const void *buffer,
|
||||
const int start_offset,
|
||||
const int stride,
|
||||
const int start_vertex_index,
|
||||
const int num_vertices)
|
||||
{
|
||||
// TODO(sergey): Add sanity check on indices.
|
||||
const unsigned char *current_buffer = (unsigned char *)buffer;
|
||||
@@ -675,17 +246,17 @@ void CpuEvalOutputAPI::setFaceVaryingDataFromBuffer(const int face_varying_chann
|
||||
}
|
||||
}
|
||||
|
||||
void CpuEvalOutputAPI::refine()
|
||||
void EvalOutputAPI::refine()
|
||||
{
|
||||
implementation_->refine();
|
||||
}
|
||||
|
||||
void CpuEvalOutputAPI::evaluateLimit(const int ptex_face_index,
|
||||
float face_u,
|
||||
float face_v,
|
||||
float P[3],
|
||||
float dPdu[3],
|
||||
float dPdv[3])
|
||||
void EvalOutputAPI::evaluateLimit(const int ptex_face_index,
|
||||
float face_u,
|
||||
float face_v,
|
||||
float P[3],
|
||||
float dPdu[3],
|
||||
float dPdv[3])
|
||||
{
|
||||
assert(face_u >= 0.0f);
|
||||
assert(face_u <= 1.0f);
|
||||
@@ -701,10 +272,10 @@ void CpuEvalOutputAPI::evaluateLimit(const int ptex_face_index,
|
||||
}
|
||||
}
|
||||
|
||||
void CpuEvalOutputAPI::evaluateVarying(const int ptex_face_index,
|
||||
float face_u,
|
||||
float face_v,
|
||||
float varying[3])
|
||||
void EvalOutputAPI::evaluateVarying(const int ptex_face_index,
|
||||
float face_u,
|
||||
float face_v,
|
||||
float varying[3])
|
||||
{
|
||||
assert(face_u >= 0.0f);
|
||||
assert(face_u <= 1.0f);
|
||||
@@ -715,11 +286,11 @@ void CpuEvalOutputAPI::evaluateVarying(const int ptex_face_index,
|
||||
implementation_->evalPatchesVarying(&patch_coord, 1, varying);
|
||||
}
|
||||
|
||||
void CpuEvalOutputAPI::evaluateFaceVarying(const int face_varying_channel,
|
||||
const int ptex_face_index,
|
||||
float face_u,
|
||||
float face_v,
|
||||
float face_varying[2])
|
||||
void EvalOutputAPI::evaluateFaceVarying(const int face_varying_channel,
|
||||
const int ptex_face_index,
|
||||
float face_u,
|
||||
float face_v,
|
||||
float face_varying[2])
|
||||
{
|
||||
assert(face_u >= 0.0f);
|
||||
assert(face_u <= 1.0f);
|
||||
@@ -730,11 +301,11 @@ void CpuEvalOutputAPI::evaluateFaceVarying(const int face_varying_channel,
|
||||
implementation_->evalPatchesFaceVarying(face_varying_channel, &patch_coord, 1, face_varying);
|
||||
}
|
||||
|
||||
void CpuEvalOutputAPI::evaluatePatchesLimit(const OpenSubdiv_PatchCoord *patch_coords,
|
||||
const int num_patch_coords,
|
||||
float *P,
|
||||
float *dPdu,
|
||||
float *dPdv)
|
||||
void EvalOutputAPI::evaluatePatchesLimit(const OpenSubdiv_PatchCoord *patch_coords,
|
||||
const int num_patch_coords,
|
||||
float *P,
|
||||
float *dPdu,
|
||||
float *dPdv)
|
||||
{
|
||||
StackOrHeapPatchCoordArray patch_coords_array;
|
||||
convertPatchCoordsToArray(patch_coords, num_patch_coords, patch_map_, &patch_coords_array);
|
||||
@@ -747,6 +318,73 @@ void CpuEvalOutputAPI::evaluatePatchesLimit(const OpenSubdiv_PatchCoord *patch_c
|
||||
}
|
||||
}
|
||||
|
||||
void EvalOutputAPI::getPatchMap(OpenSubdiv_Buffer *patch_map_handles,
|
||||
OpenSubdiv_Buffer *patch_map_quadtree,
|
||||
int *min_patch_face,
|
||||
int *max_patch_face,
|
||||
int *max_depth,
|
||||
int *patches_are_triangular)
|
||||
{
|
||||
*min_patch_face = patch_map_->getMinPatchFace();
|
||||
*max_patch_face = patch_map_->getMaxPatchFace();
|
||||
*max_depth = patch_map_->getMaxDepth();
|
||||
*patches_are_triangular = patch_map_->getPatchesAreTriangular();
|
||||
|
||||
const std::vector<PatchTable::PatchHandle> &handles = patch_map_->getHandles();
|
||||
PatchTable::PatchHandle *buffer_handles = static_cast<PatchTable::PatchHandle *>(
|
||||
patch_map_handles->alloc(patch_map_handles, handles.size()));
|
||||
memcpy(buffer_handles, &handles[0], sizeof(PatchTable::PatchHandle) * handles.size());
|
||||
|
||||
const std::vector<PatchMap::QuadNode> &quadtree = patch_map_->nodes();
|
||||
PatchMap::QuadNode *buffer_nodes = static_cast<PatchMap::QuadNode *>(
|
||||
patch_map_quadtree->alloc(patch_map_quadtree, quadtree.size()));
|
||||
memcpy(buffer_nodes, &quadtree[0], sizeof(PatchMap::QuadNode) * quadtree.size());
|
||||
}
|
||||
|
||||
void EvalOutputAPI::fillPatchArraysBuffer(OpenSubdiv_Buffer *patch_arrays_buffer)
|
||||
{
|
||||
implementation_->fillPatchArraysBuffer(patch_arrays_buffer);
|
||||
}
|
||||
|
||||
void EvalOutputAPI::wrapPatchIndexBuffer(OpenSubdiv_Buffer *patch_index_buffer)
|
||||
{
|
||||
implementation_->wrapPatchIndexBuffer(patch_index_buffer);
|
||||
}
|
||||
|
||||
void EvalOutputAPI::wrapPatchParamBuffer(OpenSubdiv_Buffer *patch_param_buffer)
|
||||
{
|
||||
implementation_->wrapPatchParamBuffer(patch_param_buffer);
|
||||
}
|
||||
|
||||
void EvalOutputAPI::wrapSrcBuffer(OpenSubdiv_Buffer *src_buffer)
|
||||
{
|
||||
implementation_->wrapSrcBuffer(src_buffer);
|
||||
}
|
||||
|
||||
void EvalOutputAPI::fillFVarPatchArraysBuffer(const int face_varying_channel,
|
||||
OpenSubdiv_Buffer *patch_arrays_buffer)
|
||||
{
|
||||
implementation_->fillFVarPatchArraysBuffer(face_varying_channel, patch_arrays_buffer);
|
||||
}
|
||||
|
||||
void EvalOutputAPI::wrapFVarPatchIndexBuffer(const int face_varying_channel,
|
||||
OpenSubdiv_Buffer *patch_index_buffer)
|
||||
{
|
||||
implementation_->wrapFVarPatchIndexBuffer(face_varying_channel, patch_index_buffer);
|
||||
}
|
||||
|
||||
void EvalOutputAPI::wrapFVarPatchParamBuffer(const int face_varying_channel,
|
||||
OpenSubdiv_Buffer *patch_param_buffer)
|
||||
{
|
||||
implementation_->wrapFVarPatchParamBuffer(face_varying_channel, patch_param_buffer);
|
||||
}
|
||||
|
||||
void EvalOutputAPI::wrapFVarSrcBuffer(const int face_varying_channel,
|
||||
OpenSubdiv_Buffer *src_buffer)
|
||||
{
|
||||
implementation_->wrapFVarSrcBuffer(face_varying_channel, src_buffer);
|
||||
}
|
||||
|
||||
} // namespace opensubdiv
|
||||
} // namespace blender
|
||||
|
||||
@@ -763,8 +401,15 @@ OpenSubdiv_EvaluatorImpl::~OpenSubdiv_EvaluatorImpl()
|
||||
}
|
||||
|
||||
OpenSubdiv_EvaluatorImpl *openSubdiv_createEvaluatorInternal(
|
||||
OpenSubdiv_TopologyRefiner *topology_refiner)
|
||||
OpenSubdiv_TopologyRefiner *topology_refiner,
|
||||
eOpenSubdivEvaluator evaluator_type,
|
||||
OpenSubdiv_EvaluatorCacheImpl *evaluator_cache_descr)
|
||||
{
|
||||
// Only CPU and GLCompute are implemented at the moment.
|
||||
if (evaluator_type != OPENSUBDIV_EVALUATOR_CPU &&
|
||||
evaluator_type != OPENSUBDIV_EVALUATOR_GLSL_COMPUTE) {
|
||||
return NULL;
|
||||
}
|
||||
using blender::opensubdiv::vector;
|
||||
TopologyRefiner *refiner = topology_refiner->impl->topology_refiner;
|
||||
if (refiner == NULL) {
|
||||
@@ -867,14 +512,34 @@ OpenSubdiv_EvaluatorImpl *openSubdiv_createEvaluatorInternal(
|
||||
}
|
||||
}
|
||||
// Create OpenSubdiv's CPU side evaluator.
|
||||
// TODO(sergey): Make it possible to use different evaluators.
|
||||
blender::opensubdiv::CpuEvalOutput *eval_output = new blender::opensubdiv::CpuEvalOutput(
|
||||
vertex_stencils, varying_stencils, all_face_varying_stencils, 2, patch_table);
|
||||
OpenSubdiv::Far::PatchMap *patch_map = new PatchMap(*patch_table);
|
||||
blender::opensubdiv::EvalOutputAPI::EvalOutput *eval_output = nullptr;
|
||||
|
||||
const bool use_gl_evaluator = evaluator_type == OPENSUBDIV_EVALUATOR_GLSL_COMPUTE;
|
||||
if (use_gl_evaluator) {
|
||||
blender::opensubdiv::GpuEvalOutput::EvaluatorCache *evaluator_cache = nullptr;
|
||||
if (evaluator_cache_descr) {
|
||||
evaluator_cache = static_cast<blender::opensubdiv::GpuEvalOutput::EvaluatorCache *>(
|
||||
evaluator_cache_descr->eval_cache);
|
||||
}
|
||||
|
||||
eval_output = new blender::opensubdiv::GpuEvalOutput(vertex_stencils,
|
||||
varying_stencils,
|
||||
all_face_varying_stencils,
|
||||
2,
|
||||
patch_table,
|
||||
evaluator_cache);
|
||||
}
|
||||
else {
|
||||
eval_output = new blender::opensubdiv::CpuEvalOutput(
|
||||
vertex_stencils, varying_stencils, all_face_varying_stencils, 2, patch_table);
|
||||
}
|
||||
|
||||
blender::opensubdiv::PatchMap *patch_map = new blender::opensubdiv::PatchMap(*patch_table);
|
||||
// Wrap everything we need into an object which we control from our side.
|
||||
OpenSubdiv_EvaluatorImpl *evaluator_descr;
|
||||
evaluator_descr = new OpenSubdiv_EvaluatorImpl();
|
||||
evaluator_descr->eval_output = new blender::opensubdiv::CpuEvalOutputAPI(eval_output, patch_map);
|
||||
|
||||
evaluator_descr->eval_output = new blender::opensubdiv::EvalOutputAPI(eval_output, patch_map);
|
||||
evaluator_descr->patch_map = patch_map;
|
||||
evaluator_descr->patch_table = patch_table;
|
||||
// TOOD(sergey): Look into whether we've got duplicated stencils arrays.
|
||||
|
@@ -28,14 +28,17 @@
|
||||
|
||||
#include "internal/base/memory.h"
|
||||
|
||||
#include "opensubdiv_capi_type.h"
|
||||
|
||||
struct OpenSubdiv_Buffer;
|
||||
struct OpenSubdiv_EvaluatorCacheImpl;
|
||||
struct OpenSubdiv_PatchCoord;
|
||||
struct OpenSubdiv_TopologyRefiner;
|
||||
|
||||
namespace blender {
|
||||
namespace opensubdiv {
|
||||
|
||||
// Anonymous forward declaration of actual evaluator implementation.
|
||||
class CpuEvalOutput;
|
||||
class PatchMap;
|
||||
|
||||
// Wrapper around implementation, which defines API which we are capable to
|
||||
// provide over the implementation.
|
||||
@@ -43,11 +46,15 @@ class CpuEvalOutput;
|
||||
// TODO(sergey): It is almost the same as C-API object, so ideally need to
|
||||
// merge them somehow, but how to do this and keep files with all the templates
|
||||
// and such separate?
|
||||
class CpuEvalOutputAPI {
|
||||
class EvalOutputAPI {
|
||||
public:
|
||||
// NOTE: API object becomes an owner of evaluator. Patch we are referencing.
|
||||
CpuEvalOutputAPI(CpuEvalOutput *implementation, OpenSubdiv::Far::PatchMap *patch_map);
|
||||
~CpuEvalOutputAPI();
|
||||
// Anonymous forward declaration of actual evaluator implementation.
|
||||
class EvalOutput;
|
||||
|
||||
// NOTE: PatchMap is not owned, only referenced.
|
||||
EvalOutputAPI(EvalOutput *implementation, PatchMap *patch_map);
|
||||
|
||||
~EvalOutputAPI();
|
||||
|
||||
// Set coarse positions from a continuous array of coordinates.
|
||||
void setCoarsePositions(const float *positions,
|
||||
@@ -130,9 +137,47 @@ class CpuEvalOutputAPI {
|
||||
float *dPdu,
|
||||
float *dPdv);
|
||||
|
||||
// Fill the output buffers and variables with data from the PatchMap.
|
||||
void getPatchMap(OpenSubdiv_Buffer *patch_map_handles,
|
||||
OpenSubdiv_Buffer *patch_map_quadtree,
|
||||
int *min_patch_face,
|
||||
int *max_patch_face,
|
||||
int *max_depth,
|
||||
int *patches_are_triangular);
|
||||
|
||||
// Copy the patch arrays buffer used by OpenSubDiv for the source data to the given buffer.
|
||||
void fillPatchArraysBuffer(OpenSubdiv_Buffer *patch_arrays_buffer);
|
||||
|
||||
// Wrap the patch index buffer used by OpenSubDiv for the source data with the given buffer.
|
||||
void wrapPatchIndexBuffer(OpenSubdiv_Buffer *patch_index_buffer);
|
||||
|
||||
// Wrap the patch param buffer used by OpenSubDiv for the source data with the given buffer.
|
||||
void wrapPatchParamBuffer(OpenSubdiv_Buffer *patch_param_buffer);
|
||||
|
||||
// Wrap the buffer used by OpenSubDiv for the source data with the given buffer.
|
||||
void wrapSrcBuffer(OpenSubdiv_Buffer *src_buffer);
|
||||
|
||||
// Copy the patch arrays buffer used by OpenSubDiv for the face varying channel with the given
|
||||
// buffer.
|
||||
void fillFVarPatchArraysBuffer(const int face_varying_channel,
|
||||
OpenSubdiv_Buffer *patch_arrays_buffer);
|
||||
|
||||
// Wrap the patch index buffer used by OpenSubDiv for the face varying channel with the given
|
||||
// buffer.
|
||||
void wrapFVarPatchIndexBuffer(const int face_varying_channel,
|
||||
OpenSubdiv_Buffer *patch_index_buffer);
|
||||
|
||||
// Wrap the patch param buffer used by OpenSubDiv for the face varying channel with the given
|
||||
// buffer.
|
||||
void wrapFVarPatchParamBuffer(const int face_varying_channel,
|
||||
OpenSubdiv_Buffer *patch_param_buffer);
|
||||
|
||||
// Wrap thebuffer used by OpenSubDiv for the face varying channel with the given buffer.
|
||||
void wrapFVarSrcBuffer(const int face_varying_channel, OpenSubdiv_Buffer *src_buffer);
|
||||
|
||||
protected:
|
||||
CpuEvalOutput *implementation_;
|
||||
OpenSubdiv::Far::PatchMap *patch_map_;
|
||||
PatchMap *patch_map_;
|
||||
EvalOutput *implementation_;
|
||||
};
|
||||
|
||||
} // namespace opensubdiv
|
||||
@@ -143,15 +188,17 @@ struct OpenSubdiv_EvaluatorImpl {
|
||||
OpenSubdiv_EvaluatorImpl();
|
||||
~OpenSubdiv_EvaluatorImpl();
|
||||
|
||||
blender::opensubdiv::CpuEvalOutputAPI *eval_output;
|
||||
const OpenSubdiv::Far::PatchMap *patch_map;
|
||||
blender::opensubdiv::EvalOutputAPI *eval_output;
|
||||
const blender::opensubdiv::PatchMap *patch_map;
|
||||
const OpenSubdiv::Far::PatchTable *patch_table;
|
||||
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("OpenSubdiv_EvaluatorImpl");
|
||||
};
|
||||
|
||||
OpenSubdiv_EvaluatorImpl *openSubdiv_createEvaluatorInternal(
|
||||
struct OpenSubdiv_TopologyRefiner *topology_refiner);
|
||||
struct OpenSubdiv_TopologyRefiner *topology_refiner,
|
||||
eOpenSubdivEvaluator evaluator_type,
|
||||
OpenSubdiv_EvaluatorCacheImpl *evaluator_cache_descr);
|
||||
|
||||
void openSubdiv_deleteEvaluatorInternal(OpenSubdiv_EvaluatorImpl *evaluator);
|
||||
|
||||
|
212
intern/opensubdiv/internal/evaluator/patch_map.cc
Normal file
212
intern/opensubdiv/internal/evaluator/patch_map.cc
Normal file
@@ -0,0 +1,212 @@
|
||||
// Original code copyright 2013 Pixar.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
// with the following modification; you may not use this file except in
|
||||
// compliance with the Apache License and the following modification to it:
|
||||
// Section 6. Trademarks. is deleted and replaced with:
|
||||
//
|
||||
// 6. Trademarks. This License does not grant permission to use the trade
|
||||
// names, trademarks, service marks, or product names of the Licensor
|
||||
// and its affiliates, except as required to comply with Section 4(c) of
|
||||
// the License and to reproduce the content of the NOTICE file.
|
||||
//
|
||||
// You may obtain a copy of the Apache License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the Apache License with the above modification is
|
||||
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the Apache License for the specific
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
// Modifications copyright 2021 Blender Foundation. All rights reserved.
|
||||
|
||||
#include "internal/evaluator/patch_map.h"
|
||||
|
||||
using OpenSubdiv::Far::ConstPatchParamArray;
|
||||
using OpenSubdiv::Far::Index;
|
||||
using OpenSubdiv::Far::PatchParam;
|
||||
using OpenSubdiv::Far::PatchParamTable;
|
||||
using OpenSubdiv::Far::PatchTable;
|
||||
|
||||
namespace blender {
|
||||
namespace opensubdiv {
|
||||
|
||||
//
|
||||
// Inline quadtree assembly methods used by the constructor:
|
||||
//
|
||||
|
||||
// sets all the children to point to the patch of given index
|
||||
inline void PatchMap::QuadNode::SetChildren(int index)
|
||||
{
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
children[i].isSet = true;
|
||||
children[i].isLeaf = true;
|
||||
children[i].index = index;
|
||||
}
|
||||
}
|
||||
|
||||
// sets the child in "quadrant" to point to the node or patch of the given index
|
||||
inline void PatchMap::QuadNode::SetChild(int quadrant, int index, bool isLeaf)
|
||||
{
|
||||
|
||||
assert(!children[quadrant].isSet);
|
||||
children[quadrant].isSet = true;
|
||||
children[quadrant].isLeaf = isLeaf;
|
||||
children[quadrant].index = index;
|
||||
}
|
||||
|
||||
inline void PatchMap::assignRootNode(QuadNode *node, int index)
|
||||
{
|
||||
|
||||
// Assign the given index to all children of the node (all leaves)
|
||||
node->SetChildren(index);
|
||||
}
|
||||
|
||||
inline PatchMap::QuadNode *PatchMap::assignLeafOrChildNode(QuadNode *node,
|
||||
bool isLeaf,
|
||||
int quadrant,
|
||||
int index)
|
||||
{
|
||||
|
||||
// Assign the node given if it is a leaf node, otherwise traverse
|
||||
// the node -- creating/assigning a new child node if needed
|
||||
|
||||
if (isLeaf) {
|
||||
node->SetChild(quadrant, index, true);
|
||||
return node;
|
||||
}
|
||||
if (node->children[quadrant].isSet) {
|
||||
return &_quadtree[node->children[quadrant].index];
|
||||
}
|
||||
else {
|
||||
int newChildNodeIndex = (int)_quadtree.size();
|
||||
_quadtree.push_back(QuadNode());
|
||||
node->SetChild(quadrant, newChildNodeIndex, false);
|
||||
return &_quadtree[newChildNodeIndex];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Constructor and initialization methods for the handles and quadtree:
|
||||
//
|
||||
PatchMap::PatchMap(PatchTable const &patchTable)
|
||||
: _minPatchFace(-1), _maxPatchFace(-1), _maxDepth(0)
|
||||
{
|
||||
|
||||
_patchesAreTriangular = patchTable.GetVaryingPatchDescriptor().GetNumControlVertices() == 3;
|
||||
|
||||
if (patchTable.GetNumPatchesTotal() > 0) {
|
||||
initializeHandles(patchTable);
|
||||
initializeQuadtree(patchTable);
|
||||
}
|
||||
}
|
||||
|
||||
void PatchMap::initializeHandles(PatchTable const &patchTable)
|
||||
{
|
||||
|
||||
//
|
||||
// Populate the vector of patch Handles. Keep track of the min and max
|
||||
// face indices to allocate resources accordingly and limit queries:
|
||||
//
|
||||
_minPatchFace = (int)patchTable.GetPatchParamTable()[0].GetFaceId();
|
||||
_maxPatchFace = _minPatchFace;
|
||||
|
||||
int numArrays = (int)patchTable.GetNumPatchArrays();
|
||||
int numPatches = (int)patchTable.GetNumPatchesTotal();
|
||||
|
||||
_handles.resize(numPatches);
|
||||
|
||||
for (int pArray = 0, handleIndex = 0; pArray < numArrays; ++pArray) {
|
||||
|
||||
ConstPatchParamArray params = patchTable.GetPatchParams(pArray);
|
||||
|
||||
int patchSize = patchTable.GetPatchArrayDescriptor(pArray).GetNumControlVertices();
|
||||
|
||||
for (Index j = 0; j < patchTable.GetNumPatches(pArray); ++j, ++handleIndex) {
|
||||
|
||||
Handle &h = _handles[handleIndex];
|
||||
|
||||
h.arrayIndex = pArray;
|
||||
h.patchIndex = handleIndex;
|
||||
h.vertIndex = j * patchSize;
|
||||
|
||||
int patchFaceId = params[j].GetFaceId();
|
||||
_minPatchFace = std::min(_minPatchFace, patchFaceId);
|
||||
_maxPatchFace = std::max(_maxPatchFace, patchFaceId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PatchMap::initializeQuadtree(PatchTable const &patchTable)
|
||||
{
|
||||
|
||||
//
|
||||
// Reserve quadtree nodes for the worst case and prune later. Set the
|
||||
// initial size to accomodate the root node of each patch face:
|
||||
//
|
||||
int nPatchFaces = (_maxPatchFace - _minPatchFace) + 1;
|
||||
|
||||
int nHandles = (int)_handles.size();
|
||||
|
||||
_quadtree.reserve(nPatchFaces + nHandles);
|
||||
_quadtree.resize(nPatchFaces);
|
||||
|
||||
PatchParamTable const ¶ms = patchTable.GetPatchParamTable();
|
||||
|
||||
for (int handle = 0; handle < nHandles; ++handle) {
|
||||
|
||||
PatchParam const ¶m = params[handle];
|
||||
|
||||
int depth = param.GetDepth();
|
||||
int rootDepth = param.NonQuadRoot();
|
||||
|
||||
_maxDepth = std::max(_maxDepth, depth);
|
||||
|
||||
QuadNode *node = &_quadtree[param.GetFaceId() - _minPatchFace];
|
||||
|
||||
if (depth == rootDepth) {
|
||||
assignRootNode(node, handle);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!_patchesAreTriangular) {
|
||||
// Use the UV bits of the PatchParam directly for quad patches:
|
||||
int u = param.GetU();
|
||||
int v = param.GetV();
|
||||
|
||||
for (int j = rootDepth + 1; j <= depth; ++j) {
|
||||
int uBit = (u >> (depth - j)) & 1;
|
||||
int vBit = (v >> (depth - j)) & 1;
|
||||
|
||||
int quadrant = (vBit << 1) | uBit;
|
||||
|
||||
node = assignLeafOrChildNode(node, (j == depth), quadrant, handle);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Use an interior UV point of triangles to identify quadrants:
|
||||
double u = 0.25;
|
||||
double v = 0.25;
|
||||
param.UnnormalizeTriangle(u, v);
|
||||
|
||||
double median = 0.5;
|
||||
bool triRotated = false;
|
||||
|
||||
for (int j = rootDepth + 1; j <= depth; ++j, median *= 0.5) {
|
||||
int quadrant = transformUVToTriQuadrant(median, u, v, triRotated);
|
||||
|
||||
node = assignLeafOrChildNode(node, (j == depth), quadrant, handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Swap the Node vector with a copy to reduce worst case memory allocation:
|
||||
QuadTree tmpTree = _quadtree;
|
||||
_quadtree.swap(tmpTree);
|
||||
}
|
||||
|
||||
} // namespace opensubdiv
|
||||
} // namespace blender
|
264
intern/opensubdiv/internal/evaluator/patch_map.h
Normal file
264
intern/opensubdiv/internal/evaluator/patch_map.h
Normal file
@@ -0,0 +1,264 @@
|
||||
// Original code copyright 2013 Pixar.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
// with the following modification; you may not use this file except in
|
||||
// compliance with the Apache License and the following modification to it:
|
||||
// Section 6. Trademarks. is deleted and replaced with:
|
||||
//
|
||||
// 6. Trademarks. This License does not grant permission to use the trade
|
||||
// names, trademarks, service marks, or product names of the Licensor
|
||||
// and its affiliates, except as required to comply with Section 4(c) of
|
||||
// the License and to reproduce the content of the NOTICE file.
|
||||
//
|
||||
// You may obtain a copy of the Apache License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the Apache License with the above modification is
|
||||
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the Apache License for the specific
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
// Modifications copyright 2021 Blender Foundation. All rights reserved.
|
||||
|
||||
#ifndef OPENSUBDIV_PATCH_MAP_H_
|
||||
#define OPENSUBDIV_PATCH_MAP_H_
|
||||
|
||||
#include <opensubdiv/far/patchTable.h>
|
||||
|
||||
namespace blender {
|
||||
namespace opensubdiv {
|
||||
|
||||
/// \brief An quadtree-based map connecting coarse faces to their sub-patches
|
||||
///
|
||||
/// PatchTable::PatchArrays contain lists of patches that represent the limit
|
||||
/// surface of a mesh, sorted by their topological type. These arrays break the
|
||||
/// connection between coarse faces and their sub-patches.
|
||||
///
|
||||
/// The PatchMap provides a quad-tree based lookup structure that, given a singular
|
||||
/// parametric location, can efficiently return a handle to the sub-patch that
|
||||
/// contains this location.
|
||||
///
|
||||
class PatchMap {
|
||||
public:
|
||||
// Quadtree node with 4 children, tree is just a vector of nodes
|
||||
struct QuadNode {
|
||||
QuadNode()
|
||||
{
|
||||
std::memset(this, 0, sizeof(QuadNode));
|
||||
}
|
||||
|
||||
struct Child {
|
||||
unsigned int isSet : 1; // true if the child has been set
|
||||
unsigned int isLeaf : 1; // true if the child is a QuadNode
|
||||
unsigned int index : 30; // child index (either QuadNode or Handle)
|
||||
};
|
||||
|
||||
// sets all the children to point to the patch of given index
|
||||
void SetChildren(int index);
|
||||
|
||||
// sets the child in "quadrant" to point to the node or patch of the given index
|
||||
void SetChild(int quadrant, int index, bool isLeaf);
|
||||
|
||||
Child children[4];
|
||||
};
|
||||
|
||||
typedef OpenSubdiv::Far::PatchTable::PatchHandle Handle;
|
||||
|
||||
/// \brief Constructor
|
||||
///
|
||||
/// @param patchTable A valid PatchTable
|
||||
///
|
||||
PatchMap(OpenSubdiv::Far::PatchTable const &patchTable);
|
||||
|
||||
/// \brief Returns a handle to the sub-patch of the face at the given (u,v).
|
||||
/// Note that the patch face ID corresponds to potentially quadrangulated
|
||||
/// face indices and not the base face indices (see Far::PtexIndices for more
|
||||
/// details).
|
||||
///
|
||||
/// @param patchFaceId The index of the patch (Ptex) face
|
||||
///
|
||||
/// @param u Local u parameter
|
||||
///
|
||||
/// @param v Local v parameter
|
||||
///
|
||||
/// @return A patch handle or 0 if the face is not supported (index
|
||||
/// out of bounds) or is tagged as a hole
|
||||
///
|
||||
Handle const *FindPatch(int patchFaceId, double u, double v) const;
|
||||
|
||||
int getMinPatchFace() const
|
||||
{
|
||||
return _minPatchFace;
|
||||
}
|
||||
|
||||
int getMaxPatchFace() const
|
||||
{
|
||||
return _maxPatchFace;
|
||||
}
|
||||
|
||||
int getMaxDepth() const
|
||||
{
|
||||
return _maxDepth;
|
||||
}
|
||||
|
||||
bool getPatchesAreTriangular() const
|
||||
{
|
||||
return _patchesAreTriangular;
|
||||
}
|
||||
|
||||
const std::vector<Handle> &getHandles()
|
||||
{
|
||||
return _handles;
|
||||
}
|
||||
|
||||
const std::vector<QuadNode> &nodes()
|
||||
{
|
||||
return _quadtree;
|
||||
}
|
||||
|
||||
private:
|
||||
void initializeHandles(OpenSubdiv::Far::PatchTable const &patchTable);
|
||||
void initializeQuadtree(OpenSubdiv::Far::PatchTable const &patchTable);
|
||||
|
||||
typedef std::vector<QuadNode> QuadTree;
|
||||
|
||||
// Internal methods supporting quadtree construction and queries
|
||||
void assignRootNode(QuadNode *node, int index);
|
||||
QuadNode *assignLeafOrChildNode(QuadNode *node, bool isLeaf, int quad, int index);
|
||||
|
||||
template<class T> static int transformUVToQuadQuadrant(T const &median, T &u, T &v);
|
||||
template<class T>
|
||||
static int transformUVToTriQuadrant(T const &median, T &u, T &v, bool &rotated);
|
||||
|
||||
private:
|
||||
bool _patchesAreTriangular; // tri and quad assembly and search requirements differ
|
||||
|
||||
int _minPatchFace; // minimum patch face index supported by the map
|
||||
int _maxPatchFace; // maximum patch face index supported by the map
|
||||
int _maxDepth; // maximum depth of a patch in the tree
|
||||
|
||||
std::vector<Handle> _handles; // all the patches in the PatchTable
|
||||
std::vector<QuadNode> _quadtree; // quadtree nodes
|
||||
};
|
||||
|
||||
//
|
||||
// Given a median value for both U and V, these methods transform a (u,v) pair
|
||||
// into the quadrant that contains them and returns the quadrant index.
|
||||
//
|
||||
// Quadrant indexing for tri and quad patches -- consistent with PatchParam's
|
||||
// usage of UV bits:
|
||||
//
|
||||
// (0,1) o-----o-----o (1,1) (0,1) o (1,0) o-----o-----o (0,0)
|
||||
// | | | |\ \ 1 |\ 0 |
|
||||
// | 2 | 3 | | \ \ | \ |
|
||||
// | | | | 2 \ \| 3 \|
|
||||
// o-----o-----o o-----o o-----o
|
||||
// | | | |\ 3 |\ \ 2 |
|
||||
// | 0 | 1 | | \ | \ \ |
|
||||
// | | | | 0 \| 1 \ \|
|
||||
// (0,0) o-----o-----o (1,0) (0,0) o-----o-----o (1,0) o (0,1)
|
||||
//
|
||||
// The triangular case also takes and returns/affects the rotation of the
|
||||
// quadrant being searched and identified (quadrant 3 imparts a rotation).
|
||||
//
|
||||
template<class T> inline int PatchMap::transformUVToQuadQuadrant(T const &median, T &u, T &v)
|
||||
{
|
||||
|
||||
int uHalf = (u >= median);
|
||||
if (uHalf)
|
||||
u -= median;
|
||||
|
||||
int vHalf = (v >= median);
|
||||
if (vHalf)
|
||||
v -= median;
|
||||
|
||||
return (vHalf << 1) | uHalf;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
int inline PatchMap::transformUVToTriQuadrant(T const &median, T &u, T &v, bool &rotated)
|
||||
{
|
||||
|
||||
if (!rotated) {
|
||||
if (u >= median) {
|
||||
u -= median;
|
||||
return 1;
|
||||
}
|
||||
if (v >= median) {
|
||||
v -= median;
|
||||
return 2;
|
||||
}
|
||||
if ((u + v) >= median) {
|
||||
rotated = true;
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
if (u < median) {
|
||||
v -= median;
|
||||
return 1;
|
||||
}
|
||||
if (v < median) {
|
||||
u -= median;
|
||||
return 2;
|
||||
}
|
||||
u -= median;
|
||||
v -= median;
|
||||
if ((u + v) < median) {
|
||||
rotated = false;
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a handle to the sub-patch of the face at the given (u,v).
|
||||
inline PatchMap::Handle const *PatchMap::FindPatch(int faceid, double u, double v) const
|
||||
{
|
||||
|
||||
//
|
||||
// Reject patch faces not supported by this map, or those corresponding
|
||||
// to holes or otherwise unassigned (the root node for a patch will
|
||||
// have all or no quadrants set):
|
||||
//
|
||||
if ((faceid < _minPatchFace) || (faceid > _maxPatchFace))
|
||||
return 0;
|
||||
|
||||
QuadNode const *node = &_quadtree[faceid - _minPatchFace];
|
||||
|
||||
if (!node->children[0].isSet)
|
||||
return 0;
|
||||
|
||||
//
|
||||
// Search the tree for the sub-patch containing the given (u,v)
|
||||
//
|
||||
assert((u >= 0.0) && (u <= 1.0) && (v >= 0.0) && (v <= 1.0));
|
||||
|
||||
double median = 0.5;
|
||||
bool triRotated = false;
|
||||
|
||||
for (int depth = 0; depth <= _maxDepth; ++depth, median *= 0.5) {
|
||||
|
||||
int quadrant = _patchesAreTriangular ? transformUVToTriQuadrant(median, u, v, triRotated) :
|
||||
transformUVToQuadQuadrant(median, u, v);
|
||||
|
||||
// holes should have been rejected at the root node of the face
|
||||
assert(node->children[quadrant].isSet);
|
||||
|
||||
if (node->children[quadrant].isLeaf) {
|
||||
return &_handles[node->children[quadrant].index];
|
||||
}
|
||||
else {
|
||||
node = &_quadtree[node->children[quadrant].index];
|
||||
}
|
||||
}
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
} // namespace opensubdiv
|
||||
} // namespace blender
|
||||
|
||||
#endif // OPENSUBDIV_PATCH_MAP_H_
|
@@ -225,7 +225,7 @@ void assignFunctionPointers(OpenSubdiv_TopologyRefiner *topology_refiner)
|
||||
|
||||
OpenSubdiv_TopologyRefiner *allocateTopologyRefiner()
|
||||
{
|
||||
OpenSubdiv_TopologyRefiner *topology_refiner = OBJECT_GUARDED_NEW(OpenSubdiv_TopologyRefiner);
|
||||
OpenSubdiv_TopologyRefiner *topology_refiner = MEM_new<OpenSubdiv_TopologyRefiner>(__func__);
|
||||
assignFunctionPointers(topology_refiner);
|
||||
return topology_refiner;
|
||||
}
|
||||
@@ -252,7 +252,7 @@ OpenSubdiv_TopologyRefiner *openSubdiv_createTopologyRefinerFromConverter(
|
||||
void openSubdiv_deleteTopologyRefiner(OpenSubdiv_TopologyRefiner *topology_refiner)
|
||||
{
|
||||
delete topology_refiner->impl;
|
||||
OBJECT_GUARDED_DELETE(topology_refiner, OpenSubdiv_TopologyRefiner);
|
||||
MEM_delete(topology_refiner);
|
||||
}
|
||||
|
||||
bool openSubdiv_topologyRefinerCompareWithConverter(
|
||||
|
@@ -19,6 +19,10 @@
|
||||
#ifndef OPENSUBDIV_EVALUATOR_CAPI_H_
|
||||
#define OPENSUBDIV_EVALUATOR_CAPI_H_
|
||||
|
||||
#include <stdint.h> // for uint64_t
|
||||
|
||||
#include "opensubdiv_capi_type.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -27,6 +31,38 @@ struct OpenSubdiv_EvaluatorInternal;
|
||||
struct OpenSubdiv_PatchCoord;
|
||||
struct OpenSubdiv_TopologyRefiner;
|
||||
|
||||
// Callback type for doing input/output operations on buffers.
|
||||
// Useful to abstract GPU buffers.
|
||||
typedef struct OpenSubdiv_Buffer {
|
||||
// Bind the buffer to the GPU.
|
||||
void (*bind_gpu)(const struct OpenSubdiv_Buffer *buffer);
|
||||
|
||||
// Allocate the buffer directly on the host for the given size in bytes. This has to return
|
||||
// a pointer to the newly allocated memory.
|
||||
void *(*alloc)(const struct OpenSubdiv_Buffer *buffer, const unsigned int size);
|
||||
|
||||
// Allocate the buffer directly on the device for the given size in bytes.
|
||||
void (*device_alloc)(const struct OpenSubdiv_Buffer *buffer, const unsigned int size);
|
||||
|
||||
// Update the given range of the buffer with new data.
|
||||
void (*device_update)(const struct OpenSubdiv_Buffer *buffer,
|
||||
unsigned int start,
|
||||
unsigned int len,
|
||||
const void *data);
|
||||
|
||||
// Wrap an existing GPU buffer, given its device handle, into the client's buffer type for
|
||||
// read-only use.
|
||||
void (*wrap_device_handle)(const struct OpenSubdiv_Buffer *buffer, uint64_t device_ptr);
|
||||
|
||||
// Offset in the buffer where the data starts, if a single buffer is used for multiple data
|
||||
// channels.
|
||||
int buffer_offset;
|
||||
|
||||
// Pointer to the client buffer data, which is modified or initialized through the various
|
||||
// callbacks.
|
||||
void *data;
|
||||
} OpenSubdiv_Buffer;
|
||||
|
||||
typedef struct OpenSubdiv_Evaluator {
|
||||
// Set coarse positions from a continuous array of coordinates.
|
||||
void (*setCoarsePositions)(struct OpenSubdiv_Evaluator *evaluator,
|
||||
@@ -122,15 +158,78 @@ typedef struct OpenSubdiv_Evaluator {
|
||||
float *dPdu,
|
||||
float *dPdv);
|
||||
|
||||
// Copy the patch map to the given buffers, and output some topology information.
|
||||
void (*getPatchMap)(struct OpenSubdiv_Evaluator *evaluator,
|
||||
struct OpenSubdiv_Buffer *patch_map_handles,
|
||||
struct OpenSubdiv_Buffer *patch_map_quadtree,
|
||||
int *min_patch_face,
|
||||
int *max_patch_face,
|
||||
int *max_depth,
|
||||
int *patches_are_triangular);
|
||||
|
||||
// Fill the given buffer with data from the evaluator's patch array buffer.
|
||||
void (*fillPatchArraysBuffer)(struct OpenSubdiv_Evaluator *evaluator,
|
||||
struct OpenSubdiv_Buffer *patch_array_buffer);
|
||||
|
||||
// Fill the given buffer with data from the evaluator's patch index buffer.
|
||||
void (*wrapPatchIndexBuffer)(struct OpenSubdiv_Evaluator *evaluator,
|
||||
struct OpenSubdiv_Buffer *patch_index_buffer);
|
||||
|
||||
// Fill the given buffer with data from the evaluator's patch parameter buffer.
|
||||
void (*wrapPatchParamBuffer)(struct OpenSubdiv_Evaluator *evaluator,
|
||||
struct OpenSubdiv_Buffer *patch_param_buffer);
|
||||
|
||||
// Fill the given buffer with data from the evaluator's source buffer.
|
||||
void (*wrapSrcBuffer)(struct OpenSubdiv_Evaluator *evaluator,
|
||||
struct OpenSubdiv_Buffer *src_buffer);
|
||||
|
||||
// Fill the given buffer with data from the evaluator's face varying patch array buffer.
|
||||
void (*fillFVarPatchArraysBuffer)(struct OpenSubdiv_Evaluator *evaluator,
|
||||
const int face_varying_channel,
|
||||
struct OpenSubdiv_Buffer *patch_array_buffer);
|
||||
|
||||
// Fill the given buffer with data from the evaluator's face varying patch index buffer.
|
||||
void (*wrapFVarPatchIndexBuffer)(struct OpenSubdiv_Evaluator *evaluator,
|
||||
const int face_varying_channel,
|
||||
struct OpenSubdiv_Buffer *patch_index_buffer);
|
||||
|
||||
// Fill the given buffer with data from the evaluator's face varying patch parameter buffer.
|
||||
void (*wrapFVarPatchParamBuffer)(struct OpenSubdiv_Evaluator *evaluator,
|
||||
const int face_varying_channel,
|
||||
struct OpenSubdiv_Buffer *patch_param_buffer);
|
||||
|
||||
// Fill the given buffer with data from the evaluator's face varying source buffer.
|
||||
void (*wrapFVarSrcBuffer)(struct OpenSubdiv_Evaluator *evaluator,
|
||||
const int face_varying_channel,
|
||||
struct OpenSubdiv_Buffer *src_buffer);
|
||||
|
||||
// Implementation of the evaluator.
|
||||
struct OpenSubdiv_EvaluatorImpl *impl;
|
||||
|
||||
// Type of the evaluator.
|
||||
eOpenSubdivEvaluator type;
|
||||
} OpenSubdiv_Evaluator;
|
||||
|
||||
typedef struct OpenSubdiv_EvaluatorCache {
|
||||
// Implementation of the evaluator cache.
|
||||
struct OpenSubdiv_EvaluatorCacheImpl *impl;
|
||||
} OpenSubdiv_EvaluatorCache;
|
||||
|
||||
OpenSubdiv_Evaluator *openSubdiv_createEvaluatorFromTopologyRefiner(
|
||||
struct OpenSubdiv_TopologyRefiner *topology_refiner);
|
||||
struct OpenSubdiv_TopologyRefiner *topology_refiner,
|
||||
eOpenSubdivEvaluator evaluator_type,
|
||||
OpenSubdiv_EvaluatorCache *evaluator_cache);
|
||||
|
||||
void openSubdiv_deleteEvaluator(OpenSubdiv_Evaluator *evaluator);
|
||||
|
||||
OpenSubdiv_EvaluatorCache *openSubdiv_createEvaluatorCache(eOpenSubdivEvaluator evaluator_type);
|
||||
|
||||
void openSubdiv_deleteEvaluatorCache(OpenSubdiv_EvaluatorCache *evaluator_cache);
|
||||
|
||||
// Return the GLSL source code from the OpenSubDiv library used for patch evaluation.
|
||||
// This function is not thread-safe.
|
||||
const char *openSubdiv_getGLSLPatchBasisSource(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -21,7 +21,9 @@
|
||||
#include <cstddef>
|
||||
|
||||
OpenSubdiv_Evaluator *openSubdiv_createEvaluatorFromTopologyRefiner(
|
||||
struct OpenSubdiv_TopologyRefiner * /*topology_refiner*/)
|
||||
struct OpenSubdiv_TopologyRefiner * /*topology_refiner*/,
|
||||
eOpenSubdivEvaluator /*evaluator_type*/,
|
||||
OpenSubdiv_EvaluatorCache * /*evaluator_cache*/)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -29,3 +31,17 @@ OpenSubdiv_Evaluator *openSubdiv_createEvaluatorFromTopologyRefiner(
|
||||
void openSubdiv_deleteEvaluator(OpenSubdiv_Evaluator * /*evaluator*/)
|
||||
{
|
||||
}
|
||||
|
||||
OpenSubdiv_EvaluatorCache *openSubdiv_createEvaluatorCache(eOpenSubdivEvaluator /*evaluator_type*/)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void openSubdiv_deleteEvaluatorCache(OpenSubdiv_EvaluatorCache * /*evaluator_cache*/)
|
||||
{
|
||||
}
|
||||
|
||||
const char *openSubdiv_getGLSLPatchBasisSource()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
Submodule release/datafiles/locale updated: 9d270fd007...620b85f16d
@@ -61,7 +61,7 @@ const UserDef U_default = {
|
||||
USER_HIDE_DOT | USER_SHOW_GIZMO_NAVIGATE | USER_SHOW_VIEWPORTNAME | USER_SHOW_FPS |
|
||||
USER_CONTINUOUS_MOUSE | USER_SAVE_PROMPT),
|
||||
.uiflag2 = USER_REGION_OVERLAP,
|
||||
.gpu_flag = USER_GPU_FLAG_OVERLAY_SMOOTH_WIRE,
|
||||
.gpu_flag = USER_GPU_FLAG_OVERLAY_SMOOTH_WIRE | USER_GPU_FLAG_SUBDIVISION_EVALUATION,
|
||||
.app_flag = 0,
|
||||
/** Default language of English (1), not Automatic (0). */
|
||||
.language = 1,
|
||||
|
Submodule release/scripts/addons updated: b3c179b286...c08568cc37
Submodule release/scripts/addons_contrib updated: 1646764828...7936dde9ec
@@ -46,18 +46,21 @@ url_manual_mapping = (
|
||||
("bpy.types.fluiddomainsettings.sndparticle_potential_min_trappedair*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-trappedair"),
|
||||
("bpy.types.fluiddomainsettings.sndparticle_potential_max_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-max-wavecrest"),
|
||||
("bpy.types.fluiddomainsettings.sndparticle_potential_min_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-wavecrest"),
|
||||
("bpy.types.lineartgpencilmodifier.use_offset_towards_custom_camera*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-offset-towards-custom-camera"),
|
||||
("bpy.types.movietrackingsettings.refine_intrinsics_principal_point*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-refine-intrinsics-principal-point"),
|
||||
("bpy.types.cyclesobjectsettings.shadow_terminator_geometry_offset*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-shadow-terminator-geometry-offset"),
|
||||
("bpy.types.cyclesrenderlayersettings.denoising_optix_input_passes*", "render/layers/denoising.html#bpy-types-cyclesrenderlayersettings-denoising-optix-input-passes"),
|
||||
("bpy.types.sequencertoolsettings.use_snap_current_frame_to_strips*", "video_editing/sequencer/editing.html#bpy-types-sequencertoolsettings-use-snap-current-frame-to-strips"),
|
||||
("bpy.types.fluiddomainsettings.sndparticle_potential_max_energy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-max-energy"),
|
||||
("bpy.types.fluiddomainsettings.sndparticle_potential_min_energy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-energy"),
|
||||
("bpy.types.lineartgpencilmodifier.use_overlap_edge_type_support*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-overlap-edge-type-support"),
|
||||
("bpy.types.movietrackingsettings.refine_intrinsics_focal_length*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-refine-intrinsics-focal-length"),
|
||||
("bpy.types.rigidbodyconstraint.rigidbodyconstraint.use_breaking*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-rigidbodyconstraint-use-breaking"),
|
||||
("bpy.types.cyclesrendersettings.preview_denoising_input_passes*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-denoising-input-passes"),
|
||||
("bpy.types.cyclesrendersettings.preview_denoising_start_sample*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-denoising-start-sample"),
|
||||
("bpy.types.fluiddomainsettings.sndparticle_sampling_trappedair*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-trappedair"),
|
||||
("bpy.types.fluiddomainsettings.sndparticle_sampling_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-wavecrest"),
|
||||
("bpy.types.lineartgpencilmodifier.use_image_boundary_trimming*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-image-boundary-trimming"),
|
||||
("bpy.types.rigidbodyconstraint.use_override_solver_iterations*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-use-override-solver-iterations"),
|
||||
("bpy.types.toolsettings.use_transform_correct_face_attributes*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-transform-correct-face-attributes"),
|
||||
("bpy.types.cyclesrendersettings.adaptive_scrambling_distance*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-adaptive-scrambling-distance"),
|
||||
@@ -67,6 +70,7 @@ url_manual_mapping = (
|
||||
("bpy.types.cyclesrendersettings.preview_denoising_prefilter*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-denoising-prefilter"),
|
||||
("bpy.types.cyclesrendersettings.preview_scrambling_distance*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-scrambling-distance"),
|
||||
("bpy.types.fluiddomainsettings.sndparticle_potential_radius*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-radius"),
|
||||
("bpy.types.brushgpencilsettings.use_stroke_random_strength*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-strength"),
|
||||
("bpy.types.cyclesrendersettings.film_transparent_roughness*", "render/cycles/render_settings/film.html#bpy-types-cyclesrendersettings-film-transparent-roughness"),
|
||||
("bpy.types.cyclesrendersettings.preview_adaptive_threshold*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-adaptive-threshold"),
|
||||
("bpy.types.fluiddomainsettings.openvdb_cache_compress_type*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-openvdb-cache-compress-type"),
|
||||
@@ -74,13 +78,19 @@ url_manual_mapping = (
|
||||
("bpy.types.fluiddomainsettings.sndparticle_combined_export*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-combined-export"),
|
||||
("bpy.types.fluiddomainsettings.use_collision_border_bottom*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-bottom"),
|
||||
("bpy.types.fluiddomainsettings.vector_scale_with_magnitude*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-vector-scale-with-magnitude"),
|
||||
("bpy.types.lineartgpencilmodifier.use_face_mark_boundaries*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-face-mark-boundaries"),
|
||||
("bpy.types.movietrackingstabilization.use_2d_stabilization*", "movie_clip/tracking/clip/sidebar/stabilization/panel.html#bpy-types-movietrackingstabilization-use-2d-stabilization"),
|
||||
("bpy.types.spacespreadsheet.display_context_path_collapsed*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-display-context-path-collapsed"),
|
||||
("bpy.types.toolsettings.annotation_stroke_placement_view2d*", "interface/annotate_tool.html#bpy-types-toolsettings-annotation-stroke-placement-view2d"),
|
||||
("bpy.types.toolsettings.annotation_stroke_placement_view3d*", "interface/annotate_tool.html#bpy-types-toolsettings-annotation-stroke-placement-view3d"),
|
||||
("bpy.types.brushgpencilsettings.use_random_press_strength*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-strength"),
|
||||
("bpy.types.fluiddomainsettings.use_collision_border_front*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-front"),
|
||||
("bpy.types.fluiddomainsettings.use_collision_border_right*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-right"),
|
||||
("bpy.types.sequencertimelineoverlay.waveform_display_type*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-waveform-display-type"),
|
||||
("bpy.types.view3doverlay.use_normals_constant_screen_size*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-use-normals-constant-screen-size"),
|
||||
("bpy.types.brushgpencilsettings.random_saturation_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random-saturation-factor"),
|
||||
("bpy.types.brushgpencilsettings.use_settings_postprocess*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-settings-postprocess"),
|
||||
("bpy.types.brushgpencilsettings.use_stroke_random_radius*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-radius"),
|
||||
("bpy.types.cyclesmaterialsettings.use_transparent_shadow*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-use-transparent-shadow"),
|
||||
("bpy.types.cyclesobjectsettings.shadow_terminator_offset*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-shadow-terminator-offset"),
|
||||
("bpy.types.cyclesobjectsettings.use_adaptive_subdivision*", "render/cycles/object_settings/adaptive_subdiv.html#bpy-types-cyclesobjectsettings-use-adaptive-subdivision"),
|
||||
@@ -91,28 +101,44 @@ url_manual_mapping = (
|
||||
("bpy.types.fluiddomainsettings.sndparticle_update_radius*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-update-radius"),
|
||||
("bpy.types.fluiddomainsettings.use_collision_border_back*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-back"),
|
||||
("bpy.types.fluiddomainsettings.use_collision_border_left*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-left"),
|
||||
("bpy.types.lineartgpencilmodifier.use_intersection_match*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-intersection-match"),
|
||||
("bpy.types.rendersettings_simplify_gpencil_view_modifier*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-view-modifier"),
|
||||
("bpy.types.brushgpencilsettings.eraser_thickness_factor*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-eraser-thickness-factor"),
|
||||
("bpy.types.brushgpencilsettings.use_random_press_radius*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-radius"),
|
||||
("bpy.types.brushgpencilsettings.use_settings_stabilizer*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-settings-stabilizer"),
|
||||
("bpy.types.colormanagedsequencercolorspacesettings.name*", "render/color_management.html#bpy-types-colormanagedsequencercolorspacesettings-name"),
|
||||
("bpy.types.cyclesrendersettings.max_transparent_bounces*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-max-transparent-bounces"),
|
||||
("bpy.types.cyclesrendersettings.min_transparent_bounces*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-min-transparent-bounces"),
|
||||
("bpy.types.fluiddomainsettings.use_collision_border_top*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-top"),
|
||||
("bpy.types.gpencilsculptsettings.intersection_threshold*", "grease_pencil/modes/draw/tools/cutter.html#bpy-types-gpencilsculptsettings-intersection-threshold"),
|
||||
("bpy.types.gpencilsculptsettings.use_multiframe_falloff*", "grease_pencil/multiframe.html#bpy-types-gpencilsculptsettings-use-multiframe-falloff"),
|
||||
("bpy.types.lineartgpencilmodifier.use_intersection_mask*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-intersection-mask"),
|
||||
("bpy.types.movietrackingsettings.use_keyframe_selection*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-use-keyframe-selection"),
|
||||
("bpy.types.rendersettings.simplify_gpencil_antialiasing*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-antialiasing"),
|
||||
("bpy.types.sequencertimelineoverlay.show_strip_duration*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-strip-duration"),
|
||||
("bpy.types.spaceoutliner.use_filter_lib_override_system*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-lib-override-system"),
|
||||
("bpy.types.toolsettings.use_transform_pivot_point_align*", "scene_layout/object/tools/tool_settings.html#bpy-types-toolsettings-use-transform-pivot-point-align"),
|
||||
("bpy.types.animvizmotionpaths.show_keyframe_action_all*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-show-keyframe-action-all"),
|
||||
("bpy.types.brush.show_multiplane_scrape_planes_preview*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-show-multiplane-scrape-planes-preview"),
|
||||
("bpy.types.brushgpencilsettings.eraser_strength_factor*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-eraser-strength-factor"),
|
||||
("bpy.types.cyclesmaterialsettings.volume_interpolation*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-volume-interpolation"),
|
||||
("bpy.types.cyclesrendersettings.debug_optix_curves_api*", "render/cycles/render_settings/debug.html#bpy-types-cyclesrendersettings-debug-optix-curves-api"),
|
||||
("bpy.types.cyclesrendersettings.denoising_input_passes*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-denoising-input-passes"),
|
||||
("bpy.types.cyclesrendersettings.film_transparent_glass*", "render/cycles/render_settings/film.html#bpy-types-cyclesrendersettings-film-transparent-glass"),
|
||||
("bpy.types.cyclesrendersettings.offscreen_dicing_scale*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-offscreen-dicing-scale"),
|
||||
("bpy.types.fluiddomainsettings.sndparticle_bubble_drag*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-bubble-drag"),
|
||||
("bpy.types.lineartgpencilmodifier.use_crease_on_smooth*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-crease-on-smooth"),
|
||||
("bpy.types.lineartgpencilmodifier.use_face_mark_invert*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-face-mark-invert"),
|
||||
("bpy.types.linestylegeometrymodifier_backbonestretcher*", "render/freestyle/view_layer/line_style/modifiers/geometry/backbone_stretcher.html#bpy-types-linestylegeometrymodifier-backbonestretcher"),
|
||||
("bpy.types.linestylegeometrymodifier_sinusdisplacement*", "render/freestyle/view_layer/line_style/modifiers/geometry/sinus_displacement.html#bpy-types-linestylegeometrymodifier-sinusdisplacement"),
|
||||
("bpy.types.sequencertoolsettings.snap_to_current_frame*", "video_editing/sequencer/editing.html#bpy-types-sequencertoolsettings-snap-to-current-frame"),
|
||||
("bpy.ops.object.geometry_nodes_input_attribute_toggle*", "modeling/modifiers/generate/geometry_nodes.html#bpy-ops-object-geometry-nodes-input-attribute-toggle"),
|
||||
("bpy.types.animvizmotionpaths.show_keyframe_highlight*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-show-keyframe-highlight"),
|
||||
("bpy.types.brushgpencilsettings.pen_subdivision_steps*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-pen-subdivision-steps"),
|
||||
("bpy.types.brushgpencilsettings.use_strength_pressure*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-use-strength-pressure"),
|
||||
("bpy.types.brushgpencilsettings.use_stroke_random_hue*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-hue"),
|
||||
("bpy.types.brushgpencilsettings.use_stroke_random_sat*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-sat"),
|
||||
("bpy.types.brushgpencilsettings.use_stroke_random_val*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-val"),
|
||||
("bpy.types.colormanageddisplaysettings.display_device*", "render/color_management.html#bpy-types-colormanageddisplaysettings-display-device"),
|
||||
("bpy.types.colormanagedviewsettings.use_curve_mapping*", "render/color_management.html#bpy-types-colormanagedviewsettings-use-curve-mapping"),
|
||||
("bpy.types.cyclesrendersettings.sample_clamp_indirect*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-sample-clamp-indirect"),
|
||||
@@ -126,11 +152,19 @@ url_manual_mapping = (
|
||||
("bpy.types.gpencillayer.annotation_onion_before_range*", "interface/annotate_tool.html#bpy-types-gpencillayer-annotation-onion-before-range"),
|
||||
("bpy.types.gpencillayer.use_annotation_onion_skinning*", "interface/annotate_tool.html#bpy-types-gpencillayer-use-annotation-onion-skinning"),
|
||||
("bpy.types.greasepencil.use_adaptive_curve_resolution*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-use-adaptive-curve-resolution"),
|
||||
("bpy.types.lineartgpencilmodifier.stroke_depth_offset*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-stroke-depth-offset"),
|
||||
("bpy.types.lineartgpencilmodifier.use_crease_on_sharp*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-crease-on-sharp"),
|
||||
("bpy.types.linestylegeometrymodifier_polygonalization*", "render/freestyle/view_layer/line_style/modifiers/geometry/polygonization.html#bpy-types-linestylegeometrymodifier-polygonalization"),
|
||||
("bpy.types.sequencertimelineoverlay.show_strip_source*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-strip-source"),
|
||||
("bpy.types.toolsettings.use_gpencil_automerge_strokes*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-automerge-strokes"),
|
||||
("bpy.types.toolsettings.use_proportional_edit_objects*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-use-proportional-edit-objects"),
|
||||
("bpy.ops.view3d.edit_mesh_extrude_move_shrink_fatten*", "modeling/meshes/editing/face/extrude_faces_normal.html#bpy-ops-view3d-edit-mesh-extrude-move-shrink-fatten"),
|
||||
("bpy.types.brushgpencilsettings.active_smooth_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-active-smooth-factor"),
|
||||
("bpy.types.brushgpencilsettings.extend_stroke_factor*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-extend-stroke-factor"),
|
||||
("bpy.types.brushgpencilsettings.use_random_press_hue*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-hue"),
|
||||
("bpy.types.brushgpencilsettings.use_random_press_sat*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-sat"),
|
||||
("bpy.types.brushgpencilsettings.use_random_press_val*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-val"),
|
||||
("bpy.types.brushgpencilsettings.use_stroke_random_uv*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-uv"),
|
||||
("bpy.types.cyclesmaterialsettings.homogeneous_volume*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-homogeneous-volume"),
|
||||
("bpy.types.cyclesrendersettings.adaptive_min_samples*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-adaptive-min-samples"),
|
||||
("bpy.types.cyclesrendersettings.debug_bvh_time_steps*", "render/cycles/render_settings/performance.html#bpy-types-cyclesrendersettings-debug-bvh-time-steps"),
|
||||
@@ -153,11 +187,15 @@ url_manual_mapping = (
|
||||
("bpy.types.rendersettings_simplify_gpencil_view_fill*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-view-fill"),
|
||||
("bpy.types.sequencertoolsettings.snap_to_hold_offset*", "video_editing/sequencer/editing.html#bpy-types-sequencertoolsettings-snap-to-hold-offset"),
|
||||
("bpy.types.toolsettings.use_mesh_automerge_and_split*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-mesh-automerge-and-split"),
|
||||
("bpy.types.animvizmotionpaths.show_keyframe_numbers*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-show-keyframe-numbers"),
|
||||
("bpy.types.brush.cloth_constraint_softbody_strength*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-constraint-softbody-strength"),
|
||||
("bpy.types.brush.elastic_deform_volume_preservation*", "sculpt_paint/sculpting/tools/elastic_deform.html#bpy-types-brush-elastic-deform-volume-preservation"),
|
||||
("bpy.types.brushgpencilsettings.fill_simplify_level*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-simplify-level"),
|
||||
("bpy.types.brushgpencilsettings.random_value_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random-value-factor"),
|
||||
("bpy.types.brushgpencilsettings.use_jitter_pressure*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-jitter-pressure"),
|
||||
("bpy.types.brushgpencilsettings.use_random_press_uv*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-uv"),
|
||||
("bpy.types.brushgpencilsettings.use_settings_random*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-settings-random"),
|
||||
("bpy.types.collection.lineart_use_intersection_mask*", "scene_layout/collections/collections.html#bpy-types-collection-lineart-use-intersection-mask"),
|
||||
("bpy.types.colormanagedinputcolorspacesettings.name*", "editors/image/image_settings.html#bpy-types-colormanagedinputcolorspacesettings-name"),
|
||||
("bpy.types.cyclesrendersettings.denoising_prefilter*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-denoising-prefilter"),
|
||||
("bpy.types.cyclesrendersettings.preview_dicing_rate*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-preview-dicing-rate"),
|
||||
@@ -171,9 +209,11 @@ url_manual_mapping = (
|
||||
("bpy.types.fluiddomainsettings.sys_particle_maximum*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-sys-particle-maximum"),
|
||||
("bpy.types.fluiddomainsettings.use_bubble_particles*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-use-bubble-particles"),
|
||||
("bpy.types.freestylelineset.select_external_contour*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-external-contour"),
|
||||
("bpy.types.lineartgpencilmodifier.use_custom_camera*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-custom-camera"),
|
||||
("bpy.types.linestylegeometrymodifier_simplification*", "render/freestyle/view_layer/line_style/modifiers/geometry/simplification.html#bpy-types-linestylegeometrymodifier-simplification"),
|
||||
("bpy.types.materialgpencilstyle.use_overlap_strokes*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-use-overlap-strokes"),
|
||||
("bpy.types.sequencertimelineoverlay.show_strip_name*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-strip-name"),
|
||||
("bpy.types.sequencertimelineoverlay.show_thumbnails*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-thumbnails"),
|
||||
("bpy.types.spacespreadsheet.geometry_component_type*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-geometry-component-type"),
|
||||
("bpy.types.toolsettings.use_gpencil_weight_data_add*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-weight-data-add"),
|
||||
("bpy.types.view3doverlay.texture_paint_mode_opacity*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-texture-paint-mode-opacity"),
|
||||
@@ -189,6 +229,7 @@ url_manual_mapping = (
|
||||
("bpy.types.cyclesrendersettings.adaptive_threshold*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-adaptive-threshold"),
|
||||
("bpy.types.cyclesrendersettings.camera_cull_margin*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-camera-cull-margin"),
|
||||
("bpy.types.cyclesrendersettings.debug_use_hair_bvh*", "render/cycles/render_settings/performance.html#bpy-types-cyclesrendersettings-debug-use-hair-bvh"),
|
||||
("bpy.types.fileassetselectparams.asset_library_ref*", "editors/asset_browser.html#bpy-types-fileassetselectparams-asset-library-ref"),
|
||||
("bpy.types.fluiddomainsettings.export_manta_script*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-export-manta-script"),
|
||||
("bpy.types.fluiddomainsettings.fractions_threshold*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-fractions-threshold"),
|
||||
("bpy.types.fluiddomainsettings.particle_band_width*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-particle-band-width"),
|
||||
@@ -200,26 +241,29 @@ url_manual_mapping = (
|
||||
("bpy.types.freestylelineset.select_by_image_border*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-by-image-border"),
|
||||
("bpy.types.freestylesettings.kr_derivative_epsilon*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-kr-derivative-epsilon"),
|
||||
("bpy.types.geometrynodecurveprimitivebeziersegment*", "modeling/geometry_nodes/curve_primitives/bezier_segment.html#bpy-types-geometrynodecurveprimitivebeziersegment"),
|
||||
("bpy.types.lineartgpencilmodifier.smooth_tolerance*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-smooth-tolerance"),
|
||||
("bpy.types.linestylegeometrymodifier_perlinnoise1d*", "render/freestyle/view_layer/line_style/modifiers/geometry/perlin_noise_1d.html#bpy-types-linestylegeometrymodifier-perlinnoise1d"),
|
||||
("bpy.types.linestylegeometrymodifier_perlinnoise2d*", "render/freestyle/view_layer/line_style/modifiers/geometry/perlin_noise_2d.html#bpy-types-linestylegeometrymodifier-perlinnoise2d"),
|
||||
("bpy.types.materialgpencilstyle.use_stroke_holdout*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-use-stroke-holdout"),
|
||||
("bpy.types.movietrackingsettings.use_tripod_solver*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-use-tripod-solver"),
|
||||
("bpy.types.rendersettings.simplify_child_particles*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-child-particles"),
|
||||
("bpy.types.rendersettings.use_high_quality_normals*", "render/eevee/render_settings/performance.html#bpy-types-rendersettings-use-high-quality-normals"),
|
||||
("bpy.types.sequencerpreviewoverlay.show_annotation*", "video_editing/preview/introduction.html#bpy-types-sequencerpreviewoverlay-show-annotation"),
|
||||
("bpy.types.sequencerpreviewoverlay.show_safe_areas*", "video_editing/preview/introduction.html#bpy-types-sequencerpreviewoverlay-show-safe-areas"),
|
||||
("bpy.types.sequencerpreviewoverlay.show_annotation*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay-show-annotation"),
|
||||
("bpy.types.sequencerpreviewoverlay.show_safe_areas*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay-show-safe-areas"),
|
||||
("bpy.types.sequencertoolsettings.snap_ignore_muted*", "video_editing/sequencer/editing.html#bpy-types-sequencertoolsettings-snap-ignore-muted"),
|
||||
("bpy.types.sequencertoolsettings.snap_ignore_sound*", "video_editing/sequencer/editing.html#bpy-types-sequencertoolsettings-snap-ignore-sound"),
|
||||
("bpy.types.spaceoutliner.use_filter_case_sensitive*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-case-sensitive"),
|
||||
("bpy.types.spaceoutliner.use_filter_object_content*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-content"),
|
||||
("bpy.types.spacesequenceeditor.show_gizmo_navigate*", "editors/video_sequencer/preview/display/gizmos.html#bpy-types-spacesequenceeditor-show-gizmo-navigate"),
|
||||
("bpy.types.toolsettings.use_proportional_connected*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-use-proportional-connected"),
|
||||
("bpy.types.toolsettings.use_proportional_projected*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-use-proportional-projected"),
|
||||
("bpy.types.view3doverlay.vertex_paint_mode_opacity*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-vertex-paint-mode-opacity"),
|
||||
("bpy.types.viewlayer.use_pass_cryptomatte_accurate*", "render/layers/passes.html#bpy-types-viewlayer-use-pass-cryptomatte-accurate"),
|
||||
("bpy.types.viewlayer.use_pass_cryptomatte_material*", "render/layers/passes.html#bpy-types-viewlayer-use-pass-cryptomatte-material"),
|
||||
("bpy.ops.gpencil.vertex_color_brightness_contrast*", "grease_pencil/modes/vertex_paint/editing.html#bpy-ops-gpencil-vertex-color-brightness-contrast"),
|
||||
("bpy.ops.view3d.edit_mesh_extrude_individual_move*", "modeling/meshes/editing/face/extrude_faces.html#bpy-ops-view3d-edit-mesh-extrude-individual-move"),
|
||||
("bpy.ops.view3d.edit_mesh_extrude_manifold_normal*", "modeling/meshes/tools/extrude_manifold.html#bpy-ops-view3d-edit-mesh-extrude-manifold-normal"),
|
||||
("bpy.types.brushgpencilsettings.pen_smooth_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-pen-smooth-factor"),
|
||||
("bpy.types.brushgpencilsettings.random_hue_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random-hue-factor"),
|
||||
("bpy.types.cyclescurverendersettings.subdivisions*", "render/cycles/render_settings/hair.html#bpy-types-cyclescurverendersettings-subdivisions"),
|
||||
("bpy.types.cyclesmaterialsettings.sample_as_light*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-sample-as-light"),
|
||||
("bpy.types.cyclesmaterialsettings.volume_sampling*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-volume-sampling"),
|
||||
@@ -248,6 +292,8 @@ url_manual_mapping = (
|
||||
("bpy.types.linestylegeometrymodifier_guidinglines*", "render/freestyle/view_layer/line_style/modifiers/geometry/guiding_lines.html#bpy-types-linestylegeometrymodifier-guidinglines"),
|
||||
("bpy.types.linestylegeometrymodifier_spatialnoise*", "render/freestyle/view_layer/line_style/modifiers/geometry/spatial_noise.html#bpy-types-linestylegeometrymodifier-spatialnoise"),
|
||||
("bpy.types.linestylethicknessmodifier_calligraphy*", "render/freestyle/view_layer/line_style/modifiers/thickness/calligraphy.html#bpy-types-linestylethicknessmodifier-calligraphy"),
|
||||
("bpy.types.materiallineart.use_material_mask_bits*", "render/materials/line_art.html#bpy-types-materiallineart-use-material-mask-bits"),
|
||||
("bpy.types.movietrackingdopesheet.use_invert_sort*", "movie_clip/tracking/dope_sheet.html#bpy-types-movietrackingdopesheet-use-invert-sort"),
|
||||
("bpy.types.rendersettings_simplify_gpencil_onplay*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-onplay"),
|
||||
("bpy.types.rigidbodyconstraint.breaking_threshold*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-breaking-threshold"),
|
||||
("bpy.types.spaceclipeditor.use_manual_calibration*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-use-manual-calibration"),
|
||||
@@ -255,14 +301,19 @@ url_manual_mapping = (
|
||||
("bpy.types.spaceoutliner.use_filter_object_camera*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-camera"),
|
||||
("bpy.types.spaceoutliner.use_filter_object_others*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-others"),
|
||||
("bpy.types.spacesequenceeditor.show_strip_overlay*", "editors/video_sequencer/sequencer/display.html#bpy-types-spacesequenceeditor-show-strip-overlay"),
|
||||
("bpy.types.spaceuveditor.custom_grid_subdivisions*", "editors/uv/sidebar.html#bpy-types-spaceuveditor-custom-grid-subdivisions"),
|
||||
("bpy.types.toolsettings.proportional_edit_falloff*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-proportional-edit-falloff"),
|
||||
("bpy.types.toolsettings.use_edge_path_live_unwrap*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-edge-path-live-unwrap"),
|
||||
("bpy.types.toolsettings.use_gpencil_draw_additive*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-draw-additive"),
|
||||
("bpy.types.toolsettings.use_snap_backface_culling*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-backface-culling"),
|
||||
("bpy.types.toolsettings.use_snap_uv_grid_absolute*", "editors/uv/controls/snapping.html#bpy-types-toolsettings-use-snap-uv-grid-absolute"),
|
||||
("bpy.types.toolsettings.use_transform_data_origin*", "scene_layout/object/tools/tool_settings.html#bpy-types-toolsettings-use-transform-data-origin"),
|
||||
("bpy.types.view3doverlay.sculpt_mode_mask_opacity*", "sculpt_paint/sculpting/editing/mask.html#bpy-types-view3doverlay-sculpt-mode-mask-opacity"),
|
||||
("bpy.ops.mesh.customdata_custom_splitnormals_add*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-custom-splitnormals-add"),
|
||||
("bpy.ops.outliner.collection_indirect_only_clear*", "render/layers/introduction.html#bpy-ops-outliner-collection-indirect-only-clear"),
|
||||
("bpy.types.animvizmotionpaths.show_frame_numbers*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-show-frame-numbers"),
|
||||
("bpy.types.brushgpencilsettings.pen_smooth_steps*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-pen-smooth-steps"),
|
||||
("bpy.types.brushgpencilsettings.show_fill_extend*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-show-fill-extend"),
|
||||
("bpy.types.cyclesrendersettings.max_subdivisions*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-max-subdivisions"),
|
||||
("bpy.types.cyclesrendersettings.preview_denoiser*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-denoiser"),
|
||||
("bpy.types.cyclesrendersettings.sampling_pattern*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-sampling-pattern"),
|
||||
@@ -293,7 +344,7 @@ url_manual_mapping = (
|
||||
("bpy.types.materialgpencilstyle.use_fill_holdout*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-use-fill-holdout"),
|
||||
("bpy.types.particlesettings.use_parent_particles*", "physics/particles/emitter/render.html#bpy-types-particlesettings-use-parent-particles"),
|
||||
("bpy.types.rigidbodyconstraint.solver_iterations*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-solver-iterations"),
|
||||
("bpy.types.sequencerpreviewoverlay.show_metadata*", "video_editing/preview/introduction.html#bpy-types-sequencerpreviewoverlay-show-metadata"),
|
||||
("bpy.types.sequencerpreviewoverlay.show_metadata*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay-show-metadata"),
|
||||
("bpy.types.sequencertimelineoverlay.show_fcurves*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-fcurves"),
|
||||
("bpy.types.spaceclipeditor.use_grayscale_preview*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-use-grayscale-preview"),
|
||||
("bpy.types.spaceoutliner.use_filter_lib_override*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-lib-override"),
|
||||
@@ -307,6 +358,9 @@ url_manual_mapping = (
|
||||
("bpy.types.viewlayer.use_pass_cryptomatte_object*", "render/layers/passes.html#bpy-types-viewlayer-use-pass-cryptomatte-object"),
|
||||
("bpy.ops.armature.rigify_apply_selection_colors*", "addons/rigging/rigify/metarigs.html#bpy-ops-armature-rigify-apply-selection-colors"),
|
||||
("bpy.types.brushgpencilsettings.fill_layer_mode*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-layer-mode"),
|
||||
("bpy.types.brushgpencilsettings.random_strength*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random-strength"),
|
||||
("bpy.types.brushgpencilsettings.simplify_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-simplify-factor"),
|
||||
("bpy.types.collection.lineart_intersection_mask*", "scene_layout/collections/collections.html#bpy-types-collection-lineart-intersection-mask"),
|
||||
("bpy.types.cyclesobjectsettings.use_camera_cull*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-use-camera-cull"),
|
||||
("bpy.types.cyclesobjectsettings.use_motion_blur*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-use-motion-blur"),
|
||||
("bpy.types.cyclesrendersettings.diffuse_bounces*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-diffuse-bounces"),
|
||||
@@ -325,6 +379,8 @@ url_manual_mapping = (
|
||||
("bpy.types.freestylesettings.use_view_map_cache*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-use-view-map-cache"),
|
||||
("bpy.types.geometrynodecurvehandletypeselection*", "modeling/geometry_nodes/curve/handle_type_selection.html#bpy-types-geometrynodecurvehandletypeselection"),
|
||||
("bpy.types.greasepencil.curve_edit_corner_angle*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-curve-edit-corner-angle"),
|
||||
("bpy.types.lineartgpencilmodifier.source_camera*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-source-camera"),
|
||||
("bpy.types.lineartgpencilmodifier.use_face_mark*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-face-mark"),
|
||||
("bpy.types.linestylegeometrymodifier_tipremover*", "render/freestyle/view_layer/line_style/modifiers/geometry/tip_remover.html#bpy-types-linestylegeometrymodifier-tipremover"),
|
||||
("bpy.types.movieclipuser.use_render_undistorted*", "editors/clip/display/clip_display.html#bpy-types-movieclipuser-use-render-undistorted"),
|
||||
("bpy.types.movietrackingcamera.distortion_model*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-distortion-model"),
|
||||
@@ -345,9 +401,11 @@ url_manual_mapping = (
|
||||
("bpy.types.brushgpencilsettings.fill_direction*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-direction"),
|
||||
("bpy.types.brushgpencilsettings.fill_draw_mode*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-draw-mode"),
|
||||
("bpy.types.brushgpencilsettings.fill_threshold*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-threshold"),
|
||||
("bpy.types.brushgpencilsettings.use_fill_limit*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-use-fill-limit"),
|
||||
("bpy.types.clothsettings.vertex_group_pressure*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-vertex-group-pressure"),
|
||||
("bpy.types.cyclesmaterialsettings.displacement*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-displacement"),
|
||||
("bpy.types.cyclesrendersettings.debug_bvh_type*", "render/cycles/render_settings/debug.html#bpy-types-cyclesrendersettings-debug-bvh-type"),
|
||||
("bpy.types.cyclesrendersettings.fast_gi_method*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-fast-gi-method"),
|
||||
("bpy.types.cyclesrendersettings.glossy_bounces*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-glossy-bounces"),
|
||||
("bpy.types.cyclesrendersettings.volume_bounces*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-volume-bounces"),
|
||||
("bpy.types.cyclesworldsettings.sampling_method*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-sampling-method"),
|
||||
@@ -376,9 +434,12 @@ url_manual_mapping = (
|
||||
("bpy.types.particlesettings.use_modifier_stack*", "physics/particles/emitter/emission.html#bpy-types-particlesettings-use-modifier-stack"),
|
||||
("bpy.types.rendersettings.sequencer_gl_preview*", "video_editing/preview/sidebar.html#bpy-types-rendersettings-sequencer-gl-preview"),
|
||||
("bpy.types.rendersettings.simplify_subdivision*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-subdivision"),
|
||||
("bpy.types.sequencerpreviewoverlay.show_cursor*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay-show-cursor"),
|
||||
("bpy.types.spacegrapheditor.show_extrapolation*", "editors/graph_editor/introduction.html#bpy-types-spacegrapheditor-show-extrapolation"),
|
||||
("bpy.types.spaceoutliner.use_filter_collection*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-collection"),
|
||||
("bpy.types.spacesequenceeditor.cursor_location*", "video_editing/preview/sidebar.html#bpy-types-spacesequenceeditor-cursor-location"),
|
||||
("bpy.types.spacesequenceeditor.display_channel*", "video_editing/preview/sidebar.html#bpy-types-spacesequenceeditor-display-channel"),
|
||||
("bpy.types.spacesequenceeditor.show_gizmo_tool*", "editors/video_sequencer/preview/display/gizmos.html#bpy-types-spacesequenceeditor-show-gizmo-tool"),
|
||||
("bpy.types.spacesequenceeditor.show_region_hud*", "video_editing/sequencer/navigating.html#bpy-types-spacesequenceeditor-show-region-hud"),
|
||||
("bpy.types.spacespreadsheet.show_only_selected*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-show-only-selected"),
|
||||
("bpy.types.spacespreadsheetrowfilter.operation*", "editors/spreadsheet.html#bpy-types-spacespreadsheetrowfilter-operation"),
|
||||
@@ -386,12 +447,12 @@ url_manual_mapping = (
|
||||
("bpy.types.toolsettings.use_snap_grid_absolute*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-grid-absolute"),
|
||||
("bpy.types.view3doverlay.show_face_orientation*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-show-face-orientation"),
|
||||
("bpy.ops.gpencil.bake_grease_pencil_animation*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-bake-grease-pencil-animation"),
|
||||
("bpy.ops.object.blenderkit_material_thumbnail*", "addons/3d_view/blenderkit.html#bpy-ops-object-blenderkit-material-thumbnail"),
|
||||
("bpy.ops.object.multires_higher_levels_delete*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-higher-levels-delete"),
|
||||
("bpy.ops.object.vertex_group_copy_to_selected*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-copy-to-selected"),
|
||||
("bpy.ops.outliner.collection_duplicate_linked*", "editors/outliner/editing.html#bpy-ops-outliner-collection-duplicate-linked"),
|
||||
("bpy.ops.view3d.edit_mesh_extrude_move_normal*", "modeling/meshes/editing/face/extrude_faces.html#bpy-ops-view3d-edit-mesh-extrude-move-normal"),
|
||||
("bpy.types.bakesettings.use_pass_transmission*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-transmission"),
|
||||
("bpy.types.brushgpencilsettings.input_samples*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-input-samples"),
|
||||
("bpy.types.clothsettings.internal_compression*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-compression"),
|
||||
("bpy.types.cyclescamerasettings.panorama_type*", "render/cycles/object_settings/cameras.html#bpy-types-cyclescamerasettings-panorama-type"),
|
||||
("bpy.types.cyclesrendersettings.dicing_camera*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-dicing-camera"),
|
||||
@@ -425,6 +486,7 @@ url_manual_mapping = (
|
||||
("bpy.types.greasepencil.edit_curve_resolution*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-edit-curve-resolution"),
|
||||
("bpy.types.linestylegeometrymodifier_2doffset*", "render/freestyle/view_layer/line_style/modifiers/geometry/2d_offset.html#bpy-types-linestylegeometrymodifier-2doffset"),
|
||||
("bpy.types.linestylegeometrymodifier_sampling*", "render/freestyle/view_layer/line_style/modifiers/geometry/sampling.html#bpy-types-linestylegeometrymodifier-sampling"),
|
||||
("bpy.types.movietrackingdopesheet.sort_method*", "movie_clip/tracking/dope_sheet.html#bpy-types-movietrackingdopesheet-sort-method"),
|
||||
("bpy.types.nodesocketinterface*.default_value*", "interface/controls/nodes/groups.html#bpy-types-nodesocketinterface-default-value"),
|
||||
("bpy.types.rendersettings.line_thickness_mode*", "render/freestyle/render.html#bpy-types-rendersettings-line-thickness-mode"),
|
||||
("bpy.types.rendersettings.motion_blur_shutter*", "render/cycles/render_settings/motion_blur.html#bpy-types-rendersettings-motion-blur-shutter"),
|
||||
@@ -434,9 +496,12 @@ url_manual_mapping = (
|
||||
("bpy.types.spaceclipeditor.show_green_channel*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-green-channel"),
|
||||
("bpy.types.spaceoutliner.show_restrict_column*", "editors/outliner/interface.html#bpy-types-spaceoutliner-show-restrict-column"),
|
||||
("bpy.types.spacespreadsheet.object_eval_state*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-object-eval-state"),
|
||||
("bpy.types.spaceuveditor.display_stretch_type*", "editors/uv/overlays.html#bpy-types-spaceuveditor-display-stretch-type"),
|
||||
("bpy.types.toolsettings.transform_pivot_point*", "editors/3dview/controls/pivot_point/index.html#bpy-types-toolsettings-transform-pivot-point"),
|
||||
("bpy.types.toolsettings.use_proportional_edit*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-use-proportional-edit"),
|
||||
("bpy.types.volumedisplay.interpolation_method*", "modeling/volumes/properties.html#bpy-types-volumedisplay-interpolation-method"),
|
||||
("bpy.types.brushgpencilsettings.angle_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-angle-factor"),
|
||||
("bpy.types.brushgpencilsettings.pen_strength*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-pen-strength"),
|
||||
("bpy.types.clothsettings.use_pressure_volume*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-use-pressure-volume"),
|
||||
("bpy.types.clothsettings.vertex_group_intern*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-vertex-group-intern"),
|
||||
("bpy.types.colormanagedviewsettings.exposure*", "render/color_management.html#bpy-types-colormanagedviewsettings-exposure"),
|
||||
@@ -459,11 +524,13 @@ url_manual_mapping = (
|
||||
("bpy.types.geometrynodeinputsplineresolution*", "modeling/geometry_nodes/curve/spline_resolution.html#bpy-types-geometrynodeinputsplineresolution"),
|
||||
("bpy.types.greasepencil.curve_edit_threshold*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-curve-edit-threshold"),
|
||||
("bpy.types.materialgpencilstyle.stroke_style*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-stroke-style"),
|
||||
("bpy.types.materiallineart.use_material_mask*", "render/materials/line_art.html#bpy-types-materiallineart-use-material-mask"),
|
||||
("bpy.types.objectlineart.use_crease_override*", "scene_layout/object/properties/line_art.html#bpy-types-objectlineart-use-crease-override"),
|
||||
("bpy.types.rendersettings.preview_pixel_size*", "render/cycles/render_settings/performance.html#bpy-types-rendersettings-preview-pixel-size"),
|
||||
("bpy.types.rendersettings.use_crop_to_border*", "render/output/properties/format.html#bpy-types-rendersettings-use-crop-to-border"),
|
||||
("bpy.types.rendersettings.use_file_extension*", "render/output/properties/output.html#bpy-types-rendersettings-use-file-extension"),
|
||||
("bpy.types.sculpt.constant_detail_resolution*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-sculpt-constant-detail-resolution"),
|
||||
("bpy.types.sequencertoolsettings.pivot_point*", "editors/video_sequencer/preview/controls/pivot_point.html#bpy-types-sequencertoolsettings-pivot-point"),
|
||||
("bpy.types.spaceclipeditor.annotation_source*", "movie_clip/tracking/clip/sidebar/view.html#bpy-types-spaceclipeditor-annotation-source"),
|
||||
("bpy.types.spaceclipeditor.show_blue_channel*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-blue-channel"),
|
||||
("bpy.types.spacefilebrowser.system_bookmarks*", "editors/file_browser.html#bpy-types-spacefilebrowser-system-bookmarks"),
|
||||
@@ -471,6 +538,7 @@ url_manual_mapping = (
|
||||
("bpy.types.spaceoutliner.use_filter_complete*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-complete"),
|
||||
("bpy.types.spacespreadsheet.attribute_domain*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-attribute-domain"),
|
||||
("bpy.types.spacespreadsheetrowfilter.enabled*", "editors/spreadsheet.html#bpy-types-spacespreadsheetrowfilter-enabled"),
|
||||
("bpy.types.spaceuveditor.show_modified_edges*", "editors/uv/overlays.html#bpy-types-spaceuveditor-show-modified-edges"),
|
||||
("bpy.types.spaceview3d.transform_orientation*", "editors/3dview/controls/orientation.html#bpy-types-spaceview3d-transform-orientation"),
|
||||
("bpy.types.spaceview3d.use_local_collections*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-use-local-collections"),
|
||||
("bpy.types.toolsettings.use_snap_peel_object*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-peel-object"),
|
||||
@@ -482,6 +550,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.scene.freestyle_alpha_modifier_add*", "render/freestyle/view_layer/line_style/alpha.html#bpy-ops-scene-freestyle-alpha-modifier-add"),
|
||||
("bpy.ops.scene.freestyle_color_modifier_add*", "render/freestyle/view_layer/line_style/color.html#bpy-ops-scene-freestyle-color-modifier-add"),
|
||||
("bpy.types.brush.cloth_simulation_area_type*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-simulation-area-type"),
|
||||
("bpy.types.brushgpencilsettings.eraser_mode*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-eraser-mode"),
|
||||
("bpy.types.brushgpencilsettings.fill_factor*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-factor"),
|
||||
("bpy.types.curve.bevel_factor_mapping_start*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-factor-mapping-start"),
|
||||
("bpy.types.cyclescamerasettings.fisheye_fov*", "render/cycles/object_settings/cameras.html#bpy-types-cyclescamerasettings-fisheye-fov"),
|
||||
@@ -512,6 +581,8 @@ url_manual_mapping = (
|
||||
("bpy.types.freestylesettings.as_render_pass*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-as-render-pass"),
|
||||
("bpy.types.freestylesettings.use_smoothness*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-use-smoothness"),
|
||||
("bpy.types.geometrynodecurvequadraticbezier*", "modeling/geometry_nodes/curve_primitives/quadratic_bezier.html#bpy-types-geometrynodecurvequadraticbezier"),
|
||||
("bpy.types.lineartgpencilmodifier.use_cache*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-cache"),
|
||||
("bpy.types.lineartgpencilmodifier.use_loose*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-loose"),
|
||||
("bpy.types.materialgpencilstyle.show_stroke*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-show-stroke"),
|
||||
("bpy.types.mesh.use_customdata_vertex_bevel*", "modeling/meshes/properties/custom_data.html#bpy-types-mesh-use-customdata-vertex-bevel"),
|
||||
("bpy.types.movietrackingcamera.focal_length*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-focal-length"),
|
||||
@@ -522,6 +593,8 @@ url_manual_mapping = (
|
||||
("bpy.types.scenegpencil.antialias_threshold*", "render/cycles/render_settings/grease_pencil.html#bpy-types-scenegpencil-antialias-threshold"),
|
||||
("bpy.types.spaceclipeditor.show_red_channel*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-red-channel"),
|
||||
("bpy.types.spaceclipeditor.use_mute_footage*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-use-mute-footage"),
|
||||
("bpy.types.spacenodeoverlay.show_wire_color*", "interface/controls/nodes/introduction.html#bpy-types-spacenodeoverlay-show-wire-color"),
|
||||
("bpy.types.spacesequenceeditor.display_mode*", "video_editing/preview/display_mode.html#bpy-types-spacesequenceeditor-display-mode"),
|
||||
("bpy.types.spacesequenceeditor.overlay_type*", "video_editing/preview/sidebar.html#bpy-types-spacesequenceeditor-overlay-type"),
|
||||
("bpy.types.spaceuveditor.sticky_select_mode*", "editors/uv/selecting.html#bpy-types-spaceuveditor-sticky-select-mode"),
|
||||
("bpy.types.spaceview3d.show_object_viewport*", "editors/3dview/display/visibility.html#bpy-types-spaceview3d-show-object-viewport"),
|
||||
@@ -538,9 +611,11 @@ url_manual_mapping = (
|
||||
("bpy.ops.outliner.collection_holdout_clear*", "render/layers/introduction.html#bpy-ops-outliner-collection-holdout-clear"),
|
||||
("bpy.ops.sculpt.face_set_change_visibility*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-sculpt-face-set-change-visibility"),
|
||||
("bpy.ops.sculpt.face_sets_randomize_colors*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-sculpt-face-sets-randomize-colors"),
|
||||
("bpy.types.animvizmotionpaths.frame_before*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-before"),
|
||||
("bpy.types.brush.disconnected_distance_max*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-disconnected-distance-max"),
|
||||
("bpy.types.brush.surface_smooth_iterations*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-iterations"),
|
||||
("bpy.types.brushgpencilsettings.pen_jitter*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-pen-jitter"),
|
||||
("bpy.types.brushgpencilsettings.show_lasso*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-show-lasso"),
|
||||
("bpy.types.cyclescurverendersettings.shape*", "render/cycles/render_settings/hair.html#bpy-types-cyclescurverendersettings-shape"),
|
||||
("bpy.types.cyclesrendersettings.ao_bounces*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-ao-bounces"),
|
||||
("bpy.types.cyclesrendersettings.time_limit*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-time-limit"),
|
||||
@@ -566,6 +641,7 @@ url_manual_mapping = (
|
||||
("bpy.types.gpencilsculptsettings.lock_axis*", "grease_pencil/modes/draw/drawing_planes.html#bpy-types-gpencilsculptsettings-lock-axis"),
|
||||
("bpy.types.imageformatsettings.file_format*", "render/output/properties/output.html#bpy-types-imageformatsettings-file-format"),
|
||||
("bpy.types.imagepaint.use_backface_culling*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-imagepaint-use-backface-culling"),
|
||||
("bpy.types.lineartgpencilmodifier.overscan*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-overscan"),
|
||||
("bpy.types.linestyle*modifier_curvature_3d*", "render/freestyle/view_layer/line_style/modifiers/color/curvature_3d.html#bpy-types-linestyle-modifier-curvature-3d"),
|
||||
("bpy.types.materialgpencilstyle.fill_color*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-fill-color"),
|
||||
("bpy.types.materialgpencilstyle.fill_style*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-fill-style"),
|
||||
@@ -580,10 +656,13 @@ url_manual_mapping = (
|
||||
("bpy.types.rendersettings.use_single_layer*", "render/layers/view_layer.html#bpy-types-rendersettings-use-single-layer"),
|
||||
("bpy.types.sceneeevee.use_taa_reprojection*", "render/eevee/render_settings/sampling.html#bpy-types-sceneeevee-use-taa-reprojection"),
|
||||
("bpy.types.sequenceeditor.use_overlay_lock*", "video_editing/preview/sidebar.html#bpy-types-sequenceeditor-use-overlay-lock"),
|
||||
("bpy.types.spaceclipeditor.cursor_location*", "editors/clip/sidebar.html#bpy-types-spaceclipeditor-cursor-location"),
|
||||
("bpy.types.spacefilebrowser.recent_folders*", "editors/file_browser.html#bpy-types-spacefilebrowser-recent-folders"),
|
||||
("bpy.types.spacefilebrowser.system_folders*", "editors/file_browser.html#bpy-types-spacefilebrowser-system-folders"),
|
||||
("bpy.types.spacenodeeditor.show_annotation*", "interface/controls/nodes/introduction.html#bpy-types-spacenodeeditor-show-annotation"),
|
||||
("bpy.types.spaceoutliner.use_filter_object*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object"),
|
||||
("bpy.types.spacesequenceeditor.use_proxies*", "video_editing/preview/sidebar.html#bpy-types-spacesequenceeditor-use-proxies"),
|
||||
("bpy.types.spaceuveditor.edge_display_type*", "editors/uv/overlays.html#bpy-types-spaceuveditor-edge-display-type"),
|
||||
("bpy.types.spaceuveditor.show_pixel_coords*", "editors/uv/sidebar.html#bpy-types-spaceuveditor-show-pixel-coords"),
|
||||
("bpy.types.spaceview3d.show_reconstruction*", "editors/3dview/display/overlays.html#bpy-types-spaceview3d-show-reconstruction"),
|
||||
("bpy.types.toolsettings.gpencil_selectmode*", "grease_pencil/selecting.html#bpy-types-toolsettings-gpencil-selectmode"),
|
||||
@@ -593,6 +672,7 @@ url_manual_mapping = (
|
||||
("bpy.types.toolsettings.use_snap_translate*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-translate"),
|
||||
("bpy.types.toolsettings.use_uv_select_sync*", "editors/uv/selecting.html#bpy-types-toolsettings-use-uv-select-sync"),
|
||||
("bpy.types.view3doverlay.wireframe_opacity*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-wireframe-opacity"),
|
||||
("bpy.ops.asset.open_containing_blend_file*", "editors/asset_browser.html#bpy-ops-asset-open-containing-blend-file"),
|
||||
("bpy.ops.gpencil.active_frames_delete_all*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-active-frames-delete-all"),
|
||||
("bpy.ops.gpencil.stroke_merge_by_distance*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-stroke-merge-by-distance"),
|
||||
("bpy.ops.node.collapse_hide_unused_toggle*", "interface/controls/nodes/editing.html#bpy-ops-node-collapse-hide-unused-toggle"),
|
||||
@@ -601,8 +681,11 @@ url_manual_mapping = (
|
||||
("bpy.ops.object.modifier_copy_to_selected*", "modeling/modifiers/introduction.html#bpy-ops-object-modifier-copy-to-selected"),
|
||||
("bpy.ops.preferences.app_template_install*", "advanced/app_templates.html#bpy-ops-preferences-app-template-install"),
|
||||
("bpy.types.actionposemarkers.active_index*", "animation/armatures/properties/pose_library.html#bpy-types-actionposemarkers-active-index"),
|
||||
("bpy.types.animvizmotionpaths.frame_after*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-after"),
|
||||
("bpy.types.animvizmotionpaths.frame_start*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-start"),
|
||||
("bpy.types.bakesettings.use_pass_indirect*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-indirect"),
|
||||
("bpy.types.brush.cloth_force_falloff_type*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-force-falloff-type"),
|
||||
("bpy.types.brushgpencilsettings.caps_type*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-caps-type"),
|
||||
("bpy.types.brushgpencilsettings.fill_leak*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-leak"),
|
||||
("bpy.types.brushgpencilsettings.show_fill*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-show-fill"),
|
||||
("bpy.types.brushgpencilsettings.uv_random*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-uv-random"),
|
||||
@@ -655,12 +738,15 @@ url_manual_mapping = (
|
||||
("bpy.types.shadernodesubsurfacescattering*", "render/shader_nodes/shader/sss.html#bpy-types-shadernodesubsurfacescattering"),
|
||||
("bpy.types.spaceclipeditor.lock_selection*", "editors/clip/introduction.html#bpy-types-spaceclipeditor-lock-selection"),
|
||||
("bpy.types.spacedopesheeteditor.auto_snap*", "editors/dope_sheet/editing.html#bpy-types-spacedopesheeteditor-auto-snap"),
|
||||
("bpy.types.spacenodeoverlay.show_overlays*", "interface/controls/nodes/introduction.html#bpy-types-spacenodeoverlay-show-overlays"),
|
||||
("bpy.types.spaceoutliner.show_mode_column*", "editors/outliner/interface.html#bpy-types-spaceoutliner-show-mode-column"),
|
||||
("bpy.types.spacesequenceeditor.show_gizmo*", "editors/video_sequencer/preview/display/gizmos.html#bpy-types-spacesequenceeditor-show-gizmo"),
|
||||
("bpy.types.spacetexteditor.use_match_case*", "editors/text_editor.html#bpy-types-spacetexteditor-use-match-case"),
|
||||
("bpy.types.spaceview3d.show_object_select*", "editors/3dview/display/visibility.html#bpy-types-spaceview3d-show-object-select"),
|
||||
("bpy.types.toolsettings.use_lock_relative*", "sculpt_paint/weight_paint/tool_settings/options.html#bpy-types-toolsettings-use-lock-relative"),
|
||||
("bpy.types.vertexpaint.use_group_restrict*", "sculpt_paint/weight_paint/tool_settings/options.html#bpy-types-vertexpaint-use-group-restrict"),
|
||||
("bpy.types.volumedisplay.wireframe_detail*", "modeling/volumes/properties.html#bpy-types-volumedisplay-wireframe-detail"),
|
||||
("bpy.types.windowmanager.asset_path_dummy*", "editors/asset_browser.html#bpy-types-windowmanager-asset-path-dummy"),
|
||||
("bpy.ops.armature.rigify_add_bone_groups*", "addons/rigging/rigify/metarigs.html#bpy-ops-armature-rigify-add-bone-groups"),
|
||||
("bpy.ops.object.assign_property_defaults*", "animation/armatures/posing/editing/apply.html#bpy-ops-object-assign-property-defaults"),
|
||||
("bpy.ops.object.vertex_group_limit_total*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-limit-total"),
|
||||
@@ -669,12 +755,16 @@ url_manual_mapping = (
|
||||
("bpy.ops.outliner.collection_hide_inside*", "editors/outliner/editing.html#bpy-ops-outliner-collection-hide-inside"),
|
||||
("bpy.ops.outliner.collection_holdout_set*", "render/layers/introduction.html#bpy-ops-outliner-collection-holdout-set"),
|
||||
("bpy.ops.outliner.collection_show_inside*", "editors/outliner/editing.html#bpy-ops-outliner-collection-show-inside"),
|
||||
("bpy.ops.poselib.restore_previous_action*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-restore-previous-action"),
|
||||
("bpy.ops.preferences.reset_default_theme*", "editors/preferences/themes.html#bpy-ops-preferences-reset-default-theme"),
|
||||
("bpy.ops.sequencer.strip_transform_clear*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-strip-transform-clear"),
|
||||
("bpy.ops.spreadsheet.add_row_filter_rule*", "editors/spreadsheet.html#bpy-ops-spreadsheet-add-row-filter-rule"),
|
||||
("bpy.types.animdata.action_extrapolation*", "editors/nla/sidebar.html#bpy-types-animdata-action-extrapolation"),
|
||||
("bpy.types.animvizmotionpaths.frame_step*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-step"),
|
||||
("bpy.types.bakesettings.max_ray_distance*", "render/cycles/baking.html#bpy-types-bakesettings-max-ray-distance"),
|
||||
("bpy.types.brush.multiplane_scrape_angle*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-multiplane-scrape-angle"),
|
||||
("bpy.types.brushgpencilsettings.hardness*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-hardness"),
|
||||
("bpy.types.brushgpencilsettings.use_trim*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-trim"),
|
||||
("bpy.types.clothsettings.internal_spring*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-spring"),
|
||||
("bpy.types.clothsettings.pressure_factor*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-pressure-factor"),
|
||||
("bpy.types.colormanagedviewsettings.look*", "render/color_management.html#bpy-types-colormanagedviewsettings-look"),
|
||||
@@ -709,6 +799,7 @@ url_manual_mapping = (
|
||||
("bpy.types.layercollection.hide_viewport*", "editors/outliner/interface.html#bpy-types-layercollection-hide-viewport"),
|
||||
("bpy.types.layercollection.indirect_only*", "editors/outliner/interface.html#bpy-types-layercollection-indirect-only"),
|
||||
("bpy.types.material.use_sss_translucency*", "render/eevee/materials/settings.html#bpy-types-material-use-sss-translucency"),
|
||||
("bpy.types.materiallineart.mat_occlusion*", "render/materials/line_art.html#bpy-types-materiallineart-mat-occlusion"),
|
||||
("bpy.types.movietrackingcamera.principal*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-principal"),
|
||||
("bpy.types.object.use_camera_lock_parent*", "scene_layout/object/properties/relations.html#bpy-types-object-use-camera-lock-parent"),
|
||||
("bpy.types.object.visible_volume_scatter*", "render/cycles/object_settings/object_data.html#bpy-types-object-visible-volume-scatter"),
|
||||
@@ -724,6 +815,7 @@ url_manual_mapping = (
|
||||
("bpy.types.spacetexteditor.margin_column*", "editors/text_editor.html#bpy-types-spacetexteditor-margin-column"),
|
||||
("bpy.types.spacetexteditor.use_find_wrap*", "editors/text_editor.html#bpy-types-spacetexteditor-use-find-wrap"),
|
||||
("bpy.types.spaceuveditor.pixel_snap_mode*", "modeling/meshes/uv/editing.html#bpy-types-spaceuveditor-pixel-snap-mode"),
|
||||
("bpy.types.spaceuveditor.use_custom_grid*", "editors/uv/sidebar.html#bpy-types-spaceuveditor-use-custom-grid"),
|
||||
("bpy.types.spaceuveditor.use_live_unwrap*", "modeling/meshes/uv/editing.html#bpy-types-spaceuveditor-use-live-unwrap"),
|
||||
("bpy.types.toolsettings.double_threshold*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-double-threshold"),
|
||||
("bpy.types.toolsettings.lock_object_mode*", "interface/window_system/topbar.html#bpy-types-toolsettings-lock-object-mode"),
|
||||
@@ -738,7 +830,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.mesh.vertices_smooth_laplacian*", "modeling/meshes/editing/vertex/laplacian_smooth.html#bpy-ops-mesh-vertices-smooth-laplacian"),
|
||||
("bpy.ops.object.multires_rebuild_subdiv*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-rebuild-subdiv"),
|
||||
("bpy.ops.sequencer.select_side_of_frame*", "video_editing/sequencer/selecting.html#bpy-ops-sequencer-select-side-of-frame"),
|
||||
("bpy.ops.view3d.blenderkit_set_category*", "addons/3d_view/blenderkit.html#bpy-ops-view3d-blenderkit-set-category"),
|
||||
("bpy.types.animvizmotionpaths.frame_end*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-end"),
|
||||
("bpy.types.armature.rigify_colors_index*", "addons/rigging/rigify/metarigs.html#bpy-types-armature-rigify-colors-index"),
|
||||
("bpy.types.armature.rigify_theme_to_add*", "addons/rigging/rigify/metarigs.html#bpy-types-armature-rigify-theme-to-add"),
|
||||
("bpy.types.bakesettings.use_pass_direct*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-direct"),
|
||||
@@ -785,11 +877,13 @@ url_manual_mapping = (
|
||||
("bpy.types.spacepreferences.filter_type*", "editors/preferences/keymap.html#bpy-types-spacepreferences-filter-type"),
|
||||
("bpy.types.spacetexteditor.replace_text*", "editors/text_editor.html#bpy-types-spacetexteditor-replace-text"),
|
||||
("bpy.types.spacetexteditor.use_find_all*", "editors/text_editor.html#bpy-types-spacetexteditor-use-find-all"),
|
||||
("bpy.types.toolsettings.snap_uv_element*", "editors/uv/controls/snapping.html#bpy-types-toolsettings-snap-uv-element"),
|
||||
("bpy.types.toolsettings.use_snap_rotate*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-rotate"),
|
||||
("bpy.types.view3doverlay.display_handle*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-display-handle"),
|
||||
("bpy.types.volumedisplay.wireframe_type*", "modeling/volumes/properties.html#bpy-types-volumedisplay-wireframe-type"),
|
||||
("bpy.ops.anim.channels_editable_toggle*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-editable-toggle"),
|
||||
("bpy.ops.curve.normals_make_consistent*", "modeling/curves/editing/control_points.html#bpy-ops-curve-normals-make-consistent"),
|
||||
("bpy.ops.ed.lib_id_load_custom_preview*", "editors/asset_browser.html#bpy-ops-ed-lib-id-load-custom-preview"),
|
||||
("bpy.ops.gpencil.frame_clean_duplicate*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-frame-clean-duplicate"),
|
||||
("bpy.ops.gpencil.stroke_simplify_fixed*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-simplify-fixed"),
|
||||
("bpy.ops.mesh.faces_select_linked_flat*", "modeling/meshes/selecting/linked.html#bpy-ops-mesh-faces-select-linked-flat"),
|
||||
@@ -803,15 +897,19 @@ url_manual_mapping = (
|
||||
("bpy.ops.outliner.collection_duplicate*", "editors/outliner/editing.html#bpy-ops-outliner-collection-duplicate"),
|
||||
("bpy.ops.pose.select_constraint_target*", "animation/armatures/posing/selecting.html#bpy-ops-pose-select-constraint-target"),
|
||||
("bpy.ops.sequencer.change_effect_input*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-change-effect-input"),
|
||||
("bpy.ops.sequencer.strip_color_tag_set*", "video_editing/sequencer/sidebar/strip.html#bpy-ops-sequencer-strip-color-tag-set"),
|
||||
("bpy.ops.sequencer.strip_transform_fit*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-strip-transform-fit"),
|
||||
("bpy.types.armature.rigify_colors_lock*", "addons/rigging/rigify/metarigs.html#bpy-types-armature-rigify-colors-lock"),
|
||||
("bpy.types.bakesettings.cage_extrusion*", "render/cycles/baking.html#bpy-types-bakesettings-cage-extrusion"),
|
||||
("bpy.types.bakesettings.use_pass_color*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-color"),
|
||||
("bpy.types.brush.boundary_falloff_type*", "sculpt_paint/sculpting/tools/boundary.html#bpy-types-brush-boundary-falloff-type"),
|
||||
("bpy.types.brush.texture_overlay_alpha*", "sculpt_paint/brush/cursor.html#bpy-types-brush-texture-overlay-alpha"),
|
||||
("bpy.types.brushgpencilsettings.aspect*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-aspect"),
|
||||
("bpy.types.brushgpencilsettings.dilate*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-dilate"),
|
||||
("bpy.types.brushgpencilsettings.random*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random"),
|
||||
("bpy.types.clothsettings.target_volume*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-target-volume"),
|
||||
("bpy.types.colormanageddisplaysettings*", "render/color_management.html#bpy-types-colormanageddisplaysettings"),
|
||||
("bpy.types.colorramp.hue_interpolation*", "interface/controls/templates/color_ramp.html#bpy-types-colorramp-hue-interpolation"),
|
||||
("bpy.types.compositornodebilateralblur*", "compositing/types/filter/bilateral_blur.html#bpy-types-compositornodebilateralblur"),
|
||||
("bpy.types.compositornodedistancematte*", "compositing/types/matte/distance_key.html#bpy-types-compositornodedistancematte"),
|
||||
("bpy.types.compositornodesetalpha.mode*", "compositing/types/converter/set_alpha.html#bpy-types-compositornodesetalpha-mode"),
|
||||
@@ -834,6 +932,7 @@ url_manual_mapping = (
|
||||
("bpy.types.greasepencil.use_curve_edit*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-use-curve-edit"),
|
||||
("bpy.types.imagepaint.screen_grab_size*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-imagepaint-screen-grab-size"),
|
||||
("bpy.types.linestyle*modifier_material*", "render/freestyle/view_layer/line_style/modifiers/color/material.html#bpy-types-linestyle-modifier-material"),
|
||||
("bpy.types.motionpath.use_custom_color*", "animation/motion_paths.html#bpy-types-motionpath-use-custom-color"),
|
||||
("bpy.types.movietrackingcamera.brown_k*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-brown-k"),
|
||||
("bpy.types.movietrackingcamera.brown_p*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-brown-p"),
|
||||
("bpy.types.object.visible_transmission*", "render/cycles/object_settings/object_data.html#bpy-types-object-visible-transmission"),
|
||||
@@ -883,8 +982,11 @@ url_manual_mapping = (
|
||||
("bpy.types.brush.boundary_deform_type*", "sculpt_paint/sculpting/tools/boundary.html#bpy-types-brush-boundary-deform-type"),
|
||||
("bpy.types.brush.cursor_overlay_alpha*", "sculpt_paint/brush/cursor.html#bpy-types-brush-cursor-overlay-alpha"),
|
||||
("bpy.types.brush.normal_radius_factor*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-normal-radius-factor"),
|
||||
("bpy.types.brush.smooth_stroke_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brush-smooth-stroke-factor"),
|
||||
("bpy.types.brush.smooth_stroke_radius*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brush-smooth-stroke-radius"),
|
||||
("bpy.types.brush.topology_rake_factor*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-brush-topology-rake-factor"),
|
||||
("bpy.types.brush.use_pose_ik_anchored*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-use-pose-ik-anchored"),
|
||||
("bpy.types.brushgpencilsettings.angle*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-angle"),
|
||||
("bpy.types.clothsettings.use_pressure*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-use-pressure"),
|
||||
("bpy.types.compositornodeantialiasing*", "compositing/types/filter/anti_aliasing.html#bpy-types-compositornodeantialiasing"),
|
||||
("bpy.types.compositornodechannelmatte*", "compositing/types/matte/channel_key.html#bpy-types-compositornodechannelmatte"),
|
||||
@@ -921,6 +1023,7 @@ url_manual_mapping = (
|
||||
("bpy.types.spacefilebrowser.bookmarks*", "editors/file_browser.html#bpy-types-spacefilebrowser-bookmarks"),
|
||||
("bpy.types.spaceoutliner.display_mode*", "editors/outliner/interface.html#bpy-types-spaceoutliner-display-mode"),
|
||||
("bpy.types.spaceoutliner.filter_state*", "editors/outliner/interface.html#bpy-types-spaceoutliner-filter-state"),
|
||||
("bpy.types.spaceuveditor.show_stretch*", "editors/uv/overlays.html#bpy-types-spaceuveditor-show-stretch"),
|
||||
("bpy.types.toolsettings.keyframe_type*", "editors/timeline.html#bpy-types-toolsettings-keyframe-type"),
|
||||
("bpy.types.toolsettings.snap_elements*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-snap-elements"),
|
||||
("bpy.types.toolsettings.use_snap_self*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-self"),
|
||||
@@ -942,16 +1045,18 @@ url_manual_mapping = (
|
||||
("bpy.ops.object.material_slot_assign*", "render/materials/assignment.html#bpy-ops-object-material-slot-assign"),
|
||||
("bpy.ops.object.material_slot_select*", "render/materials/assignment.html#bpy-ops-object-material-slot-select"),
|
||||
("bpy.ops.object.multires_unsubdivide*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-unsubdivide"),
|
||||
("bpy.ops.object.paths_update_visible*", "animation/motion_paths.html#bpy-ops-object-paths-update-visible"),
|
||||
("bpy.ops.object.transforms_to_deltas*", "scene_layout/object/editing/apply.html#bpy-ops-object-transforms-to-deltas"),
|
||||
("bpy.ops.outliner.collection_disable*", "editors/outliner/editing.html#bpy-ops-outliner-collection-disable"),
|
||||
("bpy.ops.outliner.collection_isolate*", "editors/outliner/editing.html#bpy-ops-outliner-collection-isolate"),
|
||||
("bpy.ops.pose.visual_transform_apply*", "animation/armatures/posing/editing/apply.html#bpy-ops-pose-visual-transform-apply"),
|
||||
("bpy.ops.poselib.convert_old_poselib*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-convert-old-poselib"),
|
||||
("bpy.ops.render.shutter_curve_preset*", "render/cycles/render_settings/motion_blur.html#bpy-ops-render-shutter-curve-preset"),
|
||||
("bpy.ops.sequencer.view_ghost_border*", "video_editing/preview/sidebar.html#bpy-ops-sequencer-view-ghost-border"),
|
||||
("bpy.ops.ui.override_type_set_button*", "files/linked_libraries/library_overrides.html#bpy-ops-ui-override-type-set-button"),
|
||||
("bpy.ops.view3d.blenderkit_asset_bar*", "addons/3d_view/blenderkit.html#bpy-ops-view3d-blenderkit-asset-bar"),
|
||||
("bpy.types.animdata.action_influence*", "editors/nla/sidebar.html#bpy-types-animdata-action-influence"),
|
||||
("bpy.types.armature.layers_protected*", "animation/armatures/properties/skeleton.html#bpy-types-armature-layers-protected"),
|
||||
("bpy.types.assetmetadata.description*", "editors/asset_browser.html#bpy-types-assetmetadata-description"),
|
||||
("bpy.types.bakesettings.normal_space*", "render/cycles/baking.html#bpy-types-bakesettings-normal-space"),
|
||||
("bpy.types.brush.crease_pinch_factor*", "sculpt_paint/sculpting/tools/snake_hook.html#bpy-types-brush-crease-pinch-factor"),
|
||||
("bpy.types.brush.elastic_deform_type*", "sculpt_paint/sculpting/tools/elastic_deform.html#bpy-types-brush-elastic-deform-type"),
|
||||
@@ -960,6 +1065,7 @@ url_manual_mapping = (
|
||||
("bpy.types.brush.use_primary_overlay*", "sculpt_paint/brush/cursor.html#bpy-types-brush-use-primary-overlay"),
|
||||
("bpy.types.brushtextureslot.map_mode*", "sculpt_paint/brush/texture.html#bpy-types-brushtextureslot-map-mode"),
|
||||
("bpy.types.camera.passepartout_alpha*", "render/cameras.html#bpy-types-camera-passepartout-alpha"),
|
||||
("bpy.types.colorrampelement.position*", "interface/controls/templates/color_ramp.html#bpy-types-colorrampelement-position"),
|
||||
("bpy.types.compositornodechromamatte*", "compositing/types/matte/chroma_key.html#bpy-types-compositornodechromamatte"),
|
||||
("bpy.types.compositornodedilateerode*", "compositing/types/filter/dilate_erode.html#bpy-types-compositornodedilateerode"),
|
||||
("bpy.types.compositornodeellipsemask*", "compositing/types/matte/ellipse_mask.html#bpy-types-compositornodeellipsemask"),
|
||||
@@ -988,6 +1094,7 @@ url_manual_mapping = (
|
||||
("bpy.types.materialgpencilstyle.flip*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-flip"),
|
||||
("bpy.types.materialgpencilstyle.mode*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-mode"),
|
||||
("bpy.types.modifier.show_in_editmode*", "modeling/modifiers/introduction.html#bpy-types-modifier-show-in-editmode"),
|
||||
("bpy.types.motionpath.line_thickness*", "animation/motion_paths.html#bpy-types-motionpath-line-thickness"),
|
||||
("bpy.types.object.empty_display_size*", "modeling/empties.html#bpy-types-object-empty-display-size"),
|
||||
("bpy.types.object.empty_display_type*", "modeling/empties.html#bpy-types-object-empty-display-type"),
|
||||
("bpy.types.regionview3d.use_box_clip*", "editors/3dview/navigate/views.html#bpy-types-regionview3d-use-box-clip"),
|
||||
@@ -1015,6 +1122,7 @@ url_manual_mapping = (
|
||||
("bpy.types.volumedisplay.slice_depth*", "modeling/volumes/properties.html#bpy-types-volumedisplay-slice-depth"),
|
||||
("bpy.types.worldmistsettings.falloff*", "render/cycles/world_settings.html#bpy-types-worldmistsettings-falloff"),
|
||||
("bpy.ops.clip.lock_selection_toggle*", "editors/clip/introduction.html#bpy-ops-clip-lock-selection-toggle"),
|
||||
("bpy.ops.ed.lib_id_generate_preview*", "editors/asset_browser.html#bpy-ops-ed-lib-id-generate-preview"),
|
||||
("bpy.ops.mesh.customdata_mask_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-mask-clear"),
|
||||
("bpy.ops.mesh.customdata_skin_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-skin-clear"),
|
||||
("bpy.ops.mesh.extrude_vertices_move*", "modeling/meshes/editing/vertex/extrude_vertices.html#bpy-ops-mesh-extrude-vertices-move"),
|
||||
@@ -1040,6 +1148,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.sequencer.export_subtitles*", "video_editing/preview/introduction.html#bpy-ops-sequencer-export-subtitles"),
|
||||
("bpy.ops.transform.edge_bevelweight*", "modeling/meshes/editing/edge/edge_data.html#bpy-ops-transform-edge-bevelweight"),
|
||||
("bpy.ops.wm.previews_batch_generate*", "files/blend/previews.html#bpy-ops-wm-previews-batch-generate"),
|
||||
("bpy.types.assetmetadata.active_tag*", "editors/asset_browser.html#bpy-types-assetmetadata-active-tag"),
|
||||
("bpy.types.bakesettings.cage_object*", "render/cycles/baking.html#bpy-types-bakesettings-cage-object"),
|
||||
("bpy.types.bone.use_relative_parent*", "animation/armatures/bones/properties/relations.html#bpy-types-bone-use-relative-parent"),
|
||||
("bpy.types.brush.auto_smooth_factor*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-auto-smooth-factor"),
|
||||
@@ -1092,6 +1201,7 @@ url_manual_mapping = (
|
||||
("bpy.types.shadernodeoutputmaterial*", "render/shader_nodes/output/material.html#bpy-types-shadernodeoutputmaterial"),
|
||||
("bpy.types.shadernodetexenvironment*", "render/shader_nodes/textures/environment.html#bpy-types-shadernodetexenvironment"),
|
||||
("bpy.types.spacesequenceeditor.show*", "video_editing/preview/introduction.html#bpy-types-spacesequenceeditor-show"),
|
||||
("bpy.types.spaceuveditor.show_faces*", "editors/uv/overlays.html#bpy-types-spaceuveditor-show-faces"),
|
||||
("bpy.types.spaceuveditor.uv_opacity*", "editors/uv/overlays.html#bpy-types-spaceuveditor-uv-opacity"),
|
||||
("bpy.types.subdividegpencilmodifier*", "grease_pencil/modifiers/generate/subdivide.html#bpy-types-subdividegpencilmodifier"),
|
||||
("bpy.types.thicknessgpencilmodifier*", "grease_pencil/modifiers/deform/thickness.html#bpy-types-thicknessgpencilmodifier"),
|
||||
@@ -1117,9 +1227,9 @@ url_manual_mapping = (
|
||||
("bpy.ops.mesh.vert_connect_concave*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-vert-connect-concave"),
|
||||
("bpy.ops.object.multires_subdivide*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-subdivide"),
|
||||
("bpy.ops.object.vertex_group_clean*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-clean"),
|
||||
("bpy.ops.poselib.create_pose_asset*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-create-pose-asset"),
|
||||
("bpy.ops.preferences.theme_install*", "editors/preferences/themes.html#bpy-ops-preferences-theme-install"),
|
||||
("bpy.ops.render.play-rendered-anim*", "render/output/animation_player.html#bpy-ops-render-play-rendered-anim"),
|
||||
("bpy.ops.scene.blenderkit_download*", "addons/3d_view/blenderkit.html#bpy-ops-scene-blenderkit-download"),
|
||||
("bpy.ops.sculpt.set_pivot_position*", "sculpt_paint/sculpting/editing/sculpt.html#bpy-ops-sculpt-set-pivot-position"),
|
||||
("bpy.ops.sequencer.image_strip_add*", "video_editing/sequencer/strips/image.html#bpy-ops-sequencer-image-strip-add"),
|
||||
("bpy.ops.sequencer.movie_strip_add*", "video_editing/sequencer/strips/movie.html#bpy-ops-sequencer-movie-strip-add"),
|
||||
@@ -1127,11 +1237,13 @@ url_manual_mapping = (
|
||||
("bpy.ops.sequencer.sound_strip_add*", "video_editing/sequencer/strips/sound.html#bpy-ops-sequencer-sound-strip-add"),
|
||||
("bpy.ops.ui.remove_override_button*", "files/linked_libraries/library_overrides.html#bpy-ops-ui-remove-override-button"),
|
||||
("bpy.ops.view3d.view_center_camera*", "editors/3dview/navigate/camera_view.html#bpy-ops-view3d-view-center-camera"),
|
||||
("bpy.types.animvizmotionpaths.type*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-type"),
|
||||
("bpy.types.armaturegpencilmodifier*", "grease_pencil/modifiers/deform/armature.html#bpy-types-armaturegpencilmodifier"),
|
||||
("bpy.types.brush.cloth_deform_type*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-deform-type"),
|
||||
("bpy.types.brush.cloth_sim_falloff*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-sim-falloff"),
|
||||
("bpy.types.brush.slide_deform_type*", "sculpt_paint/sculpting/tools/slide_relax.html#bpy-types-brush-slide-deform-type"),
|
||||
("bpy.types.camera.show_composition*", "render/cameras.html#bpy-types-camera-show-composition"),
|
||||
("bpy.types.colorramp.interpolation*", "interface/controls/templates/color_ramp.html#bpy-types-colorramp-interpolation"),
|
||||
("bpy.types.compositornodealphaover*", "compositing/types/color/alpha_over.html#bpy-types-compositornodealphaover"),
|
||||
("bpy.types.compositornodebokehblur*", "compositing/types/filter/bokeh_blur.html#bpy-types-compositornodebokehblur"),
|
||||
("bpy.types.compositornodecomposite*", "compositing/types/output/composite.html#bpy-types-compositornodecomposite"),
|
||||
@@ -1189,7 +1301,7 @@ url_manual_mapping = (
|
||||
("bpy.types.rendersettings.fps_base*", "render/output/properties/format.html#bpy-types-rendersettings-fps-base"),
|
||||
("bpy.types.rigidbodyobject.enabled*", "physics/rigid_body/properties/settings.html#bpy-types-rigidbodyobject-enabled"),
|
||||
("bpy.types.sceneeevee.use_overscan*", "render/eevee/render_settings/film.html#bpy-types-sceneeevee-use-overscan"),
|
||||
("bpy.types.sequencerpreviewoverlay*", "video_editing/preview/introduction.html#bpy-types-sequencerpreviewoverlay"),
|
||||
("bpy.types.sequencerpreviewoverlay*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay"),
|
||||
("bpy.types.sequencetransform.scale*", "video_editing/sequencer/sidebar/strip.html#bpy-types-sequencetransform-scale"),
|
||||
("bpy.types.shadernodeeeveespecular*", "render/shader_nodes/shader/specular_bsdf.html#bpy-types-shadernodeeeveespecular"),
|
||||
("bpy.types.shadernodehuesaturation*", "render/shader_nodes/color/hue_saturation.html#bpy-types-shadernodehuesaturation"),
|
||||
@@ -1237,7 +1349,6 @@ url_manual_mapping = (
|
||||
("bpy.ops.sequencer.select_grouped*", "video_editing/sequencer/selecting.html#bpy-ops-sequencer-select-grouped"),
|
||||
("bpy.ops.sequencer.select_handles*", "video_editing/sequencer/selecting.html#bpy-ops-sequencer-select-handles"),
|
||||
("bpy.ops.uv.average_islands_scale*", "modeling/meshes/uv/editing.html#bpy-ops-uv-average-islands-scale"),
|
||||
("bpy.ops.view3d.blenderkit_search*", "addons/3d_view/blenderkit.html#bpy-ops-view3d-blenderkit-search"),
|
||||
("bpy.types.armature.axes_position*", "animation/armatures/properties/display.html#bpy-types-armature-axes-position"),
|
||||
("bpy.types.armature.pose_position*", "animation/armatures/properties/skeleton.html#bpy-types-armature-pose-position"),
|
||||
("bpy.types.bakesettings.use_clear*", "render/cycles/baking.html#bpy-types-bakesettings-use-clear"),
|
||||
@@ -1250,6 +1361,7 @@ url_manual_mapping = (
|
||||
("bpy.types.camerasolverconstraint*", "animation/constraints/motion_tracking/camera_solver.html#bpy-types-camerasolverconstraint"),
|
||||
("bpy.types.clothcollisionsettings*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings"),
|
||||
("bpy.types.collection.hide_select*", "editors/outliner/interface.html#bpy-types-collection-hide-select"),
|
||||
("bpy.types.colorrampelement.color*", "interface/controls/templates/color_ramp.html#bpy-types-colorrampelement-color"),
|
||||
("bpy.types.compositornodecurvergb*", "compositing/types/color/rgb_curves.html#bpy-types-compositornodecurvergb"),
|
||||
("bpy.types.compositornodecurvevec*", "compositing/types/vector/vector_curves.html#bpy-types-compositornodecurvevec"),
|
||||
("bpy.types.compositornodedisplace*", "compositing/types/distort/displace.html#bpy-types-compositornodedisplace"),
|
||||
@@ -1290,6 +1402,7 @@ url_manual_mapping = (
|
||||
("bpy.types.material.line_priority*", "render/freestyle/material.html#bpy-types-material-line-priority"),
|
||||
("bpy.types.mesh.auto_smooth_angle*", "modeling/meshes/structure.html#bpy-types-mesh-auto-smooth-angle"),
|
||||
("bpy.types.modifier.show_viewport*", "modeling/modifiers/introduction.html#bpy-types-modifier-show-viewport"),
|
||||
("bpy.types.motionpath.frame_start*", "animation/motion_paths.html#bpy-types-motionpath-frame-start"),
|
||||
("bpy.types.object.visible_diffuse*", "render/cycles/object_settings/object_data.html#bpy-types-object-visible-diffuse"),
|
||||
("bpy.types.objectsolverconstraint*", "animation/constraints/motion_tracking/object_solver.html#bpy-types-objectsolverconstraint"),
|
||||
("bpy.types.opacitygpencilmodifier*", "grease_pencil/modifiers/color/opacity.html#bpy-types-opacitygpencilmodifier"),
|
||||
@@ -1347,6 +1460,8 @@ url_manual_mapping = (
|
||||
("bpy.ops.outliner.show_one_level*", "editors/outliner/editing.html#bpy-ops-outliner-show-one-level"),
|
||||
("bpy.ops.paint.brush_colors_flip*", "sculpt_paint/texture_paint/tool_settings/brush_settings.html#bpy-ops-paint-brush-colors-flip"),
|
||||
("bpy.ops.paint.weight_from_bones*", "sculpt_paint/weight_paint/editing.html#bpy-ops-paint-weight-from-bones"),
|
||||
("bpy.ops.pose.blend_to_neighbour*", "animation/armatures/posing/editing/in_betweens.html#bpy-ops-pose-blend-to-neighbour"),
|
||||
("bpy.ops.pose.paths_range_update*", "animation/motion_paths.html#bpy-ops-pose-paths-range-update"),
|
||||
("bpy.ops.poselib.action_sanitize*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-action-sanitize"),
|
||||
("bpy.ops.preferences.studiolight*", "editors/preferences/lights.html#bpy-ops-preferences-studiolight"),
|
||||
("bpy.ops.scene.view_layer_remove*", "render/layers/introduction.html#bpy-ops-scene-view-layer-remove"),
|
||||
@@ -1398,6 +1513,7 @@ url_manual_mapping = (
|
||||
("bpy.types.geometrynodetrimcurve*", "modeling/geometry_nodes/curve/trim_curve.html#bpy-types-geometrynodetrimcurve"),
|
||||
("bpy.types.gpencilsculptsettings*", "grease_pencil/properties/index.html#bpy-types-gpencilsculptsettings"),
|
||||
("bpy.types.keyframe.handle_right*", "editors/graph_editor/fcurves/properties.html#bpy-types-keyframe-handle-right"),
|
||||
("bpy.types.lengthgpencilmodifier*", "grease_pencil/modifiers/generate/length.html#bpy-types-lengthgpencilmodifier"),
|
||||
("bpy.types.light.cutoff_distance*", "render/eevee/lighting.html#bpy-types-light-cutoff-distance"),
|
||||
("bpy.types.lockedtrackconstraint*", "animation/constraints/tracking/locked_track.html#bpy-types-lockedtrackconstraint"),
|
||||
("bpy.types.material.blend_method*", "render/eevee/materials/settings.html#bpy-types-material-blend-method"),
|
||||
@@ -1454,14 +1570,17 @@ url_manual_mapping = (
|
||||
("bpy.ops.spreadsheet.toggle_pin*", "editors/spreadsheet.html#bpy-ops-spreadsheet-toggle-pin"),
|
||||
("bpy.ops.uv.follow_active_quads*", "modeling/meshes/editing/uv.html#bpy-ops-uv-follow-active-quads"),
|
||||
("bpy.types.arraygpencilmodifier*", "grease_pencil/modifiers/generate/array.html#bpy-types-arraygpencilmodifier"),
|
||||
("bpy.types.assetmetadata.author*", "editors/asset_browser.html#bpy-types-assetmetadata-author"),
|
||||
("bpy.types.bone.envelope_weight*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-envelope-weight"),
|
||||
("bpy.types.brush.use_persistent*", "sculpt_paint/sculpting/tools/layer.html#bpy-types-brush-use-persistent"),
|
||||
("bpy.types.brushgpencilsettings*", "grease_pencil/modes/draw/tools/index.html#bpy-types-brushgpencilsettings"),
|
||||
("bpy.types.buildgpencilmodifier*", "grease_pencil/modifiers/generate/build.html#bpy-types-buildgpencilmodifier"),
|
||||
("bpy.types.camera.sensor_height*", "render/cameras.html#bpy-types-camera-sensor-height"),
|
||||
("bpy.types.colorbalancemodifier*", "video_editing/sequencer/sidebar/modifiers.html#bpy-types-colorbalancemodifier"),
|
||||
("bpy.types.colorgpencilmodifier*", "grease_pencil/modifiers/color/hue_saturation.html#bpy-types-colorgpencilmodifier"),
|
||||
("bpy.types.colorramp.color_mode*", "interface/controls/templates/color_ramp.html#bpy-types-colorramp-color-mode"),
|
||||
("bpy.types.compositornodefilter*", "compositing/types/filter/filter_node.html#bpy-types-compositornodefilter"),
|
||||
("bpy.types.compositornodehuesat*", "compositing/types/color/hue_saturation.html#bpy-types-compositornodehuesat"),
|
||||
("bpy.types.compositornodehuesat*", "compositing/types/color/posterize.html#bpy-types-compositornodehuesat"),
|
||||
("bpy.types.compositornodeidmask*", "compositing/types/converter/id_mask.html#bpy-types-compositornodeidmask"),
|
||||
("bpy.types.compositornodeinvert*", "compositing/types/color/invert.html#bpy-types-compositornodeinvert"),
|
||||
("bpy.types.compositornodekeying*", "compositing/types/matte/keying.html#bpy-types-compositornodekeying"),
|
||||
@@ -1479,6 +1598,7 @@ url_manual_mapping = (
|
||||
("bpy.types.followpathconstraint*", "animation/constraints/relationship/follow_path.html#bpy-types-followpathconstraint"),
|
||||
("bpy.types.gaussianblursequence*", "video_editing/sequencer/strips/effects/blur.html#bpy-types-gaussianblursequence"),
|
||||
("bpy.types.geometrynodeboundbox*", "modeling/geometry_nodes/geometry/bounding_box.html#bpy-types-geometrynodeboundbox"),
|
||||
("bpy.types.geometrynodedualmesh*", "modeling/geometry_nodes/mesh/dual_mesh.html#bpy-types-geometrynodedualmesh"),
|
||||
("bpy.types.geometrynodematerial*", "-1"),
|
||||
("bpy.types.geometrynodemeshcone*", "modeling/geometry_nodes/mesh_primitives/cone.html#bpy-types-geometrynodemeshcone"),
|
||||
("bpy.types.geometrynodemeshcube*", "modeling/geometry_nodes/mesh_primitives/cube.html#bpy-types-geometrynodemeshcube"),
|
||||
@@ -1493,8 +1613,10 @@ url_manual_mapping = (
|
||||
("bpy.types.mesh.use_auto_smooth*", "modeling/meshes/structure.html#bpy-types-mesh-use-auto-smooth"),
|
||||
("bpy.types.meshtovolumemodifier*", "modeling/modifiers/generate/mesh_to_volume.html#bpy-types-meshtovolumemodifier"),
|
||||
("bpy.types.modifier.show_render*", "modeling/modifiers/introduction.html#bpy-types-modifier-show-render"),
|
||||
("bpy.types.motionpath.frame_end*", "animation/motion_paths.html#bpy-types-motionpath-frame-end"),
|
||||
("bpy.types.noisegpencilmodifier*", "grease_pencil/modifiers/deform/noise.html#bpy-types-noisegpencilmodifier"),
|
||||
("bpy.types.object.hide_viewport*", "scene_layout/object/properties/visibility.html#bpy-types-object-hide-viewport"),
|
||||
("bpy.types.object.show_in_front*", "scene_layout/object/properties/display.html#bpy-types-object-show-in-front"),
|
||||
("bpy.types.posebone.rigify_type*", "addons/rigging/rigify/rig_types/index.html#bpy-types-posebone-rigify-type"),
|
||||
("bpy.types.preferencesfilepaths*", "editors/preferences/file_paths.html#bpy-types-preferencesfilepaths"),
|
||||
("bpy.types.rigidbodyobject.mass*", "physics/rigid_body/properties/settings.html#bpy-types-rigidbodyobject-mass"),
|
||||
@@ -1557,10 +1679,11 @@ url_manual_mapping = (
|
||||
("bpy.ops.pose.quaternions_flip*", "animation/armatures/posing/editing/flip_quats.html#bpy-ops-pose-quaternions-flip"),
|
||||
("bpy.ops.pose.select_hierarchy*", "animation/armatures/posing/selecting.html#bpy-ops-pose-select-hierarchy"),
|
||||
("bpy.ops.pose.transforms_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-transforms-clear"),
|
||||
("bpy.ops.poselib.copy_as_asset*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-copy-as-asset"),
|
||||
("bpy.ops.preferences.copy_prev*", "editors/preferences/introduction.html#bpy-ops-preferences-copy-prev"),
|
||||
("bpy.ops.preferences.keyconfig*", "editors/preferences/keymap.html#bpy-ops-preferences-keyconfig"),
|
||||
("bpy.ops.screen.repeat_history*", "interface/undo_redo.html#bpy-ops-screen-repeat-history"),
|
||||
("bpy.ops.script.execute_preset*", "interface/controls/templates/list_presets.html#bpy-ops-script-execute-preset"),
|
||||
("bpy.ops.script.execute_preset*", "interface/window_system/tabs_panels.html#bpy-ops-script-execute-preset"),
|
||||
("bpy.ops.sculpt.face_sets_init*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-sculpt-face-sets-init"),
|
||||
("bpy.ops.sequencer.change_path*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-change-path"),
|
||||
("bpy.ops.sequencer.refresh_all*", "video_editing/sequencer/navigating.html#bpy-ops-sequencer-refresh-all"),
|
||||
@@ -1577,7 +1700,6 @@ url_manual_mapping = (
|
||||
("bpy.types.bakesettings.target*", "render/cycles/baking.html#bpy-types-bakesettings-target"),
|
||||
("bpy.types.brush.cloth_damping*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-damping"),
|
||||
("bpy.types.brush.icon_filepath*", "sculpt_paint/brush/brush.html#bpy-types-brush-icon-filepath"),
|
||||
("bpy.types.brush.smooth_stroke*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brush-smooth-stroke"),
|
||||
("bpy.types.brush.tip_roundness*", "sculpt_paint/sculpting/tools/clay_strips.html#bpy-types-brush-tip-roundness"),
|
||||
("bpy.types.camera.display_size*", "render/cameras.html#bpy-types-camera-display-size"),
|
||||
("bpy.types.camera.sensor_width*", "render/cameras.html#bpy-types-camera-sensor-width"),
|
||||
@@ -1594,6 +1716,7 @@ url_manual_mapping = (
|
||||
("bpy.types.curve.use_fill_caps*", "modeling/curves/properties/geometry.html#bpy-types-curve-use-fill-caps"),
|
||||
("bpy.types.curve.use_map_taper*", "modeling/curves/properties/geometry.html#bpy-types-curve-use-map-taper"),
|
||||
("bpy.types.cyclesworldsettings*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings"),
|
||||
("bpy.types.dashgpencilmodifier*", "grease_pencil/modifiers/generate/dash.html#bpy-types-dashgpencilmodifier"),
|
||||
("bpy.types.fluiddomainsettings*", "physics/fluid/type/domain/index.html#bpy-types-fluiddomainsettings"),
|
||||
("bpy.types.geometrynodeboolean*", "modeling/geometry_nodes/input/boolean.html#bpy-types-geometrynodeboolean"),
|
||||
("bpy.types.geometrynodeinputid*", "modeling/geometry_nodes/input/id.html#bpy-types-geometrynodeinputid"),
|
||||
@@ -1643,6 +1766,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.armature.bone_layers*", "animation/armatures/bones/editing/change_layers.html#bpy-ops-armature-bone-layers"),
|
||||
("bpy.ops.armature.select_less*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-less"),
|
||||
("bpy.ops.armature.select_more*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-more"),
|
||||
("bpy.ops.asset.bundle_install*", "editors/asset_browser.html#bpy-ops-asset-bundle-install"),
|
||||
("bpy.ops.clip.add_marker_move*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-add-marker-move"),
|
||||
("bpy.ops.clip.bundles_to_mesh*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-bundles-to-mesh"),
|
||||
("bpy.ops.clip.detect_features*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-detect-features"),
|
||||
@@ -1673,6 +1797,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.object.transfer_mode*", "editors/3dview/modes.html#bpy-ops-object-transfer-mode"),
|
||||
("bpy.ops.outliner.show_active*", "editors/outliner/editing.html#bpy-ops-outliner-show-active"),
|
||||
("bpy.ops.paint.add_simple_uvs*", "sculpt_paint/texture_paint/tool_settings/texture_slots.html#bpy-ops-paint-add-simple-uvs"),
|
||||
("bpy.ops.pose.paths_calculate*", "animation/motion_paths.html#bpy-ops-pose-paths-calculate"),
|
||||
("bpy.ops.pose.rigify_generate*", "addons/rigging/rigify/basics.html#bpy-ops-pose-rigify-generate"),
|
||||
("bpy.ops.preferences.autoexec*", "editors/preferences/save_load.html#bpy-ops-preferences-autoexec"),
|
||||
("bpy.ops.scene.view_layer_add*", "render/layers/introduction.html#bpy-ops-scene-view-layer-add"),
|
||||
@@ -1686,11 +1811,11 @@ url_manual_mapping = (
|
||||
("bpy.ops.transform.edge_slide*", "modeling/meshes/editing/edge/edge_slide.html#bpy-ops-transform-edge-slide"),
|
||||
("bpy.ops.transform.vert_slide*", "modeling/meshes/editing/vertex/slide_vertices.html#bpy-ops-transform-vert-slide"),
|
||||
("bpy.ops.uv.project_from_view*", "modeling/meshes/editing/uv.html#bpy-ops-uv-project-from-view"),
|
||||
("bpy.ops.wm.blenderkit_logout*", "addons/3d_view/blenderkit.html#bpy-ops-wm-blenderkit-logout"),
|
||||
("bpy.ops.wm.memory_statistics*", "advanced/operators.html#bpy-ops-wm-memory-statistics"),
|
||||
("bpy.ops.wm.recover_auto_save*", "files/blend/open_save.html#bpy-ops-wm-recover-auto-save"),
|
||||
("bpy.types.adjustmentsequence*", "video_editing/sequencer/strips/adjustment.html#bpy-types-adjustmentsequence"),
|
||||
("bpy.types.alphaundersequence*", "video_editing/sequencer/strips/effects/alpha_over_under_overdrop.html#bpy-types-alphaundersequence"),
|
||||
("bpy.types.animvizmotionpaths*", "animation/motion_paths.html#bpy-types-animvizmotionpaths"),
|
||||
("bpy.types.armature.show_axes*", "animation/armatures/properties/display.html#bpy-types-armature-show-axes"),
|
||||
("bpy.types.armatureconstraint*", "animation/constraints/relationship/armature.html#bpy-types-armatureconstraint"),
|
||||
("bpy.types.compositornodeblur*", "compositing/types/filter/blur_node.html#bpy-types-compositornodeblur"),
|
||||
@@ -1791,6 +1916,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.node.preview_toggle*", "interface/controls/nodes/editing.html#bpy-ops-node-preview-toggle"),
|
||||
("bpy.ops.object.origin_clear*", "scene_layout/object/editing/clear.html#bpy-ops-object-origin-clear"),
|
||||
("bpy.ops.object.parent_clear*", "scene_layout/object/editing/parent.html#bpy-ops-object-parent-clear"),
|
||||
("bpy.ops.object.paths_update*", "animation/motion_paths.html#bpy-ops-object-paths-update"),
|
||||
("bpy.ops.object.shade_smooth*", "scene_layout/object/editing/shading.html#bpy-ops-object-shade-smooth"),
|
||||
("bpy.ops.object.voxel_remesh*", "modeling/meshes/retopology.html#bpy-ops-object-voxel-remesh"),
|
||||
("bpy.ops.pose.armature_apply*", "animation/armatures/posing/editing/apply.html#bpy-ops-pose-armature-apply"),
|
||||
@@ -1810,7 +1936,6 @@ url_manual_mapping = (
|
||||
("bpy.ops.uv.cylinder_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-cylinder-project"),
|
||||
("bpy.ops.uv.minimize_stretch*", "modeling/meshes/uv/editing.html#bpy-ops-uv-minimize-stretch"),
|
||||
("bpy.ops.uv.select_edge_ring*", "editors/uv/selecting.html#bpy-ops-uv-select-edge-ring"),
|
||||
("bpy.ops.wm.blenderkit_login*", "addons/3d_view/blenderkit.html#bpy-ops-wm-blenderkit-login"),
|
||||
("bpy.ops.wm.save_as_mainfile*", "files/blend/open_save.html#bpy-ops-wm-save-as-mainfile"),
|
||||
("bpy.types.alphaoversequence*", "video_editing/sequencer/strips/effects/alpha_over_under_overdrop.html#bpy-types-alphaoversequence"),
|
||||
("bpy.types.armatureeditbones*", "animation/armatures/bones/editing/index.html#bpy-types-armatureeditbones"),
|
||||
@@ -1903,6 +2028,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.mesh.symmetry_snap*", "modeling/meshes/editing/mesh/snap_symmetry.html#bpy-ops-mesh-symmetry-snap"),
|
||||
("bpy.ops.node.group_ungroup*", "interface/controls/nodes/groups.html#bpy-ops-node-group-ungroup"),
|
||||
("bpy.ops.object.gpencil_add*", "grease_pencil/primitives.html#bpy-ops-object-gpencil-add"),
|
||||
("bpy.ops.object.paths_clear*", "animation/motion_paths.html#bpy-ops-object-paths-clear"),
|
||||
("bpy.ops.object.select_less*", "scene_layout/object/selecting.html#bpy-ops-object-select-less"),
|
||||
("bpy.ops.object.select_more*", "scene_layout/object/selecting.html#bpy-ops-object-select-more"),
|
||||
("bpy.ops.object.track_clear*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-track-clear"),
|
||||
@@ -1941,6 +2067,8 @@ url_manual_mapping = (
|
||||
("bpy.types.freestylelineset*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset"),
|
||||
("bpy.types.image.alpha_mode*", "editors/image/image_settings.html#bpy-types-image-alpha-mode"),
|
||||
("bpy.types.mask.frame_start*", "movie_clip/masking/sidebar.html#bpy-types-mask-frame-start"),
|
||||
("bpy.types.motionpath.color*", "animation/motion_paths.html#bpy-types-motionpath-color"),
|
||||
("bpy.types.motionpath.lines*", "animation/motion_paths.html#bpy-types-motionpath-lines"),
|
||||
("bpy.types.multicamsequence*", "video_editing/sequencer/strips/effects/multicam.html#bpy-types-multicamsequence"),
|
||||
("bpy.types.multiplysequence*", "video_editing/sequencer/strips/effects/multiply.html#bpy-types-multiplysequence"),
|
||||
("bpy.types.multiresmodifier*", "modeling/modifiers/generate/multiresolution.html#bpy-types-multiresmodifier"),
|
||||
@@ -1984,6 +2112,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.armature.separate*", "animation/armatures/bones/editing/separate_bones.html#bpy-ops-armature-separate"),
|
||||
("bpy.ops.clip.clean_tracks*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-clean-tracks"),
|
||||
("bpy.ops.clip.delete_track*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-delete-track"),
|
||||
("bpy.ops.clip.select_lasso*", "movie_clip/tracking/clip/selecting.html#bpy-ops-clip-select-lasso"),
|
||||
("bpy.ops.clip.solve_camera*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-solve-camera"),
|
||||
("bpy.ops.constraint.delete*", "animation/constraints/interface/header.html#bpy-ops-constraint-delete"),
|
||||
("bpy.ops.curve.smooth_tilt*", "modeling/curves/editing/control_points.html#bpy-ops-curve-smooth-tilt"),
|
||||
@@ -1996,6 +2125,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.graph.easing_type*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-easing-type"),
|
||||
("bpy.ops.graph.handle_type*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-handle-type"),
|
||||
("bpy.ops.mask.parent_clear*", "movie_clip/masking/editing.html#bpy-ops-mask-parent-clear"),
|
||||
("bpy.ops.mask.select_lasso*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-lasso"),
|
||||
("bpy.ops.mesh.bevel.vertex*", "modeling/meshes/editing/vertex/bevel_vertices.html#bpy-ops-mesh-bevel-vertex"),
|
||||
("bpy.ops.mesh.delete_loose*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-delete-loose"),
|
||||
("bpy.ops.mesh.face_shading*", "modeling/meshes/editing/face/shading.html#bpy-ops-mesh-face-shading"),
|
||||
@@ -2014,6 +2144,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.object.shade_flat*", "scene_layout/object/editing/shading.html#bpy-ops-object-shade-flat"),
|
||||
("bpy.ops.pose.group_assign*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-assign"),
|
||||
("bpy.ops.pose.group_select*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-select"),
|
||||
("bpy.ops.pose.paths_update*", "animation/motion_paths.html#bpy-ops-pose-paths-update"),
|
||||
("bpy.ops.poselib.pose_move*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-pose-move"),
|
||||
("bpy.ops.preferences.addon*", "editors/preferences/addons.html#bpy-ops-preferences-addon"),
|
||||
("bpy.ops.scene.light_cache*", "render/eevee/render_settings/indirect_lighting.html#bpy-ops-scene-light-cache"),
|
||||
@@ -2043,6 +2174,7 @@ url_manual_mapping = (
|
||||
("bpy.types.fmodifierlimits*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierlimits"),
|
||||
("bpy.types.imagepaint.mode*", "sculpt_paint/texture_paint/tool_settings/texture_slots.html#bpy-types-imagepaint-mode"),
|
||||
("bpy.types.latticemodifier*", "modeling/modifiers/deform/lattice.html#bpy-types-latticemodifier"),
|
||||
("bpy.types.materiallineart*", "render/materials/line_art.html#bpy-types-materiallineart"),
|
||||
("bpy.types.musgravetexture*", "render/materials/legacy_textures/types/musgrave.html#bpy-types-musgravetexture"),
|
||||
("bpy.types.object.location*", "scene_layout/object/properties/transforms.html#bpy-types-object-location"),
|
||||
("bpy.types.object.rotation*", "scene_layout/object/properties/transforms.html#bpy-types-object-rotation"),
|
||||
@@ -2066,6 +2198,7 @@ url_manual_mapping = (
|
||||
("bpy.types.subsurfmodifier*", "modeling/modifiers/generate/subdivision_surface.html#bpy-types-subsurfmodifier"),
|
||||
("bpy.types.texturenodemath*", "editors/texture_node/types/converter/math.html#bpy-types-texturenodemath"),
|
||||
("bpy.types.volume.filepath*", "modeling/volumes/properties.html#bpy-types-volume-filepath"),
|
||||
("bpy.ops.asset.tag_remove*", "editors/asset_browser.html#bpy-ops-asset-tag-remove"),
|
||||
("bpy.ops.clip.join_tracks*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-join-tracks"),
|
||||
("bpy.ops.constraint.apply*", "animation/constraints/interface/header.html#bpy-ops-constraint-apply"),
|
||||
("bpy.ops.curve.select_row*", "modeling/surfaces/selecting.html#bpy-ops-curve-select-row"),
|
||||
@@ -2087,6 +2220,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.node.mute_toggle*", "interface/controls/nodes/editing.html#bpy-ops-node-mute-toggle"),
|
||||
("bpy.ops.object.hide_view*", "scene_layout/object/editing/show_hide.html#bpy-ops-object-hide-view"),
|
||||
("bpy.ops.object.track_set*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-track-set"),
|
||||
("bpy.ops.pose.paths_clear*", "animation/motion_paths.html#bpy-ops-pose-paths-clear"),
|
||||
("bpy.ops.pose.scale_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-scale-clear"),
|
||||
("bpy.ops.poselib.pose_add*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-add"),
|
||||
("bpy.ops.scene.view_layer*", "render/layers/introduction.html#bpy-ops-scene-view-layer"),
|
||||
@@ -2191,6 +2325,7 @@ url_manual_mapping = (
|
||||
("bpy.types.armature.show*", "animation/armatures/properties/display.html#bpy-types-armature-show"),
|
||||
("bpy.types.armaturebones*", "animation/armatures/bones/index.html#bpy-types-armaturebones"),
|
||||
("bpy.types.arraymodifier*", "modeling/modifiers/generate/array.html#bpy-types-arraymodifier"),
|
||||
("bpy.types.assetmetadata*", "editors/asset_browser.html#bpy-types-assetmetadata"),
|
||||
("bpy.types.bevelmodifier*", "modeling/modifiers/generate/bevel.html#bpy-types-bevelmodifier"),
|
||||
("bpy.types.buildmodifier*", "modeling/modifiers/generate/build.html#bpy-types-buildmodifier"),
|
||||
("bpy.types.clothmodifier*", "physics/cloth/index.html#bpy-types-clothmodifier"),
|
||||
@@ -2315,6 +2450,7 @@ url_manual_mapping = (
|
||||
("bpy.types.weldmodifier*", "modeling/modifiers/generate/weld.html#bpy-types-weldmodifier"),
|
||||
("bpy.types.wipesequence*", "video_editing/sequencer/strips/transitions/wipe.html#bpy-types-wipesequence"),
|
||||
("bpy.ops.armature.fill*", "animation/armatures/bones/editing/fill_between_joints.html#bpy-ops-armature-fill"),
|
||||
("bpy.ops.asset.tag_add*", "editors/asset_browser.html#bpy-ops-asset-tag-add"),
|
||||
("bpy.ops.clip.prefetch*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-prefetch"),
|
||||
("bpy.ops.clip.set_axis*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-set-axis"),
|
||||
("bpy.ops.file.pack_all*", "files/blend/packed_data.html#bpy-ops-file-pack-all"),
|
||||
@@ -2399,6 +2535,7 @@ url_manual_mapping = (
|
||||
("bpy.types.lightprobe*", "render/eevee/light_probes/index.html#bpy-types-lightprobe"),
|
||||
("bpy.types.maskparent*", "movie_clip/masking/sidebar.html#bpy-types-maskparent"),
|
||||
("bpy.types.maskspline*", "movie_clip/masking/sidebar.html#bpy-types-maskspline"),
|
||||
("bpy.types.motionpath*", "animation/motion_paths.html#bpy-types-motionpath"),
|
||||
("bpy.types.node.color*", "interface/controls/nodes/sidebar.html#bpy-types-node-color"),
|
||||
("bpy.types.node.label*", "interface/controls/nodes/sidebar.html#bpy-types-node-label"),
|
||||
("bpy.types.nodesocket*", "interface/controls/nodes/parts.html#bpy-types-nodesocket"),
|
||||
@@ -2408,6 +2545,7 @@ url_manual_mapping = (
|
||||
("bpy.types.renderview*", "render/output/properties/stereoscopy/index.html#bpy-types-renderview"),
|
||||
("bpy.types.sceneeevee*", "render/eevee/index.html#bpy-types-sceneeevee"),
|
||||
("bpy.types.vectorfont*", "modeling/texts/index.html#bpy-types-vectorfont"),
|
||||
("bpy.ops.asset.clear*", "files/asset_libraries/introduction.html#bpy-ops-asset-clear"),
|
||||
("bpy.ops.clip.reload*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-reload"),
|
||||
("bpy.ops.curve.split*", "modeling/curves/editing/curve.html#bpy-ops-curve-split"),
|
||||
("bpy.ops.file.cancel*", "editors/file_browser.html#bpy-ops-file-cancel"),
|
||||
@@ -2427,7 +2565,6 @@ url_manual_mapping = (
|
||||
("bpy.ops.uv.rip_move*", "modeling/meshes/uv/tools/rip.html#bpy-ops-uv-rip-move"),
|
||||
("bpy.ops.view3d.snap*", "scene_layout/object/editing/snap.html#bpy-ops-view3d-snap"),
|
||||
("bpy.ops.view3d.zoom*", "editors/3dview/navigate/navigation.html#bpy-ops-view3d-zoom"),
|
||||
("bpy.ops.wm.url_open*", "addons/3d_view/blenderkit.html#bpy-ops-wm-url-open"),
|
||||
("bpy.types.*texspace*", "modeling/meshes/uv/uv_texture_spaces.html#bpy-types-texspace"),
|
||||
("bpy.types.arealight*", "render/lights/light_object.html#bpy-types-arealight"),
|
||||
("bpy.types.blenddata*", "files/data_blocks.html#bpy-types-blenddata"),
|
||||
@@ -2447,6 +2584,7 @@ url_manual_mapping = (
|
||||
("bpy.types.uipiemenu*", "interface/controls/buttons/menus.html#bpy-types-uipiemenu"),
|
||||
("bpy.types.uipopover*", "interface/controls/buttons/menus.html#bpy-types-uipopover"),
|
||||
("bpy.types.viewlayer*", "render/layers/introduction.html#bpy-types-viewlayer"),
|
||||
("bpy.ops.asset.mark*", "files/asset_libraries/introduction.html#bpy-ops-asset-mark"),
|
||||
("bpy.ops.collection*", "scene_layout/collections/collections.html#bpy-ops-collection"),
|
||||
("bpy.ops.constraint*", "animation/constraints/index.html#bpy-ops-constraint"),
|
||||
("bpy.ops.curve.draw*", "modeling/curves/tools/draw.html#bpy-ops-curve-draw"),
|
||||
@@ -2508,7 +2646,6 @@ url_manual_mapping = (
|
||||
("bpy.ops.uv.unwrap*", "modeling/meshes/editing/uv.html#bpy-ops-uv-unwrap"),
|
||||
("bpy.ops.wm.append*", "files/linked_libraries/link_append.html#bpy-ops-wm-append"),
|
||||
("bpy.ops.wm.search*", "interface/controls/templates/operator_search.html#bpy-ops-wm-search"),
|
||||
("bpy.types.animviz*", "animation/motion_paths.html#bpy-types-animviz"),
|
||||
("bpy.types.lattice*", "animation/lattice.html#bpy-types-lattice"),
|
||||
("bpy.types.library*", "files/linked_libraries/index.html#bpy-types-library"),
|
||||
("bpy.types.speaker*", "render/output/audio/speaker.html#bpy-types-speaker"),
|
||||
|
@@ -649,7 +649,7 @@ class AddPresetGpencilBrush(AddPresetBase, Operator):
|
||||
"settings.uv_random",
|
||||
"settings.pen_jitter",
|
||||
"settings.use_jitter_pressure",
|
||||
"settings.trim",
|
||||
"settings.use_trim",
|
||||
]
|
||||
|
||||
preset_subdir = "gpencil_brush"
|
||||
|
@@ -216,11 +216,19 @@ class SequencerFadesAdd(Operator):
|
||||
scene.animation_data.action = action
|
||||
|
||||
sequences = context.selected_sequences
|
||||
|
||||
if not sequences:
|
||||
self.report({'ERROR'}, "No sequences selected")
|
||||
return {'CANCELLED'}
|
||||
|
||||
if self.type in {'CURSOR_TO', 'CURSOR_FROM'}:
|
||||
sequences = [
|
||||
strip for strip in sequences
|
||||
if strip.frame_final_start < scene.frame_current < strip.frame_final_end
|
||||
]
|
||||
if not sequences:
|
||||
self.report({'ERROR'}, "Current frame not within strip framerange")
|
||||
return {'CANCELLED'}
|
||||
|
||||
max_duration = min(sequences, key=lambda strip: strip.frame_final_duration).frame_final_duration
|
||||
max_duration = floor(max_duration / 2.0) if self.type == 'IN_OUT' else max_duration
|
||||
|
@@ -1146,6 +1146,30 @@ class ConstraintButtonsSubPanel:
|
||||
col.prop(con, "frame_start", text="Frame Start")
|
||||
col.prop(con, "frame_end", text="End")
|
||||
|
||||
def draw_transform_cache_velocity(self, context):
|
||||
self.draw_transform_cache_subpanel(
|
||||
context, self.layout.template_cache_file_velocity
|
||||
)
|
||||
|
||||
def draw_transform_cache_procedural(self, context):
|
||||
self.draw_transform_cache_subpanel(
|
||||
context, self.layout.template_cache_file_procedural
|
||||
)
|
||||
|
||||
def draw_transform_cache_time(self, context):
|
||||
self.draw_transform_cache_subpanel(
|
||||
context, self.layout.template_cache_file_time_settings
|
||||
)
|
||||
|
||||
def draw_transform_cache_subpanel(self, context, template_func):
|
||||
con = self.get_constraint(context)
|
||||
if con.cache_file is None:
|
||||
return
|
||||
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = True
|
||||
template_func(con, "cache_file")
|
||||
|
||||
# Child Of Constraint
|
||||
|
||||
@@ -1335,7 +1359,7 @@ class BONE_PT_bLockTrackConstraint(BoneConstraintPanel, ConstraintButtonsPanel,
|
||||
self.draw_lock_track(context)
|
||||
|
||||
|
||||
# Disance Limit Constraint
|
||||
# Distance Limit Constraint
|
||||
|
||||
class OBJECT_PT_bDistLimitConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
|
||||
def draw(self, context):
|
||||
@@ -1534,6 +1558,54 @@ class BONE_PT_bTransformCacheConstraint(BoneConstraintPanel, ConstraintButtonsPa
|
||||
self.draw_transform_cache(context)
|
||||
|
||||
|
||||
class OBJECT_PT_bTransformCacheConstraint_velocity(ObjectConstraintPanel, ConstraintButtonsSubPanel, Panel):
|
||||
bl_parent_id = "OBJECT_PT_bTransformCacheConstraint"
|
||||
bl_label = "Velocity"
|
||||
|
||||
def draw(self, context):
|
||||
self.draw_transform_cache_velocity(context)
|
||||
|
||||
|
||||
class BONE_PT_bTransformCacheConstraint_velocity(BoneConstraintPanel, ConstraintButtonsSubPanel, Panel):
|
||||
bl_parent_id = "BONE_PT_bTransformCacheConstraint"
|
||||
bl_label = "Velocity"
|
||||
|
||||
def draw(self, context):
|
||||
self.draw_transform_cache_velocity(context)
|
||||
|
||||
|
||||
class OBJECT_PT_bTransformCacheConstraint_procedural(ObjectConstraintPanel, ConstraintButtonsSubPanel, Panel):
|
||||
bl_parent_id = "OBJECT_PT_bTransformCacheConstraint"
|
||||
bl_label = "Render Procedural"
|
||||
|
||||
def draw(self, context):
|
||||
self.draw_transform_cache_procedural(context)
|
||||
|
||||
|
||||
class BONE_PT_bTransformCacheConstraint_procedural(BoneConstraintPanel, ConstraintButtonsSubPanel, Panel):
|
||||
bl_parent_id = "BONE_PT_bTransformCacheConstraint"
|
||||
bl_label = "Render Procedural"
|
||||
|
||||
def draw(self, context):
|
||||
self.draw_transform_cache_procedural(context)
|
||||
|
||||
|
||||
class OBJECT_PT_bTransformCacheConstraint_time(ObjectConstraintPanel, ConstraintButtonsSubPanel, Panel):
|
||||
bl_parent_id = "OBJECT_PT_bTransformCacheConstraint"
|
||||
bl_label = "Time"
|
||||
|
||||
def draw(self, context):
|
||||
self.draw_transform_cache_time(context)
|
||||
|
||||
|
||||
class BONE_PT_bTransformCacheConstraint_time(BoneConstraintPanel, ConstraintButtonsSubPanel, Panel):
|
||||
bl_parent_id = "BONE_PT_bTransformCacheConstraint"
|
||||
bl_label = "Time"
|
||||
|
||||
def draw(self, context):
|
||||
self.draw_transform_cache_time(context)
|
||||
|
||||
|
||||
# Python Constraint
|
||||
|
||||
class OBJECT_PT_bPythonConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
|
||||
@@ -1620,6 +1692,9 @@ classes = (
|
||||
OBJECT_PT_bCameraSolverConstraint,
|
||||
OBJECT_PT_bObjectSolverConstraint,
|
||||
OBJECT_PT_bTransformCacheConstraint,
|
||||
OBJECT_PT_bTransformCacheConstraint_time,
|
||||
OBJECT_PT_bTransformCacheConstraint_procedural,
|
||||
OBJECT_PT_bTransformCacheConstraint_velocity,
|
||||
OBJECT_PT_bPythonConstraint,
|
||||
OBJECT_PT_bArmatureConstraint,
|
||||
OBJECT_PT_bArmatureConstraint_bones,
|
||||
@@ -1657,6 +1732,9 @@ classes = (
|
||||
BONE_PT_bCameraSolverConstraint,
|
||||
BONE_PT_bObjectSolverConstraint,
|
||||
BONE_PT_bTransformCacheConstraint,
|
||||
BONE_PT_bTransformCacheConstraint_time,
|
||||
BONE_PT_bTransformCacheConstraint_procedural,
|
||||
BONE_PT_bTransformCacheConstraint_velocity,
|
||||
BONE_PT_bPythonConstraint,
|
||||
BONE_PT_bArmatureConstraint,
|
||||
BONE_PT_bArmatureConstraint_bones,
|
||||
|
@@ -298,6 +298,8 @@ class GRAPH_MT_key(Menu):
|
||||
layout.operator("graph.decimate", text="Decimate (Allowed Change)").mode = 'ERROR'
|
||||
layout.operator_context = operator_context
|
||||
|
||||
layout.menu("GRAPH_MT_slider", text="Slider Operators")
|
||||
|
||||
layout.operator("graph.clean").channels = False
|
||||
layout.operator("graph.clean", text="Clean Channels").channels = True
|
||||
layout.operator("graph.smooth")
|
||||
@@ -337,6 +339,15 @@ class GRAPH_MT_key_snap(Menu):
|
||||
layout.operator("graph.frame_jump", text="Cursor to Selection")
|
||||
layout.operator("graph.snap_cursor_value", text="Cursor Value to Selection")
|
||||
|
||||
class GRAPH_MT_slider(Menu):
|
||||
bl_label = "Slider Operators"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("graph.breakdown", text="Breakdown")
|
||||
layout.operator("graph.blend_to_neighbor", text="Blend To Neighbor")
|
||||
|
||||
|
||||
class GRAPH_MT_view_pie(Menu):
|
||||
bl_label = "View"
|
||||
@@ -475,6 +486,7 @@ classes = (
|
||||
GRAPH_MT_key,
|
||||
GRAPH_MT_key_transform,
|
||||
GRAPH_MT_key_snap,
|
||||
GRAPH_MT_slider,
|
||||
GRAPH_MT_delete,
|
||||
GRAPH_MT_context_menu,
|
||||
GRAPH_MT_channel_context_menu,
|
||||
|
@@ -772,6 +772,17 @@ class USERPREF_PT_viewport_selection(ViewportPanel, CenterAlignMixIn, Panel):
|
||||
layout.prop(system, "use_select_pick_depth")
|
||||
|
||||
|
||||
class USERPREF_PT_viewport_subdivision(ViewportPanel, CenterAlignMixIn, Panel):
|
||||
bl_label = "Subdivision"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw_centered(self, context, layout):
|
||||
prefs = context.preferences
|
||||
system = prefs.system
|
||||
|
||||
layout.prop(system, "use_gpu_subdivision")
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Theme Panels
|
||||
|
||||
@@ -2342,6 +2353,7 @@ classes = (
|
||||
USERPREF_PT_viewport_quality,
|
||||
USERPREF_PT_viewport_textures,
|
||||
USERPREF_PT_viewport_selection,
|
||||
USERPREF_PT_viewport_subdivision,
|
||||
|
||||
USERPREF_PT_edit_objects,
|
||||
USERPREF_PT_edit_objects_new,
|
||||
|
@@ -698,6 +698,8 @@ class VIEW3D_PT_tools_weight_gradient(Panel, View3DPaintPanel):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
settings = context.tool_settings.weight_paint
|
||||
if settings is None:
|
||||
return False
|
||||
brush = settings.brush
|
||||
return brush is not None
|
||||
|
||||
|
@@ -753,6 +753,7 @@ geometry_node_categories = [
|
||||
NodeItem("GeometryNodeImageTexture"),
|
||||
]),
|
||||
GeometryNodeCategory("GEO_UTILITIES", "Utilities", items=[
|
||||
NodeItem("GeometryNodeAccumulateField"),
|
||||
NodeItem("ShaderNodeMapRange"),
|
||||
NodeItem("ShaderNodeFloatCurve"),
|
||||
NodeItem("ShaderNodeClamp"),
|
||||
|
@@ -413,14 +413,6 @@ void DM_calc_loop_tangents(DerivedMesh *dm,
|
||||
const char (*tangent_names)[MAX_NAME],
|
||||
int tangent_names_len);
|
||||
|
||||
/* debug only */
|
||||
#ifndef NDEBUG
|
||||
char *DM_debug_info(DerivedMesh *dm);
|
||||
void DM_debug_print(DerivedMesh *dm);
|
||||
|
||||
bool DM_is_valid(DerivedMesh *dm);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -253,12 +253,28 @@ void BKE_pose_channel_session_uuid_generate(struct bPoseChannel *pchan);
|
||||
*/
|
||||
struct bPoseChannel *BKE_pose_channel_find_name(const struct bPose *pose, const char *name);
|
||||
/**
|
||||
* Find the active pose-channel for an object
|
||||
* (we can't just use pose, as layer info is in armature)
|
||||
* Checks if the bone is on a visible armature layer
|
||||
*
|
||||
* \note #Object, not #bPose is used here, as we need layer info from Armature.
|
||||
* \return true if on a visible layer, false otherwise.
|
||||
*/
|
||||
struct bPoseChannel *BKE_pose_channel_active(struct Object *ob);
|
||||
bool BKE_pose_is_layer_visible(const struct bArmature *arm, const struct bPoseChannel *pchan);
|
||||
/**
|
||||
* Find the active pose-channel for an object
|
||||
*
|
||||
* \param check_arm_layer: checks if the bone is on a visible armature layer (this might be skipped
|
||||
* (e.g. for "Show Active" from the Outliner).
|
||||
* \return #bPoseChannel if found or NULL.
|
||||
* \note #Object, not #bPose is used here, as we need info (layer/active bone) from Armature.
|
||||
*/
|
||||
struct bPoseChannel *BKE_pose_channel_active(struct Object *ob, const bool check_arm_layer);
|
||||
/**
|
||||
* Find the active pose-channel for an object if it is on a visible armature layer
|
||||
* (calls #BKE_pose_channel_active with check_arm_layer set to true)
|
||||
*
|
||||
* \return #bPoseChannel if found or NULL.
|
||||
* \note #Object, not #bPose is used here, as we need info (layer/active bone) from Armature.
|
||||
*/
|
||||
struct bPoseChannel *BKE_pose_channel_active_if_layer_visible(struct Object *ob);
|
||||
/**
|
||||
* Use this when detecting the "other selected bone",
|
||||
* when we have multiple armatures in pose mode.
|
||||
|
@@ -186,11 +186,6 @@ void BKE_animdata_transfer_by_basepath(struct Main *bmain,
|
||||
struct ID *dstID,
|
||||
struct ListBase *basepaths);
|
||||
|
||||
char *BKE_animdata_driver_path_hack(struct bContext *C,
|
||||
struct PointerRNA *ptr,
|
||||
struct PropertyRNA *prop,
|
||||
char *base_path);
|
||||
|
||||
/* ************************************* */
|
||||
/* Batch AnimData API */
|
||||
|
||||
|
@@ -38,10 +38,6 @@ struct ID;
|
||||
struct ReportList;
|
||||
|
||||
/* Attribute.domain */
|
||||
/**
|
||||
* \warning Careful when changing existing items.
|
||||
* Arrays may be initialized from this (e.g. #DATASET_layout_hierarchy).
|
||||
*/
|
||||
typedef enum AttributeDomain {
|
||||
ATTR_DOMAIN_AUTO = -1, /* Use for nodes to choose automatically based on other data. */
|
||||
ATTR_DOMAIN_POINT = 0, /* Mesh, Hair or PointCloud Point */
|
||||
|
@@ -30,6 +30,39 @@
|
||||
#include "BLI_float3.hh"
|
||||
#include "BLI_function_ref.hh"
|
||||
|
||||
/**
|
||||
* This file defines classes that help to provide access to attribute data on a #GeometryComponent.
|
||||
* The API for retrieving attributes is defined in `BKE_geometry_set.hh`, but this comment has some
|
||||
* general comments about the system.
|
||||
*
|
||||
* Attributes are stored in geometry data, though they can also be stored in instances. Their
|
||||
* storage is often tied to `CustomData`, which is a system to store "layers" of data with specific
|
||||
* types and names. However, since `CustomData` was added to Blender before attributes were
|
||||
* conceptualized, it combines the "legacy" style of task-specific attribute types with generic
|
||||
* types like "Float". The attribute API here only provides access to generic types.
|
||||
*
|
||||
* Attributes are retrieved from geometry components by providing an "id" (#AttributeIDRef). This
|
||||
* is most commonly just an attribute name. The attribute API on geometry components has some more
|
||||
* advanced capabilities:
|
||||
* 1. Read-only access: With a `const` geometry component, an attribute on the geometry cannot be
|
||||
* modified, so the `for_write` and `for_output` versions of the API are not available. This is
|
||||
* extremely important for writing coherent bug-free code. When an attribute is retrieved with
|
||||
* write access, via #WriteAttributeLookup or #OutputAttribute, the geometry component must be
|
||||
* tagged to clear caches that depend on the changed data.
|
||||
* 2. Domain interpolation: When retrieving an attribute, a domain (#AttributeDomain) can be
|
||||
* provided. If the attribute is stored on a different domain and conversion is possible, a
|
||||
* version of the data interpolated to the requested domain will be provided. These conversions
|
||||
* are implemented in each #GeometryComponent by `attribute_try_adapt_domain_impl`.
|
||||
* 3. Implicit type conversion: In addition to interpolating domains, attribute types can be
|
||||
* converted, using the conversions in `BKE_type_conversions.hh`. The #VArray / #GVArray system
|
||||
* makes it possible to only convert necessary indices on-demand.
|
||||
* 4. Anonymous attributes: The "id" used to look up an attribute can also be an anonymous
|
||||
* attribute reference. Currently anonymous attributes are only used in geometry nodes.
|
||||
* 5. Abstracted storage: Since the data returned from the API is usually a virtual array,
|
||||
* it doesn't have to be stored contiguously (even though that is generally preferred). This
|
||||
* allows accessing "legacy" attributes like `material_index`, which is stored in `MPoly`.
|
||||
*/
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
/**
|
||||
@@ -181,11 +214,14 @@ struct ReadAttributeLookup {
|
||||
* Used when looking up a "plain attribute" based on a name for reading from it and writing to it.
|
||||
*/
|
||||
struct WriteAttributeLookup {
|
||||
/* The virtual array that is used to read from and write to the attribute. */
|
||||
/** The virtual array that is used to read from and write to the attribute. */
|
||||
GVMutableArray varray;
|
||||
/* Domain the attributes lives on in the geometry. */
|
||||
/** Domain the attributes lives on in the geometry component. */
|
||||
AttributeDomain domain;
|
||||
/* Call this after changing the attribute to invalidate caches that depend on this attribute. */
|
||||
/**
|
||||
* Call this after changing the attribute to invalidate caches that depend on this attribute.
|
||||
* \note Do not call this after the component the attribute is from has been destructed.
|
||||
*/
|
||||
std::function<void()> tag_modified_fn;
|
||||
|
||||
/* Convenience function to check if the attribute has been found. */
|
||||
@@ -205,6 +241,10 @@ struct WriteAttributeLookup {
|
||||
* VMutableArray_Span in many cases).
|
||||
* - An output attribute can live side by side with an existing attribute with a different domain
|
||||
* or data type. The old attribute will only be overwritten when the #save function is called.
|
||||
*
|
||||
* \note The lifetime of an output attribute should not be longer than the the lifetime of the
|
||||
* geometry component it comes from, since it can keep a reference to the component for use in
|
||||
* the #save method.
|
||||
*/
|
||||
class OutputAttribute {
|
||||
public:
|
||||
|
@@ -163,7 +163,21 @@ bool BKE_scene_collections_object_remove(struct Main *bmain,
|
||||
struct Scene *scene,
|
||||
struct Object *object,
|
||||
const bool free_us);
|
||||
|
||||
/**
|
||||
* Check all collections in \a bmain (including embedded ones in scenes) for CollectionObject with
|
||||
* NULL object pointer, and remove them.
|
||||
*/
|
||||
void BKE_collections_object_remove_nulls(struct Main *bmain);
|
||||
|
||||
/**
|
||||
* Check all collections in \a bmain (including embedded ones in scenes) for duplicate
|
||||
* CollectionObject with a same object pointer within a same object, and remove them.
|
||||
*
|
||||
* NOTE: Always keeps the first of the detected duplicates.
|
||||
*/
|
||||
void BKE_collections_object_remove_duplicates(struct Main *bmain);
|
||||
|
||||
/**
|
||||
* Remove all NULL children from parent collections of changed \a collection.
|
||||
* This is used for library remapping, where these pointers have been set to NULL.
|
||||
|
@@ -282,8 +282,9 @@ bool CTX_data_dir(const char *member);
|
||||
ListBase ctx_data_list; \
|
||||
CollectionPointerLink *ctx_link; \
|
||||
CTX_data_##member(C, &ctx_data_list); \
|
||||
for (ctx_link = ctx_data_list.first; ctx_link; ctx_link = ctx_link->next) { \
|
||||
Type instance = ctx_link->ptr.data;
|
||||
for (ctx_link = (CollectionPointerLink *)ctx_data_list.first; ctx_link; \
|
||||
ctx_link = ctx_link->next) { \
|
||||
Type instance = (Type)ctx_link->ptr.data;
|
||||
|
||||
#define CTX_DATA_END \
|
||||
} \
|
||||
|
@@ -104,6 +104,13 @@ void driver_change_variable_type(struct DriverVar *dvar, int type);
|
||||
*
|
||||
*/
|
||||
void driver_variable_name_validate(struct DriverVar *dvar);
|
||||
/**
|
||||
* Ensure the driver variable's name is unique.
|
||||
*
|
||||
* Assumes the driver variable has already been assigned to the driver, so that
|
||||
* the prev/next pointers can be used to find the other variables.
|
||||
*/
|
||||
void driver_variable_unique_name(struct DriverVar *dvar);
|
||||
/**
|
||||
* Add a new driver variable.
|
||||
*/
|
||||
|
@@ -93,41 +93,64 @@ class GeometryComponent {
|
||||
|
||||
GeometryComponentType type() const;
|
||||
|
||||
/* Return true when any attribute with this name exists, including built in attributes. */
|
||||
/**
|
||||
* Return true when any attribute with this name exists, including built in attributes.
|
||||
*/
|
||||
bool attribute_exists(const blender::bke::AttributeIDRef &attribute_id) const;
|
||||
|
||||
/* Return the data type and domain of an attribute with the given name if it exists. */
|
||||
/**
|
||||
* Return the data type and domain of an attribute with the given name if it exists.
|
||||
*/
|
||||
std::optional<AttributeMetaData> attribute_get_meta_data(
|
||||
const blender::bke::AttributeIDRef &attribute_id) const;
|
||||
|
||||
/* Returns true when the geometry component supports this attribute domain. */
|
||||
/**
|
||||
* Return true when the geometry component supports this attribute domain.
|
||||
* \note Conceptually this function is static, the result is always the same for different
|
||||
* instances of the same geometry component type.
|
||||
*/
|
||||
bool attribute_domain_supported(const AttributeDomain domain) const;
|
||||
/* Can only be used with supported domain types. */
|
||||
/**
|
||||
* Return the length of a specific domain, or 0 if the domain is not supported.
|
||||
*/
|
||||
virtual int attribute_domain_size(const AttributeDomain domain) const;
|
||||
|
||||
/**
|
||||
* Return true if the attribute name corresponds to a built-in attribute with a hardcoded domain
|
||||
* and data type.
|
||||
*/
|
||||
bool attribute_is_builtin(const blender::StringRef attribute_name) const;
|
||||
bool attribute_is_builtin(const blender::bke::AttributeIDRef &attribute_id) const;
|
||||
|
||||
/* Get read-only access to the highest priority attribute with the given name.
|
||||
* Returns null if the attribute does not exist. */
|
||||
/**
|
||||
* Get read-only access to an attribute with the given name or id, on the highest priority domain
|
||||
* if there is a name collision.
|
||||
* \return null if the attribute does not exist.
|
||||
*/
|
||||
blender::bke::ReadAttributeLookup attribute_try_get_for_read(
|
||||
const blender::bke::AttributeIDRef &attribute_id) const;
|
||||
|
||||
/* Get read and write access to the highest priority attribute with the given name.
|
||||
* Returns null if the attribute does not exist. */
|
||||
/**
|
||||
* Get read and write access to an attribute with the given name or id, on the highest priority
|
||||
* domain if there is a name collision.
|
||||
* \note #WriteAttributeLookup.tag_modified_fn must be called after modifying data.
|
||||
* \return null if the attribute does not exist
|
||||
*/
|
||||
blender::bke::WriteAttributeLookup attribute_try_get_for_write(
|
||||
const blender::bke::AttributeIDRef &attribute_id);
|
||||
|
||||
/* Get a read-only attribute for the domain based on the given attribute. This can be used to
|
||||
/**
|
||||
* Get a read-only attribute for the domain based on the given attribute. This can be used to
|
||||
* interpolate from one domain to another.
|
||||
* Returns null if the interpolation is not implemented. */
|
||||
* \return null if the interpolation is not implemented.
|
||||
*/
|
||||
blender::fn::GVArray attribute_try_adapt_domain(const blender::fn::GVArray &varray,
|
||||
const AttributeDomain from_domain,
|
||||
const AttributeDomain to_domain) const
|
||||
{
|
||||
return this->attribute_try_adapt_domain_impl(varray, from_domain, to_domain);
|
||||
}
|
||||
|
||||
/* Use instead of the method above when the type is known at compile time for type safety. */
|
||||
template<typename T>
|
||||
blender::VArray<T> attribute_try_adapt_domain(const blender::VArray<T> &varray,
|
||||
const AttributeDomain from_domain,
|
||||
@@ -137,17 +160,19 @@ class GeometryComponent {
|
||||
.template typed<T>();
|
||||
}
|
||||
|
||||
/* Returns true when the attribute has been deleted. */
|
||||
/** Returns true when the attribute has been deleted. */
|
||||
bool attribute_try_delete(const blender::bke::AttributeIDRef &attribute_id);
|
||||
|
||||
/* Returns true when the attribute has been created. */
|
||||
/** Returns true when the attribute has been created. */
|
||||
bool attribute_try_create(const blender::bke::AttributeIDRef &attribute_id,
|
||||
const AttributeDomain domain,
|
||||
const CustomDataType data_type,
|
||||
const AttributeInit &initializer);
|
||||
|
||||
/* Try to create the builtin attribute with the given name. No data type or domain has to be
|
||||
* provided, because those are fixed for builtin attributes. */
|
||||
/**
|
||||
* Try to create the builtin attribute with the given name. No data type or domain has to be
|
||||
* provided, because those are fixed for builtin attributes.
|
||||
*/
|
||||
bool attribute_try_create_builtin(const blender::StringRef attribute_name,
|
||||
const AttributeInit &initializer);
|
||||
|
||||
@@ -160,34 +185,41 @@ class GeometryComponent {
|
||||
|
||||
virtual bool is_empty() const;
|
||||
|
||||
/* Get a virtual array to read the data of an attribute on the given domain and data type.
|
||||
* Returns null when the attribute does not exist or cannot be converted to the requested domain
|
||||
* and data type. */
|
||||
/**
|
||||
* Get a virtual array that refers to the data of an attribute, interpolated to the given domain
|
||||
* and converted to the data type. Returns null when the attribute does not exist or cannot be
|
||||
* interpolated or converted.
|
||||
*/
|
||||
blender::fn::GVArray attribute_try_get_for_read(const blender::bke::AttributeIDRef &attribute_id,
|
||||
const AttributeDomain domain,
|
||||
const CustomDataType data_type) const;
|
||||
|
||||
/* Get a virtual array to read the data of an attribute on the given domain. The data type is
|
||||
* left unchanged. Returns null when the attribute does not exist or cannot be adapted to the
|
||||
* requested domain. */
|
||||
/**
|
||||
* Get a virtual array that refers to the data of an attribute, interpolated to the given domain.
|
||||
* The data type is left unchanged. Returns null when the attribute does not exist or cannot be
|
||||
* interpolated.
|
||||
*/
|
||||
blender::fn::GVArray attribute_try_get_for_read(const blender::bke::AttributeIDRef &attribute_id,
|
||||
const AttributeDomain domain) const;
|
||||
|
||||
/* Get a virtual array to read data of an attribute with the given data type. The domain is
|
||||
* left unchanged. Returns null when the attribute does not exist or cannot be converted to the
|
||||
* requested data type. */
|
||||
/**
|
||||
* Get a virtual array that refers to the data of an attribute converted to the given data type.
|
||||
* The attribute's domain is left unchanged. Returns null when the attribute does not exist or
|
||||
* cannot be converted.
|
||||
*/
|
||||
blender::bke::ReadAttributeLookup attribute_try_get_for_read(
|
||||
const blender::bke::AttributeIDRef &attribute_id, const CustomDataType data_type) const;
|
||||
|
||||
/* Get a virtual array to read the data of an attribute. If that is not possible, the returned
|
||||
* virtual array will contain a default value. This never returns null. */
|
||||
/**
|
||||
* Get a virtual array that refers to the data of an attribute, interpolated to the given domain
|
||||
* and converted to the data type. If that is not possible, the returned virtual array will
|
||||
* contain a default value. This never returns null.
|
||||
*/
|
||||
blender::fn::GVArray attribute_get_for_read(const blender::bke::AttributeIDRef &attribute_id,
|
||||
const AttributeDomain domain,
|
||||
const CustomDataType data_type,
|
||||
const void *default_value = nullptr) const;
|
||||
|
||||
/* Should be used instead of the method above when the requested data type is known at compile
|
||||
* time for better type safety. */
|
||||
/* Use instead of the method above when the type is known at compile time for type safety. */
|
||||
template<typename T>
|
||||
blender::VArray<T> attribute_get_for_read(const blender::bke::AttributeIDRef &attribute_id,
|
||||
const AttributeDomain domain,
|
||||
@@ -214,16 +246,7 @@ class GeometryComponent {
|
||||
const AttributeDomain domain,
|
||||
const CustomDataType data_type,
|
||||
const void *default_value = nullptr);
|
||||
|
||||
/* Same as attribute_try_get_for_output, but should be used when the original values in the
|
||||
* attributes are not read, i.e. the attribute is used only for output. Since values are not read
|
||||
* from this attribute, no default value is necessary. */
|
||||
blender::bke::OutputAttribute attribute_try_get_for_output_only(
|
||||
const blender::bke::AttributeIDRef &attribute_id,
|
||||
const AttributeDomain domain,
|
||||
const CustomDataType data_type);
|
||||
|
||||
/* Statically typed method corresponding to the equally named generic one. */
|
||||
/* Use instead of the method above when the type is known at compile time for type safety. */
|
||||
template<typename T>
|
||||
blender::bke::OutputAttribute_Typed<T> attribute_try_get_for_output(
|
||||
const blender::bke::AttributeIDRef &attribute_id,
|
||||
@@ -235,7 +258,17 @@ class GeometryComponent {
|
||||
return this->attribute_try_get_for_output(attribute_id, domain, data_type, &default_value);
|
||||
}
|
||||
|
||||
/* Statically typed method corresponding to the equally named generic one. */
|
||||
/**
|
||||
* Same as #attribute_try_get_for_output, but should be used when the original values in the
|
||||
* attributes are not read, i.e. the attribute is used only for output. The can be faster because
|
||||
* it can avoid interpolation and conversion of existing values. Since values are not read from
|
||||
* this attribute, no default value is necessary.
|
||||
*/
|
||||
blender::bke::OutputAttribute attribute_try_get_for_output_only(
|
||||
const blender::bke::AttributeIDRef &attribute_id,
|
||||
const AttributeDomain domain,
|
||||
const CustomDataType data_type);
|
||||
/* Use instead of the method above when the type is known at compile time for type safety. */
|
||||
template<typename T>
|
||||
blender::bke::OutputAttribute_Typed<T> attribute_try_get_for_output_only(
|
||||
const blender::bke::AttributeIDRef &attribute_id, const AttributeDomain domain)
|
||||
@@ -339,7 +372,7 @@ struct GeometrySet {
|
||||
*/
|
||||
blender::Vector<const GeometryComponent *> get_components_for_read() const;
|
||||
|
||||
void compute_boundbox_without_instances(blender::float3 *r_min, blender::float3 *r_max) const;
|
||||
bool compute_boundbox_without_instances(blender::float3 *r_min, blender::float3 *r_max) const;
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &stream, const GeometrySet &geometry_set);
|
||||
|
||||
@@ -889,6 +922,11 @@ class InstancesComponent : public GeometryComponent {
|
||||
int instances_amount() const;
|
||||
int references_amount() const;
|
||||
|
||||
/**
|
||||
* Remove the indices in the selection mask and remove unused instance references afterwards.
|
||||
*/
|
||||
void remove_instances(const blender::IndexMask selection);
|
||||
|
||||
blender::Span<int> almost_unique_ids() const;
|
||||
|
||||
blender::bke::CustomDataAttributes &attributes();
|
||||
|
@@ -867,15 +867,12 @@ void BKE_mesh_calc_relative_deform(const struct MPoly *mpoly,
|
||||
bool BKE_mesh_validate(struct Mesh *me, const bool do_verbose, const bool cddata_check_mask);
|
||||
/**
|
||||
* Checks if a Mesh is valid without any modification. This is always verbose.
|
||||
*
|
||||
* \see #DM_is_valid to call on derived meshes
|
||||
*
|
||||
* \returns is_valid.
|
||||
* \returns True if the mesh is valid.
|
||||
*/
|
||||
bool BKE_mesh_is_valid(struct Mesh *me);
|
||||
/**
|
||||
* Check all material indices of polygons are valid, invalid ones are set to 0.
|
||||
* \returns is_valid.
|
||||
* \returns True if the material indices are valid.
|
||||
*/
|
||||
bool BKE_mesh_validate_material_indices(struct Mesh *me);
|
||||
|
||||
|
@@ -22,6 +22,7 @@
|
||||
struct BMEditMesh;
|
||||
struct CustomData_MeshMasks;
|
||||
struct Mesh;
|
||||
struct Object;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -51,6 +52,8 @@ void BKE_mesh_wrapper_vert_coords_copy_with_mat4(const struct Mesh *me,
|
||||
int vert_coords_len,
|
||||
const float mat[4][4]);
|
||||
|
||||
struct Mesh *BKE_mesh_wrapper_ensure_subdivision(const struct Object *ob, struct Mesh *me);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -34,6 +34,7 @@
|
||||
#include "RNA_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
# include "BLI_map.hh"
|
||||
# include "BLI_string_ref.hh"
|
||||
#endif
|
||||
|
||||
@@ -413,7 +414,6 @@ typedef struct bNodeTreeType {
|
||||
|
||||
/* calls allowing threaded composite */
|
||||
void (*localize)(struct bNodeTree *localtree, struct bNodeTree *ntree);
|
||||
void (*local_sync)(struct bNodeTree *localtree, struct bNodeTree *ntree);
|
||||
void (*local_merge)(struct Main *bmain, struct bNodeTree *localtree, struct bNodeTree *ntree);
|
||||
|
||||
/* Tree update. Overrides `nodetype->updatetreefunc` ! */
|
||||
@@ -501,16 +501,13 @@ void ntreeFreeLocalTree(struct bNodeTree *ntree);
|
||||
struct bNode *ntreeFindType(const struct bNodeTree *ntree, int type);
|
||||
bool ntreeHasType(const struct bNodeTree *ntree, int type);
|
||||
bool ntreeHasTree(const struct bNodeTree *ntree, const struct bNodeTree *lookup);
|
||||
void ntreeUpdateTree(struct Main *main, struct bNodeTree *ntree);
|
||||
void ntreeUpdateAllNew(struct Main *main);
|
||||
/**
|
||||
* \param tree_update_flag: #eNodeTreeUpdate enum.
|
||||
*/
|
||||
void ntreeUpdateAllUsers(struct Main *main, struct ID *id, int tree_update_flag);
|
||||
void ntreeUpdateAllUsers(struct Main *main, struct ID *id);
|
||||
|
||||
void ntreeGetDependencyList(struct bNodeTree *ntree,
|
||||
struct bNode ***r_deplist,
|
||||
int *r_deplist_len);
|
||||
void ntreeUpdateNodeLevels(struct bNodeTree *ntree);
|
||||
|
||||
/**
|
||||
* XXX: old trees handle output flags automatically based on special output
|
||||
@@ -521,20 +518,11 @@ void ntreeSetOutput(struct bNodeTree *ntree);
|
||||
|
||||
void ntreeFreeCache(struct bNodeTree *ntree);
|
||||
|
||||
bool ntreeNodeExists(const struct bNodeTree *ntree, const struct bNode *testnode);
|
||||
bool ntreeOutputExists(const struct bNode *node, const struct bNodeSocket *testsock);
|
||||
void ntreeNodeFlagSet(const bNodeTree *ntree, const int flag, const bool enable);
|
||||
/**
|
||||
* Returns localized tree for execution in threads.
|
||||
*/
|
||||
struct bNodeTree *ntreeLocalize(struct bNodeTree *ntree);
|
||||
/**
|
||||
* Sync local composite with real tree.
|
||||
* The local tree is supposed to be running, be careful moving previews!
|
||||
*
|
||||
* Is called by jobs manager, outside threads, so it doesn't happen during draw.
|
||||
*/
|
||||
void ntreeLocalSync(struct bNodeTree *localtree, struct bNodeTree *ntree);
|
||||
/**
|
||||
* Merge local tree results back, and free local tree.
|
||||
*
|
||||
@@ -700,31 +688,28 @@ void nodeRemoveNode(struct Main *bmain,
|
||||
struct bNode *node,
|
||||
bool do_id_user);
|
||||
|
||||
/**
|
||||
* \param ntree: is the target tree.
|
||||
*
|
||||
* \note keep socket list order identical, for copying links.
|
||||
* \note `unique_name` needs to be true. It's only disabled for speed when doing GPUnodetrees.
|
||||
*/
|
||||
struct bNode *BKE_node_copy_ex(struct bNodeTree *ntree,
|
||||
const struct bNode *node_src,
|
||||
const int flag,
|
||||
const bool unique_name);
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
/**
|
||||
* Same as #BKE_node_copy_ex but stores pointers to a new node and its sockets in the source node.
|
||||
*
|
||||
* NOTE: DANGER ZONE!
|
||||
*
|
||||
* TODO(sergey): Maybe it's better to make BKE_node_copy_ex() return a mapping from old node and
|
||||
* sockets to new one.
|
||||
* \note keeps socket list order identical, for copying links.
|
||||
* \note `unique_name` should usually be true, unless the \a dst_tree is temporary,
|
||||
* or the names can already be assumed valid.
|
||||
*/
|
||||
struct bNode *BKE_node_copy_store_new_pointers(struct bNodeTree *ntree,
|
||||
struct bNode *node_src,
|
||||
const int flag);
|
||||
struct bNodeTree *ntreeCopyTree_ex_new_pointers(const struct bNodeTree *ntree,
|
||||
struct Main *bmain,
|
||||
const bool do_id_user);
|
||||
bNode *node_copy_with_mapping(bNodeTree *dst_tree,
|
||||
const bNode &node_src,
|
||||
int flag,
|
||||
bool unique_name,
|
||||
Map<const bNodeSocket *, bNodeSocket *> &new_socket_map);
|
||||
|
||||
bNode *node_copy(bNodeTree *dst_tree, const bNode &src_node, int flag, bool unique_name);
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
#endif
|
||||
|
||||
bNode *BKE_node_copy(bNodeTree *dst_tree, const bNode *src_node, int flag, bool unique_name);
|
||||
|
||||
/**
|
||||
* Also used via RNA API, so we check for proper input output direction.
|
||||
@@ -833,12 +818,7 @@ void nodeClearActive(struct bNodeTree *ntree);
|
||||
void nodeClearActiveID(struct bNodeTree *ntree, short idtype);
|
||||
struct bNode *nodeGetActiveTexture(struct bNodeTree *ntree);
|
||||
|
||||
void nodeUpdate(struct bNodeTree *ntree, struct bNode *node);
|
||||
bool nodeUpdateID(struct bNodeTree *ntree, struct ID *id);
|
||||
void nodeUpdateInternalLinks(struct bNodeTree *ntree, struct bNode *node);
|
||||
|
||||
int nodeSocketIsHidden(const struct bNodeSocket *sock);
|
||||
void ntreeTagUsedSockets(struct bNodeTree *ntree);
|
||||
void nodeSetSocketAvailability(struct bNodeTree *ntree,
|
||||
struct bNodeSocket *sock,
|
||||
bool is_available);
|
||||
@@ -960,28 +940,16 @@ bNodePreview *BKE_node_preview_verify(
|
||||
struct bNodeInstanceHash *previews, bNodeInstanceKey key, int xsize, int ysize, bool create);
|
||||
bNodePreview *BKE_node_preview_copy(struct bNodePreview *preview);
|
||||
void BKE_node_preview_free(struct bNodePreview *preview);
|
||||
void BKE_node_preview_init_tree(struct bNodeTree *ntree,
|
||||
int xsize,
|
||||
int ysize,
|
||||
bool create_previews);
|
||||
void BKE_node_preview_init_tree(struct bNodeTree *ntree, int xsize, int ysize);
|
||||
void BKE_node_preview_free_tree(struct bNodeTree *ntree);
|
||||
void BKE_node_preview_remove_unused(struct bNodeTree *ntree);
|
||||
void BKE_node_preview_clear(struct bNodePreview *preview);
|
||||
void BKE_node_preview_clear_tree(struct bNodeTree *ntree);
|
||||
|
||||
void BKE_node_preview_sync_tree(struct bNodeTree *to_ntree, struct bNodeTree *from_ntree);
|
||||
void BKE_node_preview_merge_tree(struct bNodeTree *to_ntree,
|
||||
struct bNodeTree *from_ntree,
|
||||
bool remove_old);
|
||||
|
||||
/**
|
||||
* Hack warning! this function is only used for shader previews,
|
||||
* and since it gets called multiple times per pixel for Z-transparency we only add the color once.
|
||||
* Preview gets cleared before it starts render though.
|
||||
*/
|
||||
void BKE_node_preview_set_pixel(
|
||||
struct bNodePreview *preview, const float col[4], int x, int y, bool do_manage);
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
@@ -1170,7 +1138,6 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree,
|
||||
#define SH_NODE_SEPRGB 120
|
||||
#define SH_NODE_COMBRGB 121
|
||||
#define SH_NODE_HUE_SAT 122
|
||||
#define NODE_DYNAMIC 123
|
||||
|
||||
#define SH_NODE_OUTPUT_MATERIAL 124
|
||||
#define SH_NODE_OUTPUT_WORLD 125
|
||||
@@ -1739,6 +1706,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
|
||||
#define GEO_NODE_INPUT_MESH_EDGE_NEIGHBORS 1143
|
||||
#define GEO_NODE_INPUT_MESH_ISLAND 1144
|
||||
#define GEO_NODE_INPUT_SCENE_TIME 1145
|
||||
#define GEO_NODE_ACCUMULATE_FIELD 1146
|
||||
|
||||
/** \} */
|
||||
|
||||
|
110
source/blender/blenkernel/BKE_node_tree_update.h
Normal file
110
source/blender/blenkernel/BKE_node_tree_update.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
struct bNode;
|
||||
struct bNodeSocket;
|
||||
struct bNodeTree;
|
||||
struct bNodeLink;
|
||||
struct Main;
|
||||
struct ID;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Tag tree as changed without providing any more information about what has changed exactly.
|
||||
* The update process has to assume that everything may have changed.
|
||||
*
|
||||
* Using one of the methods below to tag the tree after changes is preffered when possible.
|
||||
*/
|
||||
void BKE_ntree_update_tag_all(struct bNodeTree *ntree);
|
||||
|
||||
/**
|
||||
* More specialized tag functions that may result in a more efficient update.
|
||||
*/
|
||||
|
||||
void BKE_ntree_update_tag_node_property(struct bNodeTree *ntree, struct bNode *node);
|
||||
void BKE_ntree_update_tag_node_new(struct bNodeTree *ntree, struct bNode *node);
|
||||
void BKE_ntree_update_tag_node_removed(struct bNodeTree *ntree);
|
||||
void BKE_ntree_update_tag_node_mute(struct bNodeTree *ntree, struct bNode *node);
|
||||
void BKE_ntree_update_tag_node_internal_link(struct bNodeTree *ntree, struct bNode *node);
|
||||
|
||||
void BKE_ntree_update_tag_socket_property(struct bNodeTree *ntree, struct bNodeSocket *socket);
|
||||
void BKE_ntree_update_tag_socket_new(struct bNodeTree *ntree, struct bNodeSocket *socket);
|
||||
void BKE_ntree_update_tag_socket_type(struct bNodeTree *ntree, struct bNodeSocket *socket);
|
||||
void BKE_ntree_update_tag_socket_availability(struct bNodeTree *ntree, struct bNodeSocket *socket);
|
||||
void BKE_ntree_update_tag_socket_removed(struct bNodeTree *ntree);
|
||||
|
||||
void BKE_ntree_update_tag_link_changed(struct bNodeTree *ntree);
|
||||
void BKE_ntree_update_tag_link_removed(struct bNodeTree *ntree);
|
||||
void BKE_ntree_update_tag_link_added(struct bNodeTree *ntree, struct bNodeLink *link);
|
||||
void BKE_ntree_update_tag_link_mute(struct bNodeTree *ntree, struct bNodeLink *link);
|
||||
|
||||
/** Used after file loading when run-time data on the tree has not been initialized yet. */
|
||||
void BKE_ntree_update_tag_missing_runtime_data(struct bNodeTree *ntree);
|
||||
/** Used when the interface sockets/values have changed. */
|
||||
void BKE_ntree_update_tag_interface(struct bNodeTree *ntree);
|
||||
/** Used when an id data block changed that might be used by nodes that need to be updated. */
|
||||
void BKE_ntree_update_tag_id_changed(struct Main *bmain, struct ID *id);
|
||||
|
||||
typedef struct NodeTreeUpdateExtraParams {
|
||||
/**
|
||||
* Data passed into the callbacks.
|
||||
*/
|
||||
void *user_data;
|
||||
|
||||
/**
|
||||
* Called for every tree that has been changed during the update. This can be used to send
|
||||
* notifiers to trigger redraws or depsgraph updates.
|
||||
*/
|
||||
void (*tree_changed_fn)(struct ID *, struct bNodeTree *, void *user_data);
|
||||
|
||||
/**
|
||||
* Called for every tree whose output value may have changed based on the provided update tags.
|
||||
* This can be used to tag the depsgraph if necessary.
|
||||
*/
|
||||
void (*tree_output_changed_fn)(struct ID *, struct bNodeTree *, void *user_data);
|
||||
} NodeTreeUpdateExtraParams;
|
||||
|
||||
/**
|
||||
* Updates #bmain based on changes to node trees.
|
||||
*/
|
||||
void BKE_ntree_update_main(struct Main *bmain, struct NodeTreeUpdateExtraParams *params);
|
||||
|
||||
/**
|
||||
* Same as #BKE_ntree_update_main, but will first only look at the provided tree and only looks
|
||||
* at #bmain when something relevant for other data-blocks changed. This avoids scanning #bmain in
|
||||
* many cases.
|
||||
*
|
||||
* If #bmain is null, only the provided tree is updated. This should only be used in very rare
|
||||
* cases because it may result it incorrectly synced data in DNA.
|
||||
*
|
||||
* If #tree is null, this is the same as calling #BKE_ntree_update_main.
|
||||
*/
|
||||
void BKE_ntree_update_main_tree(struct Main *bmain,
|
||||
struct bNodeTree *ntree,
|
||||
struct NodeTreeUpdateExtraParams *params);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -48,6 +48,7 @@ struct RegionView3D;
|
||||
struct RigidBodyWorld;
|
||||
struct Scene;
|
||||
struct ShaderFxData;
|
||||
struct SubsurfModifierData;
|
||||
struct View3D;
|
||||
struct ViewLayer;
|
||||
|
||||
@@ -512,6 +513,7 @@ bool BKE_object_obdata_texspace_get(struct Object *ob,
|
||||
float **r_loc,
|
||||
float **r_size);
|
||||
|
||||
struct Mesh *BKE_object_get_evaluated_mesh_no_subsurf(const struct Object *object);
|
||||
/** Get evaluated mesh for given object. */
|
||||
struct Mesh *BKE_object_get_evaluated_mesh(const struct Object *object);
|
||||
/**
|
||||
@@ -712,6 +714,15 @@ void BKE_object_modifiers_lib_link_common(void *userData,
|
||||
struct ID **idpoin,
|
||||
int cb_flag);
|
||||
|
||||
/**
|
||||
* Return the last subsurf modifier of an object, this does not check whether modifiers on top of
|
||||
* it are disabled. Return NULL if no such modifier is found.
|
||||
*
|
||||
* This does not check if the modifier is enabled as it is assumed that the caller verified that it
|
||||
* is enabled for its evaluation mode.
|
||||
*/
|
||||
struct SubsurfModifierData *BKE_object_get_last_subsurf_modifier(const struct Object *ob);
|
||||
|
||||
void BKE_object_replace_data_on_shallow_copy(struct Object *ob, struct ID *new_data);
|
||||
|
||||
struct PartEff;
|
||||
|
@@ -41,7 +41,7 @@ void *BKE_pointcloud_add_default(struct Main *bmain, const char *name);
|
||||
struct PointCloud *BKE_pointcloud_new_nomain(const int totpoint);
|
||||
|
||||
struct BoundBox *BKE_pointcloud_boundbox_get(struct Object *ob);
|
||||
void BKE_pointcloud_minmax(const struct PointCloud *pointcloud, float r_min[3], float r_max[3]);
|
||||
bool BKE_pointcloud_minmax(const struct PointCloud *pointcloud, float r_min[3], float r_max[3]);
|
||||
|
||||
void BKE_pointcloud_update_customdata_pointers(struct PointCloud *pointcloud);
|
||||
bool BKE_pointcloud_customdata_required(struct PointCloud *pointcloud,
|
||||
|
@@ -22,6 +22,8 @@
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@@ -465,20 +465,20 @@ void BKE_region_callback_refresh_tag_gizmomap_set(void (*callback)(struct wmGizm
|
||||
*/
|
||||
struct ARegion *BKE_area_find_region_type(const struct ScrArea *area, int type);
|
||||
struct ARegion *BKE_area_find_region_active_win(struct ScrArea *area);
|
||||
struct ARegion *BKE_area_find_region_xy(struct ScrArea *area, const int regiontype, int x, int y);
|
||||
struct ARegion *BKE_area_find_region_xy(struct ScrArea *area,
|
||||
const int regiontype,
|
||||
const int xy[2]) ATTR_NONNULL(3);
|
||||
/**
|
||||
* \note This is only for screen level regions (typically menus/popups).
|
||||
*/
|
||||
struct ARegion *BKE_screen_find_region_xy(struct bScreen *screen,
|
||||
const int regiontype,
|
||||
int x,
|
||||
int y) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
|
||||
const int xy[2]) ATTR_WARN_UNUSED_RESULT
|
||||
ATTR_NONNULL(1, 3);
|
||||
|
||||
struct ARegion *BKE_screen_find_main_region_at_xy(struct bScreen *screen,
|
||||
const int space_type,
|
||||
const int x,
|
||||
const int y);
|
||||
|
||||
const int xy[2]) ATTR_NONNULL(1, 3);
|
||||
/**
|
||||
* \note Ideally we can get the area from the context,
|
||||
* there are a few places however where this isn't practical.
|
||||
@@ -495,9 +495,10 @@ struct ScrArea *BKE_screen_find_big_area(struct bScreen *screen,
|
||||
const short min);
|
||||
struct ScrArea *BKE_screen_area_map_find_area_xy(const struct ScrAreaMap *areamap,
|
||||
const int spacetype,
|
||||
int x,
|
||||
int y);
|
||||
struct ScrArea *BKE_screen_find_area_xy(struct bScreen *screen, const int spacetype, int x, int y);
|
||||
const int xy[2]) ATTR_NONNULL(1, 3);
|
||||
struct ScrArea *BKE_screen_find_area_xy(struct bScreen *screen,
|
||||
const int spacetype,
|
||||
const int xy[2]) ATTR_NONNULL(1, 3);
|
||||
|
||||
void BKE_screen_gizmo_tag_refresh(struct bScreen *screen);
|
||||
|
||||
|
@@ -330,17 +330,6 @@ class BezierSpline final : public Spline {
|
||||
int resolution() const;
|
||||
void set_resolution(const int value);
|
||||
|
||||
/**
|
||||
* \warning Call #reallocate on the spline's attributes after adding all points.
|
||||
*/
|
||||
void add_point(const blender::float3 position,
|
||||
const HandleType handle_type_left,
|
||||
const blender::float3 handle_position_left,
|
||||
const HandleType handle_type_right,
|
||||
const blender::float3 handle_position_right,
|
||||
const float radius,
|
||||
const float tilt);
|
||||
|
||||
void resize(const int size) final;
|
||||
blender::MutableSpan<blender::float3> positions() final;
|
||||
blender::Span<blender::float3> positions() const final;
|
||||
@@ -567,14 +556,6 @@ class NURBSpline final : public Spline {
|
||||
uint8_t order() const;
|
||||
void set_order(const uint8_t value);
|
||||
|
||||
/**
|
||||
* \warning Call #reallocate on the spline's attributes after adding all points.
|
||||
*/
|
||||
void add_point(const blender::float3 position,
|
||||
const float radius,
|
||||
const float tilt,
|
||||
const float weight);
|
||||
|
||||
bool check_valid_size_and_order() const;
|
||||
int knots_size() const;
|
||||
|
||||
@@ -634,11 +615,6 @@ class PolySpline final : public Spline {
|
||||
|
||||
int size() const final;
|
||||
|
||||
/**
|
||||
* \warning Call #reallocate on the spline's attributes after adding all points.
|
||||
*/
|
||||
void add_point(const blender::float3 position, const float radius, const float tilt);
|
||||
|
||||
void resize(const int size) final;
|
||||
blender::MutableSpan<blender::float3> positions() final;
|
||||
blender::Span<blender::float3> positions() const final;
|
||||
@@ -710,7 +686,7 @@ struct CurveEval {
|
||||
|
||||
void translate(const blender::float3 &translation);
|
||||
void transform(const blender::float4x4 &matrix);
|
||||
void bounds_min_max(blender::float3 &min, blender::float3 &max, const bool use_evaluated) const;
|
||||
bool bounds_min_max(blender::float3 &min, blender::float3 &max, const bool use_evaluated) const;
|
||||
|
||||
/**
|
||||
* Return the start indices for each of the curve spline's control points, if they were part
|
||||
|
@@ -188,7 +188,16 @@ typedef struct Subdiv {
|
||||
/* Cached values, are not supposed to be accessed directly. */
|
||||
struct {
|
||||
/* Indexed by base face index, element indicates total number of ptex
|
||||
* faces created for preceding base faces. */
|
||||
* faces created for preceding base faces. This also stores the final
|
||||
* ptex offset (the total number of PTex faces) at the end of the array
|
||||
* so that algorithms can compute the number of ptex faces for a given
|
||||
* face by computing the delta with the offset for the next face without
|
||||
* using a separate data structure, e.g.:
|
||||
*
|
||||
* const int num_face_ptex_faces = face_ptex_offset[i + 1] - face_ptex_offset[i];
|
||||
*
|
||||
* In total this array has a size of `num base faces + 1`.
|
||||
*/
|
||||
int *face_ptex_offset;
|
||||
} cache_;
|
||||
} Subdiv;
|
||||
@@ -257,6 +266,9 @@ void BKE_subdiv_displacement_detach(Subdiv *subdiv);
|
||||
|
||||
/* ============================ TOPOLOGY HELPERS ============================ */
|
||||
|
||||
/* For each element in the array, this stores the total number of ptex faces up to that element,
|
||||
* with the total number of ptex faces being the last element in the array. The array is of length
|
||||
* `base face count + 1`. */
|
||||
int *BKE_subdiv_face_ptex_offset_get(Subdiv *subdiv);
|
||||
|
||||
/* =========================== PTEX FACES AND GRIDS ========================= */
|
||||
|
@@ -31,15 +31,25 @@ extern "C" {
|
||||
|
||||
struct Mesh;
|
||||
struct Subdiv;
|
||||
struct OpenSubdiv_EvaluatorCache;
|
||||
|
||||
typedef enum eSubdivEvaluatorType {
|
||||
SUBDIV_EVALUATOR_TYPE_CPU,
|
||||
SUBDIV_EVALUATOR_TYPE_GLSL_COMPUTE,
|
||||
} eSubdivEvaluatorType;
|
||||
|
||||
/* Returns true if evaluator is ready for use. */
|
||||
bool BKE_subdiv_eval_begin(struct Subdiv *subdiv);
|
||||
bool BKE_subdiv_eval_begin(struct Subdiv *subdiv,
|
||||
eSubdivEvaluatorType evaluator_type,
|
||||
struct OpenSubdiv_EvaluatorCache *evaluator_cache);
|
||||
|
||||
/* coarse_vertex_cos is an optional argument which allows to override coordinates of the coarse
|
||||
* mesh. */
|
||||
bool BKE_subdiv_eval_begin_from_mesh(struct Subdiv *subdiv,
|
||||
const struct Mesh *mesh,
|
||||
const float (*coarse_vertex_cos)[3]);
|
||||
const float (*coarse_vertex_cos)[3],
|
||||
eSubdivEvaluatorType evaluator_type,
|
||||
struct OpenSubdiv_EvaluatorCache *evaluator_cache);
|
||||
bool BKE_subdiv_eval_refine_from_mesh(struct Subdiv *subdiv,
|
||||
const struct Mesh *mesh,
|
||||
const float (*coarse_vertex_cos)[3]);
|
||||
|
@@ -38,7 +38,8 @@ typedef bool (*SubdivForeachTopologyInformationCb)(const struct SubdivForeachCon
|
||||
const int num_vertices,
|
||||
const int num_edges,
|
||||
const int num_loops,
|
||||
const int num_polygons);
|
||||
const int num_polygons,
|
||||
const int *subdiv_polygon_offset);
|
||||
|
||||
typedef void (*SubdivForeachVertexFromCornerCb)(const struct SubdivForeachContext *context,
|
||||
void *tls,
|
||||
|
71
source/blender/blenkernel/BKE_subdiv_modifier.h
Normal file
71
source/blender/blenkernel/BKE_subdiv_modifier.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2021 by Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Mesh;
|
||||
struct Object;
|
||||
struct Scene;
|
||||
struct Subdiv;
|
||||
struct SubdivSettings;
|
||||
struct SubsurfModifierData;
|
||||
|
||||
void BKE_subsurf_modifier_subdiv_settings_init(struct SubdivSettings *settings,
|
||||
const struct SubsurfModifierData *smd,
|
||||
const bool use_render_params);
|
||||
|
||||
/* If skip_check_is_last is true, we assume that the modifier passed is the last enabled modifier
|
||||
* in the stack. */
|
||||
bool BKE_subsurf_modifier_can_do_gpu_subdiv_ex(const struct Scene *scene,
|
||||
const struct Object *ob,
|
||||
const struct SubsurfModifierData *smd,
|
||||
int required_mode,
|
||||
bool skip_check_is_last);
|
||||
|
||||
bool BKE_subsurf_modifier_can_do_gpu_subdiv(const struct Scene *scene,
|
||||
const struct Object *ob,
|
||||
const int required_mode);
|
||||
|
||||
extern void (*BKE_subsurf_modifier_free_gpu_cache_cb)(struct Subdiv *subdiv);
|
||||
|
||||
struct Subdiv *BKE_subsurf_modifier_subdiv_descriptor_ensure(
|
||||
const struct SubsurfModifierData *smd,
|
||||
const struct SubdivSettings *subdiv_settings,
|
||||
const struct Mesh *mesh,
|
||||
const bool for_draw_code);
|
||||
|
||||
struct SubsurfRuntimeData *BKE_subsurf_modifier_ensure_runtime(struct SubsurfModifierData *smd);
|
||||
|
||||
/* Return the #ModifierMode required for the evaluation of the subsurf modifier, which should be
|
||||
* used to check if the modifier is enabled. */
|
||||
int BKE_subsurf_modifier_eval_required_mode(bool is_final_render, bool is_edit_mode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -91,7 +91,7 @@ typedef struct UndoStep {
|
||||
/** When this is true, undo/memfile read code is allowed to re-use old data-blocks for unchanged
|
||||
* IDs, and existing depsgraphes. This has to be forbidden in some cases (like renamed IDs). */
|
||||
bool use_old_bmain_data;
|
||||
/** For use by undo systems that accumulate changes (text editor, painting). */
|
||||
/** For use by undo systems that accumulate changes (mesh-sculpt & image-painting). */
|
||||
bool is_applied;
|
||||
/* Over alloc 'type->struct_size'. */
|
||||
} UndoStep;
|
||||
|
@@ -126,7 +126,7 @@ set(SRC
|
||||
intern/curve_eval.cc
|
||||
intern/curve_to_mesh_convert.cc
|
||||
intern/curveprofile.cc
|
||||
intern/customdata.c
|
||||
intern/customdata.cc
|
||||
intern/customdata_file.c
|
||||
intern/data_transfer.c
|
||||
intern/deform.c
|
||||
@@ -156,7 +156,7 @@ set(SRC
|
||||
intern/gpencil_curve.c
|
||||
intern/gpencil_geom.cc
|
||||
intern/gpencil_modifier.c
|
||||
intern/hair.c
|
||||
intern/hair.cc
|
||||
intern/icons.cc
|
||||
intern/icons_rasterize.c
|
||||
intern/idprop.c
|
||||
@@ -226,6 +226,7 @@ set(SRC
|
||||
intern/multires_versioning.c
|
||||
intern/nla.c
|
||||
intern/node.cc
|
||||
intern/node_tree_update.cc
|
||||
intern/type_conversions.cc
|
||||
intern/object.cc
|
||||
intern/object_deform.c
|
||||
@@ -274,6 +275,7 @@ set(SRC
|
||||
intern/subdiv_eval.c
|
||||
intern/subdiv_foreach.c
|
||||
intern/subdiv_mesh.c
|
||||
intern/subdiv_modifier.c
|
||||
intern/subdiv_stats.c
|
||||
intern/subdiv_topology.c
|
||||
intern/subsurf_ccg.c
|
||||
@@ -420,6 +422,7 @@ set(SRC
|
||||
BKE_multires.h
|
||||
BKE_nla.h
|
||||
BKE_node.h
|
||||
BKE_node_tree_update.h
|
||||
BKE_object.h
|
||||
BKE_object_deform.h
|
||||
BKE_object_facemap.h
|
||||
@@ -451,6 +454,7 @@ set(SRC
|
||||
BKE_subdiv_eval.h
|
||||
BKE_subdiv_foreach.h
|
||||
BKE_subdiv_mesh.h
|
||||
BKE_subdiv_modifier.h
|
||||
BKE_subdiv_topology.h
|
||||
BKE_subsurf.h
|
||||
BKE_text.h
|
||||
|
@@ -2311,145 +2311,3 @@ static void mesh_init_origspace(Mesh *mesh)
|
||||
|
||||
BKE_mesh_tessface_clear(mesh);
|
||||
}
|
||||
|
||||
/* derivedmesh info printing function,
|
||||
* to help track down differences DM output */
|
||||
|
||||
#ifndef NDEBUG
|
||||
# include "BLI_dynstr.h"
|
||||
|
||||
static void dm_debug_info_layers(DynStr *dynstr,
|
||||
DerivedMesh *dm,
|
||||
CustomData *cd,
|
||||
void *(*getElemDataArray)(DerivedMesh *, int))
|
||||
{
|
||||
int type;
|
||||
|
||||
for (type = 0; type < CD_NUMTYPES; type++) {
|
||||
if (CustomData_has_layer(cd, type)) {
|
||||
/* NOTE: doesn't account for multiple layers. */
|
||||
const char *name = CustomData_layertype_name(type);
|
||||
const int size = CustomData_sizeof(type);
|
||||
const void *pt = getElemDataArray(dm, type);
|
||||
const int pt_size = pt ? (int)(MEM_allocN_len(pt) / size) : 0;
|
||||
const char *structname;
|
||||
int structnum;
|
||||
CustomData_file_write_info(type, &structname, &structnum);
|
||||
BLI_dynstr_appendf(
|
||||
dynstr,
|
||||
" dict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n",
|
||||
name,
|
||||
structname,
|
||||
type,
|
||||
(const void *)pt,
|
||||
size,
|
||||
pt_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *DM_debug_info(DerivedMesh *dm)
|
||||
{
|
||||
DynStr *dynstr = BLI_dynstr_new();
|
||||
char *ret;
|
||||
const char *tstr;
|
||||
|
||||
BLI_dynstr_append(dynstr, "{\n");
|
||||
BLI_dynstr_appendf(dynstr, " 'ptr': '%p',\n", (void *)dm);
|
||||
switch (dm->type) {
|
||||
case DM_TYPE_CDDM:
|
||||
tstr = "DM_TYPE_CDDM";
|
||||
break;
|
||||
case DM_TYPE_CCGDM:
|
||||
tstr = "DM_TYPE_CCGDM";
|
||||
break;
|
||||
default:
|
||||
tstr = "UNKNOWN";
|
||||
break;
|
||||
}
|
||||
BLI_dynstr_appendf(dynstr, " 'type': '%s',\n", tstr);
|
||||
BLI_dynstr_appendf(dynstr, " 'numVertData': %d,\n", dm->numVertData);
|
||||
BLI_dynstr_appendf(dynstr, " 'numEdgeData': %d,\n", dm->numEdgeData);
|
||||
BLI_dynstr_appendf(dynstr, " 'numTessFaceData': %d,\n", dm->numTessFaceData);
|
||||
BLI_dynstr_appendf(dynstr, " 'numPolyData': %d,\n", dm->numPolyData);
|
||||
BLI_dynstr_appendf(dynstr, " 'deformedOnly': %d,\n", dm->deformedOnly);
|
||||
|
||||
BLI_dynstr_append(dynstr, " 'vertexLayers': (\n");
|
||||
dm_debug_info_layers(dynstr, dm, &dm->vertData, dm->getVertDataArray);
|
||||
BLI_dynstr_append(dynstr, " ),\n");
|
||||
|
||||
BLI_dynstr_append(dynstr, " 'edgeLayers': (\n");
|
||||
dm_debug_info_layers(dynstr, dm, &dm->edgeData, dm->getEdgeDataArray);
|
||||
BLI_dynstr_append(dynstr, " ),\n");
|
||||
|
||||
BLI_dynstr_append(dynstr, " 'loopLayers': (\n");
|
||||
dm_debug_info_layers(dynstr, dm, &dm->loopData, dm->getLoopDataArray);
|
||||
BLI_dynstr_append(dynstr, " ),\n");
|
||||
|
||||
BLI_dynstr_append(dynstr, " 'polyLayers': (\n");
|
||||
dm_debug_info_layers(dynstr, dm, &dm->polyData, dm->getPolyDataArray);
|
||||
BLI_dynstr_append(dynstr, " ),\n");
|
||||
|
||||
BLI_dynstr_append(dynstr, " 'tessFaceLayers': (\n");
|
||||
dm_debug_info_layers(dynstr, dm, &dm->faceData, dm->getTessFaceDataArray);
|
||||
BLI_dynstr_append(dynstr, " ),\n");
|
||||
|
||||
BLI_dynstr_append(dynstr, "}\n");
|
||||
|
||||
ret = BLI_dynstr_get_cstring(dynstr);
|
||||
BLI_dynstr_free(dynstr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DM_debug_print(DerivedMesh *dm)
|
||||
{
|
||||
char *str = DM_debug_info(dm);
|
||||
puts(str);
|
||||
fflush(stdout);
|
||||
MEM_freeN(str);
|
||||
}
|
||||
|
||||
bool DM_is_valid(DerivedMesh *dm)
|
||||
{
|
||||
const bool do_verbose = true;
|
||||
const bool do_fixes = false;
|
||||
|
||||
bool is_valid = true;
|
||||
bool changed = true;
|
||||
|
||||
is_valid &= BKE_mesh_validate_all_customdata(
|
||||
dm->getVertDataLayout(dm),
|
||||
dm->getNumVerts(dm),
|
||||
dm->getEdgeDataLayout(dm),
|
||||
dm->getNumEdges(dm),
|
||||
dm->getLoopDataLayout(dm),
|
||||
dm->getNumLoops(dm),
|
||||
dm->getPolyDataLayout(dm),
|
||||
dm->getNumPolys(dm),
|
||||
false, /* setting mask here isn't useful, gives false positives */
|
||||
do_verbose,
|
||||
do_fixes,
|
||||
&changed);
|
||||
|
||||
is_valid &= BKE_mesh_validate_arrays(nullptr,
|
||||
dm->getVertArray(dm),
|
||||
dm->getNumVerts(dm),
|
||||
dm->getEdgeArray(dm),
|
||||
dm->getNumEdges(dm),
|
||||
dm->getTessFaceArray(dm),
|
||||
dm->getNumTessFaces(dm),
|
||||
dm->getLoopArray(dm),
|
||||
dm->getNumLoops(dm),
|
||||
dm->getPolyArray(dm),
|
||||
dm->getNumPolys(dm),
|
||||
(MDeformVert *)dm->getVertDataArray(dm, CD_MDEFORMVERT),
|
||||
do_verbose,
|
||||
do_fixes,
|
||||
&changed);
|
||||
|
||||
BLI_assert(changed == false);
|
||||
|
||||
return is_valid;
|
||||
}
|
||||
|
||||
#endif /* NDEBUG */
|
||||
|
@@ -705,7 +705,12 @@ bool BKE_pose_channels_is_valid(const bPose *pose)
|
||||
|
||||
#endif
|
||||
|
||||
bPoseChannel *BKE_pose_channel_active(Object *ob)
|
||||
bool BKE_pose_is_layer_visible(const bArmature *arm, const bPoseChannel *pchan)
|
||||
{
|
||||
return (pchan->bone->layer & arm->layer);
|
||||
}
|
||||
|
||||
bPoseChannel *BKE_pose_channel_active(Object *ob, const bool check_arm_layer)
|
||||
{
|
||||
bArmature *arm = (ob) ? ob->data : NULL;
|
||||
bPoseChannel *pchan;
|
||||
@@ -716,14 +721,21 @@ bPoseChannel *BKE_pose_channel_active(Object *ob)
|
||||
|
||||
/* find active */
|
||||
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
if ((pchan->bone) && (pchan->bone == arm->act_bone) && (pchan->bone->layer & arm->layer)) {
|
||||
return pchan;
|
||||
if ((pchan->bone) && (pchan->bone == arm->act_bone)) {
|
||||
if (!check_arm_layer || BKE_pose_is_layer_visible(arm, pchan)) {
|
||||
return pchan;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bPoseChannel *BKE_pose_channel_active_if_layer_visible(struct Object *ob)
|
||||
{
|
||||
return BKE_pose_channel_active(ob, true);
|
||||
}
|
||||
|
||||
bPoseChannel *BKE_pose_channel_active_or_first_selected(struct Object *ob)
|
||||
{
|
||||
bArmature *arm = (ob) ? ob->data : NULL;
|
||||
@@ -732,7 +744,7 @@ bPoseChannel *BKE_pose_channel_active_or_first_selected(struct Object *ob)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bPoseChannel *pchan = BKE_pose_channel_active(ob);
|
||||
bPoseChannel *pchan = BKE_pose_channel_active_if_layer_visible(ob);
|
||||
if (pchan && (pchan->bone->flag & BONE_SELECTED) && PBONE_VISIBLE(arm, pchan->bone)) {
|
||||
return pchan;
|
||||
}
|
||||
|
@@ -676,41 +676,6 @@ void BKE_animdata_transfer_by_basepath(Main *bmain, ID *srcID, ID *dstID, ListBa
|
||||
}
|
||||
}
|
||||
|
||||
char *BKE_animdata_driver_path_hack(bContext *C,
|
||||
PointerRNA *ptr,
|
||||
PropertyRNA *prop,
|
||||
char *base_path)
|
||||
{
|
||||
ID *id = ptr->owner_id;
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
|
||||
/* get standard path which may be extended */
|
||||
char *basepath = base_path ? base_path : RNA_path_from_ID_to_property(ptr, prop);
|
||||
char *path = basepath; /* in case no remapping is needed */
|
||||
|
||||
/* Remapping will only be performed in the Properties Editor, as only this
|
||||
* restricts the subspace of options to the 'active' data (a manageable state)
|
||||
*/
|
||||
/* TODO: watch out for pinned context? */
|
||||
if ((area) && (area->spacetype == SPACE_PROPERTIES)) {
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
|
||||
if (ob && id) {
|
||||
/* TODO: after material textures were removed, this function serves
|
||||
* no purpose anymore, but could be used again so was not removed. */
|
||||
|
||||
/* fix RNA pointer, as we've now changed the ID root by changing the paths */
|
||||
if (basepath != path) {
|
||||
/* rebase provided pointer so that it starts from object... */
|
||||
RNA_pointer_create(&ob->id, ptr->type, ptr->data, ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* the path should now have been corrected for use */
|
||||
return path;
|
||||
}
|
||||
|
||||
/* Path Validation -------------------------------------------- */
|
||||
|
||||
/* Check if a given RNA Path is valid, by tracing it from the given ID,
|
||||
|
@@ -24,7 +24,7 @@
|
||||
#include "BKE_asset_catalog.hh"
|
||||
#include "BKE_asset_library.h"
|
||||
|
||||
#include "BLI_fileops.h"
|
||||
#include "BLI_fileops.hh"
|
||||
#include "BLI_path_util.h"
|
||||
|
||||
/* For S_ISREG() and S_ISDIR() on Windows. */
|
||||
@@ -32,6 +32,10 @@
|
||||
# include "BLI_winstuff.h"
|
||||
#endif
|
||||
|
||||
#include "CLG_log.h"
|
||||
|
||||
static CLG_LogRef LOG = {"bke.asset_service"};
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
const CatalogFilePath AssetCatalogService::DEFAULT_CATALOG_FILENAME = "blender_assets.cats.txt";
|
||||
@@ -311,6 +315,7 @@ void AssetCatalogService::load_from_disk(const CatalogFilePath &file_or_director
|
||||
BLI_stat_t status;
|
||||
if (BLI_stat(file_or_directory_path.data(), &status) == -1) {
|
||||
/* TODO(@sybren): throw an appropriate exception. */
|
||||
CLOG_WARN(&LOG, "path not found: %s", file_or_directory_path.data());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -337,6 +342,7 @@ void AssetCatalogService::load_directory_recursive(const CatalogFilePath &direct
|
||||
|
||||
if (!BLI_exists(file_path.data())) {
|
||||
/* No file to be loaded is perfectly fine. */
|
||||
CLOG_INFO(&LOG, 2, "path not found: %s", file_path.data());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -824,8 +830,12 @@ void AssetCatalogDefinitionFile::parse_catalog_file(
|
||||
const CatalogFilePath &catalog_definition_file_path,
|
||||
AssetCatalogParsedFn catalog_loaded_callback)
|
||||
{
|
||||
std::fstream infile(catalog_definition_file_path);
|
||||
fstream infile(catalog_definition_file_path, std::ios::in);
|
||||
|
||||
if (!infile.is_open()) {
|
||||
CLOG_ERROR(&LOG, "%s: unable to open file", catalog_definition_file_path.c_str());
|
||||
return;
|
||||
}
|
||||
bool seen_version_number = false;
|
||||
std::string line;
|
||||
while (std::getline(infile, line)) {
|
||||
@@ -956,7 +966,7 @@ bool AssetCatalogDefinitionFile::write_to_disk_unsafe(const CatalogFilePath &des
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ofstream output(dest_file_path);
|
||||
fstream output(dest_file_path, std::ios::out);
|
||||
|
||||
/* TODO(@sybren): remember the line ending style that was originally read, then use that to write
|
||||
* the file again. */
|
||||
|
@@ -27,6 +27,8 @@
|
||||
#include "DNA_asset_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
|
||||
#include "CLG_log.h"
|
||||
|
||||
#include "testing/testing.h"
|
||||
|
||||
namespace blender::bke::tests {
|
||||
@@ -93,6 +95,18 @@ class AssetCatalogTest : public testing::Test {
|
||||
CatalogFilePath asset_library_root_;
|
||||
CatalogFilePath temp_library_path_;
|
||||
|
||||
static void SetUpTestSuite()
|
||||
{
|
||||
testing::Test::SetUpTestSuite();
|
||||
CLG_init();
|
||||
}
|
||||
|
||||
static void TearDownTestSuite()
|
||||
{
|
||||
CLG_exit();
|
||||
testing::Test::TearDownTestSuite();
|
||||
}
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
const std::string test_files_dir = blender::tests::flags_test_asset_dir();
|
||||
@@ -549,6 +563,30 @@ TEST_F(AssetCatalogTest, write_single_file)
|
||||
/* TODO(@sybren): test ordering of catalogs in the file. */
|
||||
}
|
||||
|
||||
TEST_F(AssetCatalogTest, read_write_unicode_filepath)
|
||||
{
|
||||
TestableAssetCatalogService service(asset_library_root_);
|
||||
const CatalogFilePath load_from_path = asset_library_root_ + "/новый/" +
|
||||
AssetCatalogService::DEFAULT_CATALOG_FILENAME;
|
||||
service.load_from_disk(load_from_path);
|
||||
|
||||
const CatalogFilePath save_to_path = use_temp_path() + "новый.cats.txt";
|
||||
AssetCatalogDefinitionFile *cdf = service.get_catalog_definition_file();
|
||||
ASSERT_NE(nullptr, cdf) << "unable to load " << load_from_path;
|
||||
EXPECT_TRUE(cdf->write_to_disk(save_to_path));
|
||||
|
||||
AssetCatalogService loaded_service(save_to_path);
|
||||
loaded_service.load_from_disk();
|
||||
|
||||
/* Test that the file was loaded correctly. */
|
||||
const bUUID materials_uuid("a2151dff-dead-4f29-b6bc-b2c7d6cccdb4");
|
||||
const AssetCatalog *cat = loaded_service.find_catalog(materials_uuid);
|
||||
ASSERT_NE(nullptr, cat);
|
||||
EXPECT_EQ(materials_uuid, cat->catalog_id);
|
||||
EXPECT_EQ(AssetCatalogPath("Материалы"), cat->path);
|
||||
EXPECT_EQ("Russian Materials", cat->simple_name);
|
||||
}
|
||||
|
||||
TEST_F(AssetCatalogTest, no_writing_empty_files)
|
||||
{
|
||||
const CatalogFilePath temp_lib_root = create_temp_path();
|
||||
|
@@ -440,6 +440,16 @@ static bool object_in_any_collection(Main *bmain, Object *ob)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool collection_instantiated_by_any_object(Main *bmain, Collection *collection)
|
||||
{
|
||||
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
|
||||
if (ob->type == OB_EMPTY && ob->instance_collection == collection) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static ID *loose_data_instantiate_process_check(LooseDataInstantiateContext *instantiate_context,
|
||||
BlendfileLinkAppendContextItem *item)
|
||||
{
|
||||
@@ -633,12 +643,19 @@ static void loose_data_instantiate_collection_process(
|
||||
* children.
|
||||
*/
|
||||
Collection *collection = (Collection *)id;
|
||||
/* The collection could be linked/appended together with an Empty object instantiating it,
|
||||
* better not instantiate the collection in the viewlayer in that case.
|
||||
*
|
||||
* Can easily happen when copy/pasting such instantiating empty, see T93839. */
|
||||
const bool collection_is_instantiated = collection_instantiated_by_any_object(bmain,
|
||||
collection);
|
||||
/* Always consider adding collections directly selected by the user. */
|
||||
bool do_add_collection = (item->tag & LINK_APPEND_TAG_INDIRECT) == 0;
|
||||
bool do_add_collection = (item->tag & LINK_APPEND_TAG_INDIRECT) == 0 &&
|
||||
!collection_is_instantiated;
|
||||
/* In linking case, do not enforce instantiating non-directly linked collections/objects.
|
||||
* This avoids cluttering the ViewLayers, user can instantiate themselves specific collections
|
||||
* or objects easily from the Outliner if needed. */
|
||||
if (!do_add_collection && do_append) {
|
||||
if (!do_add_collection && do_append && !collection_is_instantiated) {
|
||||
LISTBASE_FOREACH (CollectionObject *, coll_ob, &collection->gobject) {
|
||||
Object *ob = coll_ob->ob;
|
||||
if (!object_in_any_scene(bmain, ob)) {
|
||||
@@ -726,6 +743,8 @@ static void loose_data_instantiate_object_process(LooseDataInstantiateContext *i
|
||||
* if you want it do it at the editor level. */
|
||||
const bool object_set_active = false;
|
||||
|
||||
const bool is_linking = (lapp_context->params->flag & FILE_LINK) != 0;
|
||||
|
||||
/* NOTE: For objects we only view_layer-instantiate duplicated objects that are not yet used
|
||||
* anywhere. */
|
||||
LinkNode *itemlink;
|
||||
@@ -736,6 +755,17 @@ static void loose_data_instantiate_object_process(LooseDataInstantiateContext *i
|
||||
continue;
|
||||
}
|
||||
|
||||
/* In linking case, never instantiate stray objects that are not directly linked.
|
||||
*
|
||||
* While this is not ideal (in theory no object should remain un-owned), in case of indirectly
|
||||
* linked objects, the other solution would be to add them to a local collection, which would
|
||||
* make them directly linked. Think for now keeping them indirectly linked is more important.
|
||||
* Ref. T93757.
|
||||
*/
|
||||
if (is_linking && (item->tag & LINK_APPEND_TAG_INDIRECT) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Object *ob = (Object *)id;
|
||||
|
||||
if (object_in_any_collection(bmain, ob)) {
|
||||
|
@@ -127,7 +127,7 @@ bool bvhcache_has_tree(const BVHCache *bvh_cache, const BVHTree *tree)
|
||||
|
||||
BVHCache *bvhcache_init()
|
||||
{
|
||||
BVHCache *cache = (BVHCache *)MEM_callocN(sizeof(BVHCache), __func__);
|
||||
BVHCache *cache = MEM_cnew<BVHCache>(__func__);
|
||||
BLI_mutex_init(&cache->mutex);
|
||||
return cache;
|
||||
}
|
||||
|
@@ -186,7 +186,7 @@ static ID *collection_owner_get(Main *bmain, ID *id)
|
||||
Collection *master_collection = (Collection *)id;
|
||||
BLI_assert((master_collection->flag & COLLECTION_IS_MASTER) != 0);
|
||||
|
||||
for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
if (scene->master_collection == master_collection) {
|
||||
return &scene->id;
|
||||
}
|
||||
@@ -1205,9 +1205,7 @@ static void collection_object_remove_nulls(Collection *collection)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
for (CollectionObject *cob = collection->gobject.first, *cob_next = NULL; cob; cob = cob_next) {
|
||||
cob_next = cob->next;
|
||||
|
||||
LISTBASE_FOREACH_MUTABLE (CollectionObject *, cob, &collection->gobject) {
|
||||
if (cob->ob == NULL) {
|
||||
BLI_freelinkN(&collection->gobject, cob);
|
||||
changed = true;
|
||||
@@ -1221,22 +1219,61 @@ static void collection_object_remove_nulls(Collection *collection)
|
||||
|
||||
void BKE_collections_object_remove_nulls(Main *bmain)
|
||||
{
|
||||
for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
collection_object_remove_nulls(scene->master_collection);
|
||||
}
|
||||
|
||||
for (Collection *collection = bmain->collections.first; collection;
|
||||
collection = collection->id.next) {
|
||||
LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
|
||||
collection_object_remove_nulls(collection);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove all duplicate objects from collections.
|
||||
* This is used for library remapping, happens when remapping an object to another one already
|
||||
* present in the collection. Otherwise this should never happen.
|
||||
*/
|
||||
static void collection_object_remove_duplicates(Collection *collection)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
LISTBASE_FOREACH_MUTABLE (CollectionObject *, cob, &collection->gobject) {
|
||||
if (cob->ob->runtime.collection_management) {
|
||||
BLI_freelinkN(&collection->gobject, cob);
|
||||
changed = true;
|
||||
continue;
|
||||
}
|
||||
cob->ob->runtime.collection_management = true;
|
||||
}
|
||||
|
||||
/* Cleanup. */
|
||||
LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
|
||||
cob->ob->runtime.collection_management = false;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
BKE_collection_object_cache_free(collection);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_collections_object_remove_duplicates(struct Main *bmain)
|
||||
{
|
||||
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
|
||||
ob->runtime.collection_management = false;
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
collection_object_remove_duplicates(scene->master_collection);
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
|
||||
collection_object_remove_duplicates(collection);
|
||||
}
|
||||
}
|
||||
|
||||
static void collection_null_children_remove(Collection *collection)
|
||||
{
|
||||
for (CollectionChild *child = collection->children.first, *child_next = NULL; child;
|
||||
child = child_next) {
|
||||
child_next = child->next;
|
||||
|
||||
LISTBASE_FOREACH_MUTABLE (CollectionChild *, child, &collection->children) {
|
||||
if (child->collection == NULL) {
|
||||
BLI_freelinkN(&collection->children, child);
|
||||
}
|
||||
@@ -1245,9 +1282,7 @@ static void collection_null_children_remove(Collection *collection)
|
||||
|
||||
static void collection_missing_parents_remove(Collection *collection)
|
||||
{
|
||||
for (CollectionParent *parent = collection->parents.first, *parent_next; parent != NULL;
|
||||
parent = parent_next) {
|
||||
parent_next = parent->next;
|
||||
LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &collection->parents) {
|
||||
if ((parent->collection == NULL) || !collection_find_child(parent->collection, collection)) {
|
||||
BLI_freelinkN(&collection->parents, parent);
|
||||
}
|
||||
@@ -1267,28 +1302,23 @@ void BKE_collections_child_remove_nulls(Main *bmain,
|
||||
* otherwise we can miss some cases...
|
||||
* Also, master collections are not in bmain, so we also need to loop over scenes.
|
||||
*/
|
||||
for (child_collection = bmain->collections.first; child_collection != NULL;
|
||||
child_collection = child_collection->id.next) {
|
||||
collection_null_children_remove(child_collection);
|
||||
LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
|
||||
collection_null_children_remove(collection);
|
||||
}
|
||||
for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
collection_null_children_remove(scene->master_collection);
|
||||
}
|
||||
}
|
||||
|
||||
for (child_collection = bmain->collections.first; child_collection != NULL;
|
||||
child_collection = child_collection->id.next) {
|
||||
collection_missing_parents_remove(child_collection);
|
||||
LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
|
||||
collection_missing_parents_remove(collection);
|
||||
}
|
||||
for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
collection_missing_parents_remove(scene->master_collection);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (CollectionParent *parent = child_collection->parents.first, *parent_next; parent;
|
||||
parent = parent_next) {
|
||||
parent_next = parent->next;
|
||||
|
||||
LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &child_collection->parents) {
|
||||
collection_null_children_remove(parent->collection);
|
||||
|
||||
if (!collection_find_child(parent->collection, child_collection)) {
|
||||
@@ -1586,9 +1616,9 @@ static void collection_parents_rebuild_recursive(Collection *collection)
|
||||
BKE_collection_parent_relations_rebuild(collection);
|
||||
collection->tag &= ~COLLECTION_TAG_RELATION_REBUILD;
|
||||
|
||||
for (CollectionChild *child = collection->children.first; child != NULL; child = child->next) {
|
||||
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
|
||||
/* See comment above in `BKE_collection_parent_relations_rebuild`. */
|
||||
if ((collection->id.tag & (LIB_TAG_NO_MAIN | LIB_TAG_COPIED_ON_WRITE)) != 0) {
|
||||
if ((child->collection->id.tag & (LIB_TAG_NO_MAIN | LIB_TAG_COPIED_ON_WRITE)) != 0) {
|
||||
continue;
|
||||
}
|
||||
collection_parents_rebuild_recursive(child->collection);
|
||||
@@ -1598,8 +1628,7 @@ static void collection_parents_rebuild_recursive(Collection *collection)
|
||||
void BKE_main_collections_parent_relations_rebuild(Main *bmain)
|
||||
{
|
||||
/* Only collections not in bmain (master ones in scenes) have no parent... */
|
||||
for (Collection *collection = bmain->collections.first; collection != NULL;
|
||||
collection = collection->id.next) {
|
||||
LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
|
||||
BLI_freelistN(&collection->parents);
|
||||
|
||||
collection->tag |= COLLECTION_TAG_RELATION_REBUILD;
|
||||
@@ -1607,7 +1636,7 @@ void BKE_main_collections_parent_relations_rebuild(Main *bmain)
|
||||
|
||||
/* Scene's master collections will be 'root' parent of most of our collections, so start with
|
||||
* them. */
|
||||
for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
/* This function can be called from readfile.c, when this pointer is not guaranteed to be NULL.
|
||||
*/
|
||||
if (scene->master_collection != NULL) {
|
||||
@@ -1619,8 +1648,7 @@ void BKE_main_collections_parent_relations_rebuild(Main *bmain)
|
||||
|
||||
/* We may have parent chains outside of scene's master_collection context? At least, readfile's
|
||||
* lib_link_collection_data() seems to assume that, so do the same here. */
|
||||
for (Collection *collection = bmain->collections.first; collection != NULL;
|
||||
collection = collection->id.next) {
|
||||
LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
|
||||
if (collection->tag & COLLECTION_TAG_RELATION_REBUILD) {
|
||||
/* NOTE: we do not have easy access to 'which collections is root' info in that case, which
|
||||
* means test for cycles in collection relationships may fail here. I don't think that is an
|
||||
|
@@ -278,13 +278,13 @@ void BKE_cryptomatte_matte_id_to_entries(NodeCryptomatte *node_storage, const ch
|
||||
token = token.substr(first, (last - first + 1));
|
||||
if (*token.begin() == '<' && *(--token.end()) == '>') {
|
||||
float encoded_hash = atof(token.substr(1, token.length() - 2).c_str());
|
||||
entry = (CryptomatteEntry *)MEM_callocN(sizeof(CryptomatteEntry), __func__);
|
||||
entry = MEM_cnew<CryptomatteEntry>(__func__);
|
||||
entry->encoded_hash = encoded_hash;
|
||||
}
|
||||
else {
|
||||
const char *name = token.c_str();
|
||||
int name_len = token.length();
|
||||
entry = (CryptomatteEntry *)MEM_callocN(sizeof(CryptomatteEntry), __func__);
|
||||
entry = MEM_cnew<CryptomatteEntry>(__func__);
|
||||
STRNCPY(entry->name, name);
|
||||
uint32_t hash = BKE_cryptomatte_hash(name, name_len);
|
||||
entry->encoded_hash = BKE_cryptomatte_hash_to_float(hash);
|
||||
|
@@ -2694,7 +2694,7 @@ void BKE_curve_bevelList_make(Object *ob, const ListBase *nurbs, const bool for_
|
||||
|
||||
if (nu->type == CU_POLY) {
|
||||
len = nu->pntsu;
|
||||
BevList *bl = (BevList *)MEM_callocN(sizeof(BevList), __func__);
|
||||
BevList *bl = MEM_cnew<BevList>(__func__);
|
||||
bl->bevpoints = (BevPoint *)MEM_calloc_arrayN(len, sizeof(BevPoint), __func__);
|
||||
if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) {
|
||||
bl->seglen = (float *)MEM_malloc_arrayN(segcount, sizeof(float), __func__);
|
||||
@@ -2744,7 +2744,7 @@ void BKE_curve_bevelList_make(Object *ob, const ListBase *nurbs, const bool for_
|
||||
/* in case last point is not cyclic */
|
||||
len = segcount * resolu + 1;
|
||||
|
||||
BevList *bl = (BevList *)MEM_callocN(sizeof(BevList), __func__);
|
||||
BevList *bl = MEM_cnew<BevList>(__func__);
|
||||
bl->bevpoints = (BevPoint *)MEM_calloc_arrayN(len, sizeof(BevPoint), __func__);
|
||||
if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) {
|
||||
bl->seglen = (float *)MEM_malloc_arrayN(segcount, sizeof(float), __func__);
|
||||
@@ -2880,7 +2880,7 @@ void BKE_curve_bevelList_make(Object *ob, const ListBase *nurbs, const bool for_
|
||||
if (nu->pntsv == 1) {
|
||||
len = (resolu * segcount);
|
||||
|
||||
BevList *bl = (BevList *)MEM_callocN(sizeof(BevList), __func__);
|
||||
BevList *bl = MEM_cnew<BevList>(__func__);
|
||||
bl->bevpoints = (BevPoint *)MEM_calloc_arrayN(len, sizeof(BevPoint), __func__);
|
||||
if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) {
|
||||
bl->seglen = (float *)MEM_malloc_arrayN(segcount, sizeof(float), __func__);
|
||||
|
@@ -100,11 +100,17 @@ void CurveEval::transform(const float4x4 &matrix)
|
||||
}
|
||||
}
|
||||
|
||||
void CurveEval::bounds_min_max(float3 &min, float3 &max, const bool use_evaluated) const
|
||||
bool CurveEval::bounds_min_max(float3 &min, float3 &max, const bool use_evaluated) const
|
||||
{
|
||||
bool have_minmax = false;
|
||||
for (const SplinePtr &spline : this->splines()) {
|
||||
spline->bounds_min_max(min, max, use_evaluated);
|
||||
if (spline->size()) {
|
||||
spline->bounds_min_max(min, max, use_evaluated);
|
||||
have_minmax = true;
|
||||
}
|
||||
}
|
||||
|
||||
return have_minmax;
|
||||
}
|
||||
|
||||
float CurveEval::total_length() const
|
||||
|
@@ -401,10 +401,8 @@ struct ResultAttributes {
|
||||
};
|
||||
static ResultAttributes create_result_attributes(const CurveEval &curve,
|
||||
const CurveEval &profile,
|
||||
Mesh &mesh)
|
||||
MeshComponent &mesh_component)
|
||||
{
|
||||
MeshComponent mesh_component;
|
||||
mesh_component.replace(&mesh, GeometryOwnershipType::Editable);
|
||||
Set<AttributeIDRef> curve_attributes;
|
||||
|
||||
/* In order to prefer attributes on the main curve input when there are name collisions, first
|
||||
@@ -708,7 +706,11 @@ Mesh *curve_to_mesh_sweep(const CurveEval &curve, const CurveEval &profile, cons
|
||||
mesh->smoothresh = DEG2RADF(180.0f);
|
||||
BKE_mesh_normals_tag_dirty(mesh);
|
||||
|
||||
ResultAttributes attributes = create_result_attributes(curve, profile, *mesh);
|
||||
/* Create the mesh component for retrieving attributes at this scope, since output attributes
|
||||
* can keep a reference to the component for updating after retrieving write access. */
|
||||
MeshComponent mesh_component;
|
||||
mesh_component.replace(mesh, GeometryOwnershipType::Editable);
|
||||
ResultAttributes attributes = create_result_attributes(curve, profile, mesh_component);
|
||||
|
||||
threading::parallel_for(curves.index_range(), 128, [&](IndexRange curves_range) {
|
||||
for (const int i_spline : curves_range) {
|
||||
@@ -760,7 +762,10 @@ static CurveEval get_curve_single_vert()
|
||||
{
|
||||
CurveEval curve;
|
||||
std::unique_ptr<PolySpline> spline = std::make_unique<PolySpline>();
|
||||
spline->add_point(float3(0), 0, 0.0f);
|
||||
spline->resize(1.0f);
|
||||
spline->positions().fill(float3(0));
|
||||
spline->radii().fill(1.0f);
|
||||
spline->tilts().fill(0.0f);
|
||||
curve.add_spline(std::move(spline));
|
||||
|
||||
return curve;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user