Fix Cycles MetalRT access of macOS 11 features when unavailable #104976
|
@ -123,7 +123,7 @@ void fill_selection_true(GMutableSpan selection)
|
|||
}
|
||||
}
|
||||
|
||||
static bool contains(const VArray<bool> &varray, const bool value)
|
||||
static bool contains(const VArray<bool> &varray, const IndexRange range_to_check, const bool value)
|
||||
{
|
||||
const CommonVArrayInfo info = varray.common_info();
|
||||
if (info.type == CommonVArrayInfo::Type::Single) {
|
||||
|
@ -132,7 +132,7 @@ static bool contains(const VArray<bool> &varray, const bool value)
|
|||
if (info.type == CommonVArrayInfo::Type::Span) {
|
||||
const Span<bool> span(static_cast<const bool *>(info.data), varray.size());
|
||||
return threading::parallel_reduce(
|
||||
span.index_range(),
|
||||
range_to_check,
|
||||
4096,
|
||||
false,
|
||||
[&](const IndexRange range, const bool init) {
|
||||
|
@ -141,7 +141,7 @@ static bool contains(const VArray<bool> &varray, const bool value)
|
|||
[&](const bool a, const bool b) { return a || b; });
|
||||
}
|
||||
return threading::parallel_reduce(
|
||||
varray.index_range(),
|
||||
range_to_check,
|
||||
2048,
|
||||
false,
|
||||
[&](const IndexRange range, const bool init) {
|
||||
|
@ -159,10 +159,15 @@ static bool contains(const VArray<bool> &varray, const bool value)
|
|||
[&](const bool a, const bool b) { return a || b; });
|
||||
}
|
||||
|
||||
bool has_anything_selected(const VArray<bool> &varray, const IndexRange range_to_check)
|
||||
{
|
||||
return contains(varray, range_to_check, true);
|
||||
}
|
||||
|
||||
bool has_anything_selected(const bke::CurvesGeometry &curves)
|
||||
{
|
||||
const VArray<bool> selection = curves.attributes().lookup<bool>(".selection");
|
||||
return !selection || contains(selection, true);
|
||||
return !selection || contains(selection, curves.curves_range(), true);
|
||||
}
|
||||
|
||||
bool has_anything_selected(const GSpan selection)
|
||||
|
|
|
@ -93,6 +93,7 @@ bool has_anything_selected(const bke::CurvesGeometry &curves);
|
|||
* Return true if any element in the span is selected, on either domain with either type.
|
||||
*/
|
||||
bool has_anything_selected(GSpan selection);
|
||||
bool has_anything_selected(const VArray<bool> &varray, IndexRange range_to_check);
|
||||
|
||||
/**
|
||||
* Find curves that have any point selected (a selection factor greater than zero),
|
||||
|
|
|
@ -164,7 +164,7 @@ DEF_ICON(NLA)
|
|||
DEF_ICON(PREFERENCES)
|
||||
DEF_ICON(TIME)
|
||||
DEF_ICON(NODETREE)
|
||||
DEF_ICON(GEOMETRY_NODES)
|
||||
DEF_ICON_MODIFIER(GEOMETRY_NODES)
|
||||
DEF_ICON(CONSOLE)
|
||||
DEF_ICON_BLANK(183)
|
||||
DEF_ICON(TRACKER)
|
||||
|
|
|
@ -758,8 +758,8 @@ static void init_proportional_edit(TransInfo *t)
|
|||
else if (t->data_type == &TransConvertType_MeshUV && t->flag & T_PROP_CONNECTED) {
|
||||
/* Already calculated by uv_set_connectivity_distance. */
|
||||
}
|
||||
else if (t->data_type == &TransConvertType_Curve) {
|
||||
BLI_assert(t->obedit_type == OB_CURVES_LEGACY);
|
||||
else if (ELEM(t->data_type, &TransConvertType_Curve, &TransConvertType_Curves)) {
|
||||
BLI_assert(t->obedit_type == OB_CURVES_LEGACY || t->obedit_type == OB_CURVES);
|
||||
set_prop_dist(t, false);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "BLI_array.hh"
|
||||
#include "BLI_index_mask_ops.hh"
|
||||
#include "BLI_inplace_priority_queue.hh"
|
||||
#include "BLI_span.hh"
|
||||
|
||||
#include "BKE_curves.hh"
|
||||
|
@ -23,11 +24,46 @@
|
|||
|
||||
namespace blender::ed::transform::curves {
|
||||
|
||||
static void calculate_curve_point_distances_for_proportional_editing(
|
||||
const Span<float3> positions, MutableSpan<float> r_distances)
|
||||
{
|
||||
Array<bool, 32> visited(positions.size(), false);
|
||||
|
||||
InplacePriorityQueue<float, std::less<float>> queue(r_distances);
|
||||
while (!queue.is_empty()) {
|
||||
int64_t index = queue.pop_index();
|
||||
if (visited[index]) {
|
||||
continue;
|
||||
}
|
||||
visited[index] = true;
|
||||
|
||||
/* TODO(Falk): Handle cyclic curves here. */
|
||||
if (index > 0 && !visited[index - 1]) {
|
||||
int adjacent = index - 1;
|
||||
float dist = r_distances[index] + math::distance(positions[index], positions[adjacent]);
|
||||
if (dist < r_distances[adjacent]) {
|
||||
r_distances[adjacent] = dist;
|
||||
queue.priority_changed(adjacent);
|
||||
}
|
||||
}
|
||||
if (index < positions.size() - 1 && !visited[index + 1]) {
|
||||
int adjacent = index + 1;
|
||||
float dist = r_distances[index] + math::distance(positions[index], positions[adjacent]);
|
||||
if (dist < r_distances[adjacent]) {
|
||||
r_distances[adjacent] = dist;
|
||||
queue.priority_changed(adjacent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void createTransCurvesVerts(bContext * /*C*/, TransInfo *t)
|
||||
{
|
||||
MutableSpan<TransDataContainer> trans_data_contrainers(t->data_container, t->data_container_len);
|
||||
Array<Vector<int64_t>> selected_indices_per_object(t->data_container_len);
|
||||
Array<IndexMask> selection_per_object(t->data_container_len);
|
||||
const bool use_proportional_edit = (t->flag & T_PROP_EDIT_ALL) != 0;
|
||||
const bool use_connected_only = (t->flag & T_PROP_CONNECTED) != 0;
|
||||
|
||||
/* Count selected elements per object and create TransData structs. */
|
||||
for (const int i : trans_data_contrainers.index_range()) {
|
||||
|
@ -35,10 +71,15 @@ static void createTransCurvesVerts(bContext * /*C*/, TransInfo *t)
|
|||
Curves *curves_id = static_cast<Curves *>(tc.obedit->data);
|
||||
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
|
||||
selection_per_object[i] = ed::curves::retrieve_selected_points(curves,
|
||||
selected_indices_per_object[i]);
|
||||
if (use_proportional_edit) {
|
||||
tc.data_len = curves.point_num;
|
||||
}
|
||||
else {
|
||||
selection_per_object[i] = ed::curves::retrieve_selected_points(
|
||||
curves, selected_indices_per_object[i]);
|
||||
tc.data_len = selection_per_object[i].size();
|
||||
}
|
||||
|
||||
tc.data_len = selection_per_object[i].size();
|
||||
if (tc.data_len > 0) {
|
||||
tc.data = MEM_cnew_array<TransData>(tc.data_len, __func__);
|
||||
}
|
||||
|
@ -52,34 +93,92 @@ static void createTransCurvesVerts(bContext * /*C*/, TransInfo *t)
|
|||
}
|
||||
Curves *curves_id = static_cast<Curves *>(tc.obedit->data);
|
||||
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
IndexMask selected_indices = selection_per_object[i];
|
||||
|
||||
float mtx[3][3], smtx[3][3];
|
||||
copy_m3_m4(mtx, tc.obedit->object_to_world);
|
||||
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
|
||||
|
||||
MutableSpan<float3> positions = curves.positions_for_write();
|
||||
threading::parallel_for(selected_indices.index_range(), 1024, [&](const IndexRange range) {
|
||||
for (const int selection_i : range) {
|
||||
TransData *td = &tc.data[selection_i];
|
||||
float *elem = reinterpret_cast<float *>(&positions[selected_indices[selection_i]]);
|
||||
copy_v3_v3(td->iloc, elem);
|
||||
copy_v3_v3(td->center, td->iloc);
|
||||
td->loc = elem;
|
||||
if (use_proportional_edit) {
|
||||
const OffsetIndices<int> points_by_curve = curves.points_by_curve();
|
||||
const VArray<bool> selection = curves.attributes().lookup_or_default<bool>(
|
||||
".selection", ATTR_DOMAIN_POINT, true);
|
||||
threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange range) {
|
||||
Vector<float> closest_distances;
|
||||
for (const int curve_i : range) {
|
||||
const IndexRange points = points_by_curve[curve_i];
|
||||
const bool has_any_selected = ed::curves::has_anything_selected(selection, points);
|
||||
if (!has_any_selected) {
|
||||
for (const int point_i : points) {
|
||||
TransData &td = tc.data[point_i];
|
||||
td.flag |= TD_NOTCONNECTED;
|
||||
td.dist = FLT_MAX;
|
||||
}
|
||||
if (use_connected_only) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
td->flag = TD_SELECTED;
|
||||
td->ext = nullptr;
|
||||
closest_distances.reinitialize(points.size());
|
||||
closest_distances.fill(std::numeric_limits<float>::max());
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
}
|
||||
});
|
||||
for (const int i : IndexRange(points.size())) {
|
||||
const int point_i = points[i];
|
||||
TransData &td = tc.data[point_i];
|
||||
float3 *elem = &positions[point_i];
|
||||
|
||||
copy_v3_v3(td.iloc, *elem);
|
||||
copy_v3_v3(td.center, td.iloc);
|
||||
td.loc = *elem;
|
||||
|
||||
td.flag = 0;
|
||||
if (selection[point_i]) {
|
||||
closest_distances[i] = 0.0f;
|
||||
td.flag = TD_SELECTED;
|
||||
}
|
||||
|
||||
td.ext = nullptr;
|
||||
|
||||
copy_m3_m3(td.smtx, smtx);
|
||||
copy_m3_m3(td.mtx, mtx);
|
||||
}
|
||||
|
||||
if (use_connected_only) {
|
||||
calculate_curve_point_distances_for_proportional_editing(
|
||||
positions.slice(points), closest_distances.as_mutable_span());
|
||||
for (const int i : IndexRange(points.size())) {
|
||||
TransData &td = tc.data[points[i]];
|
||||
td.dist = closest_distances[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
const IndexMask selected_indices = selection_per_object[i];
|
||||
threading::parallel_for(selected_indices.index_range(), 1024, [&](const IndexRange range) {
|
||||
for (const int selection_i : range) {
|
||||
TransData *td = &tc.data[selection_i];
|
||||
float3 *elem = &positions[selected_indices[selection_i]];
|
||||
|
||||
copy_v3_v3(td->iloc, *elem);
|
||||
copy_v3_v3(td->center, td->iloc);
|
||||
td->loc = *elem;
|
||||
|
||||
td->flag = TD_SELECTED;
|
||||
td->ext = nullptr;
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void recalcData_curves(TransInfo *t)
|
||||
{
|
||||
Span<TransDataContainer> trans_data_contrainers(t->data_container, t->data_container_len);
|
||||
const Span<TransDataContainer> trans_data_contrainers(t->data_container, t->data_container_len);
|
||||
for (const TransDataContainer &tc : trans_data_contrainers) {
|
||||
Curves *curves_id = static_cast<Curves *>(tc.obedit->data);
|
||||
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "DNA_gpencil_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "BKE_gpencil.h"
|
||||
|
@ -42,6 +43,7 @@
|
|||
#include "MOD_gpencil_util.h"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
|
||||
|
@ -254,11 +256,11 @@ static bool isDisabled(GpencilModifierData *md, int UNUSED(userRenderParams))
|
|||
/* Generic "generateStrokes" callback */
|
||||
static void generateStrokes(GpencilModifierData *md, Depsgraph *depsgraph, Object *ob)
|
||||
{
|
||||
Scene *scene = DEG_get_evaluated_scene(depsgraph);
|
||||
bGPdata *gpd = ob->data;
|
||||
|
||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
|
||||
BKE_gpencil_frame_active_set(depsgraph, gpd);
|
||||
bGPDframe *gpf = gpl->actframe;
|
||||
bGPDframe *gpf = BKE_gpencil_frame_retime_get(depsgraph, scene, ob, gpl);
|
||||
if (gpf == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -53,7 +53,8 @@ class USDShapeReader : public USDGeomReader {
|
|||
const char ** /*err_str*/) override;
|
||||
bool is_time_varying();
|
||||
|
||||
virtual bool topology_changed(const Mesh * /*existing_mesh*/, double /*motionSampleTime*/)
|
||||
virtual bool topology_changed(const Mesh * /*existing_mesh*/,
|
||||
double /*motionSampleTime*/) override
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue