Cleanup: Reduce nesteds in node.cc #105509

Merged
Hans Goudey merged 12 commits from mod_moder/blender:cleanup_reduce_nesteds into main 2023-04-16 22:53:20 +02:00
36 changed files with 216 additions and 172 deletions
Showing only changes of commit f9f051b9cb - Show all commits

View File

@ -1934,7 +1934,7 @@ if(FIRST_RUN)
info_cfg_option(WITH_IMAGE_OPENEXR)
info_cfg_option(WITH_IMAGE_OPENJPEG)
info_cfg_option(WITH_IMAGE_TIFF)
info_cfg_text("Audio:")
info_cfg_option(WITH_CODEC_AVI)
info_cfg_option(WITH_CODEC_FFMPEG)

View File

@ -3,23 +3,26 @@
#include "GHOST_NDOFManagerUnix.h"
#include "GHOST_System.h"
/* Logging, use `ghost.ndof.unix.*` prefix. */
#include "CLG_log.h"
#include <spnav.h>
#include <stdio.h>
#include <unistd.h>
#define SPNAV_SOCK_PATH "/var/run/spnav.sock"
static const char *spnav_sock_path = "/var/run/spnav.sock";
static CLG_LogRef LOG_NDOF_UNIX = {"ghost.ndof.unix"};
#define LOG (&LOG_NDOF_UNIX)
GHOST_NDOFManagerUnix::GHOST_NDOFManagerUnix(GHOST_System &sys)
: GHOST_NDOFManager(sys), available_(false)
{
if (access(SPNAV_SOCK_PATH, F_OK) != 0) {
#ifdef DEBUG
/* annoying for official builds, just adds noise and most people don't own these */
puts("ndof: spacenavd not found");
/* This isn't a hard error, just means the user doesn't have a 3D mouse. */
#endif
if (access(spnav_sock_path, F_OK) != 0) {
CLOG_INFO(LOG, 1, "'spacenavd' not found at \"%s\"", spnav_sock_path);
}
else if (spnav_open() != -1) {
CLOG_INFO(LOG, 1, "'spacenavd' found at\"%s\"", spnav_sock_path);
available_ = true;
/* determine exactly which device (if any) is plugged in */

View File

@ -6318,6 +6318,7 @@ def km_sculpt_expand_modal(_params):
])
return keymap
def km_sculpt_mesh_filter_modal_map(_params):
items = []
keymap = (

View File

@ -3260,13 +3260,13 @@ class VIEW3D_MT_sculpt(Menu):
props = layout.operator("sculpt.trim_box_gesture", text="Box Trim")
props.trim_mode = 'DIFFERENCE'
layout.operator("sculpt.trim_lasso_gesture", text="Lasso Trim")
props = layout.operator("sculpt.trim_lasso_gesture", text="Lasso Trim")
props.trim_mode = 'DIFFERENCE'
props = layout.operator("sculpt.trim_box_gesture", text="Box Add")
props.trim_mode = 'JOIN'
layout.operator("sculpt.trim_lasso_gesture", text="Lasso Add")
props = layout.operator("sculpt.trim_lasso_gesture", text="Lasso Add")
props.trim_mode = 'JOIN'
layout.operator("sculpt.project_line_gesture", text="Line Project")

View File

@ -93,7 +93,8 @@ static const Edge<CoordSpace::Tile> convert_coord_space(const Edge<CoordSpace::U
};
}
class NonManifoldTileEdges : public Vector<Edge<CoordSpace::Tile>> {};
class NonManifoldTileEdges : public Vector<Edge<CoordSpace::Tile>> {
};
class NonManifoldUVEdges : public Vector<Edge<CoordSpace::UV>> {
public:
@ -221,7 +222,7 @@ struct Rows {
/** This pixel is directly affected by a brush and doesn't need to be solved. */
Brush,
SelectedForCloserExamination,
/** This pixel will be copid from another pixel to solve non-manifold edge bleeding. */
/** This pixel will be copied from another pixel to solve non-manifold edge bleeding. */
CopyFromClosestEdge,
};
@ -232,7 +233,7 @@ struct Rows {
/**
* Index of the edge in the list of non-manifold edges.
*
* The edge is kept to calculate athe mix factor between the two pixels that have chosen to
* The edge is kept to calculate the mix factor between the two pixels that have chosen to
* be mixed.
*/
int64_t edge_index;
@ -308,7 +309,7 @@ struct Rows {
* Look for a second source pixel that will be blended with the first source pixel to improve
* the quality of the fix.
*
* - The second source pixel must be a neighbour pixel of the first source, or the same as the
* - The second source pixel must be a neighbor pixel of the first source, or the same as the
* first source when no second pixel could be found.
* - The second source pixel must be a pixel that is painted on by the brush.
* - The second source pixel must be the second closest pixel , or the first source

View File

@ -21,4 +21,4 @@ void BKE_pbvh_pixels_copy_update(PBVH &pbvh,
ImageUser &image_user,
const uv_islands::MeshData &mesh_data);
} // namespace blender::bke::pbvh::pixels
} // namespace blender::bke::pbvh::pixels

View File

@ -680,21 +680,21 @@ template<typename T = float> struct AngleFraction {
default:
BLI_assert_unreachable();
}
/* Resulting angle should be oscilating in [0..pi/4] range. */
/* Resulting angle should be oscillating in [0..pi/4] range. */
BLI_assert(a.numerator_ >= 0 && a.numerator_ <= a.denominator_ / 4);
T angle = T(M_PI) * (T(a.numerator_) / T(a.denominator_));
x = math::cos(angle);
y = math::sin(angle);
/* Diagonal symetry "unfolding". */
/* Diagonal symmetry "unfolding". */
if (ELEM(octant, 1, 2)) {
std::swap(x, y);
}
}
/* Y axis symetry. */
/* Y axis symmetry. */
if (octant >= 2) {
x = -x;
}
/* X axis symetry. */
/* X axis symmetry. */
if (is_negative) {
y = -y;
}

View File

@ -22,19 +22,16 @@ namespace blender::math::detail {
template<typename T, typename AngleT>
AxisAngle<T, AngleT>::AxisAngle(const VecBase<T, 3> &axis, const AngleT &angle)
{
/* TODO: After merge to limit side effects. */
// BLI_assert(is_unit_scale(axis));
// axis_ = axis;
T length;
this->axis_ = math::normalize_and_get_length(axis, length);
this->angle_ = angle;
BLI_assert(is_unit_scale(axis));
axis_ = axis;
angle_ = angle;
}
template<typename T, typename AngleT>
AxisAngle<T, AngleT>::AxisAngle(const AxisSigned axis, const AngleT &angle)
{
this->axis_ = VecBase<T, 3>(axis);
this->angle_ = angle;
axis_ = to_vector<VecBase<T, 3>>(axis);
angle_ = angle;
}
template<typename T, typename AngleT>

View File

@ -27,11 +27,6 @@ namespace blender::math {
namespace detail {
/* Forward declaration for casting operators. */
template<typename T> struct Euler3;
template<typename T> struct EulerXYZ;
template<typename T> struct Quaternion;
template<typename T, typename AngleT> struct AxisAngle {
using vec3_type = VecBase<T, 3>;

View File

@ -90,8 +90,10 @@ template<typename T> inline T floor(const T &a)
return std::floor(a);
}
/* Repeats the sawtooth pattern even on negative numbers.
* ex: 'mod_periodic(-3, 4) = 1', 'mod(-3, 4)= -3' */
/**
* Repeats the saw-tooth pattern even on negative numbers.
* ex: `mod_periodic(-3, 4) = 1`, `mod(-3, 4)= -3`
*/
template<typename T> inline T mod_periodic(const T &a, const T &b)
{
return a - (b * math::floor(a / b));

View File

@ -455,8 +455,8 @@ struct CartesianBasis {
const AxisSigned b_forward)
{
/* Pick predictable next axis. */
AxisSigned a_up = AxisSigned(abs(a_forward.next_after()));
AxisSigned b_up = AxisSigned(abs(b_forward.next_after()));
AxisSigned a_up = abs(a_forward.next_after());
AxisSigned b_up = abs(b_forward.next_after());
if (sign(a_forward) != sign(b_forward)) {
/* Flip both axis (up and right) so resulting rotation matrix sign remains positive. */

View File

@ -130,10 +130,6 @@ template<typename T> struct EulerBase {
/** \name EulerXYZ
* \{ */
/* Forward declaration for casting operators. */
template<typename T, typename AngleT> struct AxisAngle;
template<typename T> struct Quaternion;
template<typename T> struct EulerXYZ : public EulerBase<T> {
using AngleT = AngleRadian<T>;

View File

@ -1379,8 +1379,8 @@ template<typename MatT> [[nodiscard]] MatT orthogonalize(const MatT &mat, const
/**
* The secondary axis is chosen as follow (X->Y, Y->X, Z->X).
* If this axis is coplanar try the third axis.
* If also coplanar, make up an axis by shuffling the primary axis coordinates (xyz > yzx).
* If this axis is co-planar try the third axis.
* If also co-planar, make up an axis by shuffling the primary axis coordinates (XYZ > YZX).
*/
switch (axis) {
case Axis::X:

View File

@ -20,9 +20,6 @@ namespace blender::math {
namespace detail {
/* Forward declaration for casting operators. */
template<typename T> struct EulerXYZ;
/**
* A `blender::math::Quaternion<T>` represents either an orientation or a rotation.
*

View File

@ -265,10 +265,10 @@ set(SRC
BLI_math_angle_types.hh
BLI_math_axis_angle.hh
BLI_math_axis_angle_types.hh
BLI_math_basis_types.hh
BLI_math_base.h
BLI_math_base.hh
BLI_math_base_safe.h
BLI_math_basis_types.hh
BLI_math_bits.h
BLI_math_boolean.hh
BLI_math_color.h

View File

@ -304,7 +304,7 @@ TEST(math_rotation, RotateDirectionAroundAxis)
TEST(math_rotation, AxisAngleConstructors)
{
AxisAngle a({0.0f, 0.0f, 2.0f}, M_PI_2);
AxisAngle a({0.0f, 0.0f, 1.0f}, M_PI_2);
EXPECT_V3_NEAR(a.axis(), float3(0, 0, 1), 1e-4);
EXPECT_NEAR(float(a.angle()), M_PI_2, 1e-4);
EXPECT_NEAR(sin(a.angle()), 1.0f, 1e-4);
@ -316,6 +316,10 @@ TEST(math_rotation, AxisAngleConstructors)
EXPECT_NEAR(b.angle().sin(), 1.0f, 1e-4);
EXPECT_NEAR(b.angle().cos(), 0.0f, 1e-4);
AxisAngle axis_angle_basis = AxisAngle(AxisSigned::Y_NEG, M_PI);
EXPECT_EQ(axis_angle_basis.axis(), float3(0.0f, -1.0f, 0.0f));
EXPECT_EQ(axis_angle_basis.angle(), M_PI);
AxisAngle c({1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f});
EXPECT_V3_NEAR(c.axis(), float3(0, 0, 1), 1e-4);
EXPECT_NEAR(float(c.angle()), M_PI_2, 1e-4);

View File

@ -271,7 +271,7 @@ TEST(math_rotation_types, AngleFraction)
EXPECT_NEAR(angle.cos(), cos((T(M_PI) * i) / 16), 1e-6f);
EXPECT_NEAR(angle.sin(), sin((T(M_PI) * i) / 16), 1e-6f);
/* Ensure symetry. */
/* Ensure symmetry. */
AngleCartesian angle_opposite(pi + pi * i / 16);
EXPECT_EQ(angle.cos(), -angle_opposite.cos());
EXPECT_EQ(angle.sin(), -angle_opposite.sin());
@ -308,6 +308,7 @@ TEST(math_rotation_types, AngleFraction)
EXPECT_EQ(AngleCartesian(-pi * 1 / 4).sin(), T(-M_SQRT1_2));
EXPECT_EQ(AngleCartesian(-pi * 3 / 4).sin(), T(-M_SQRT1_2));
}
TEST(math_rotation_types, TypeConversion)
{
/* All the same rotation. */
@ -315,7 +316,8 @@ TEST(math_rotation_types, TypeConversion)
EulerXYZ euler_xyz(AngleRadian::from_degree(20.0559),
AngleRadian::from_degree(-20.5632f),
AngleRadian::from_degree(30.3091f));
AxisAngle axis_angle({0.563771, -0.333098, 0.755783}, AngleRadian::from_degree(44.0284f));
AxisAngle axis_angle(normalize(float3{0.563771, -0.333098, 0.755783}),
AngleRadian::from_degree(44.0284f));
EXPECT_V4_NEAR(float4(to_quaternion(euler_xyz)), float4(quaternion), 1e-4);
EXPECT_V3_NEAR(to_axis_angle(euler_xyz).axis(), axis_angle.axis(), 1e-4);
@ -394,12 +396,12 @@ TEST(math_rotation_types, Euler3Conversion)
EXPECT_V3_NEAR(float3(to_euler(mat_zxy, EulerOrder::ZXY).xyz()), xyz, 1e-4);
EXPECT_V3_NEAR(float3(to_euler(mat_zyx, EulerOrder::ZYX).xyz()), xyz, 1e-4);
AxisAngle axis_angle_xyz = AxisAngle({0.563771, -0.333098, 0.755783}, 0.76844f);
AxisAngle axis_angle_xzy = AxisAngle({0.359907, -0.376274, 0.853747}, 0.676476f);
AxisAngle axis_angle_yxz = AxisAngle({0.636846, -0.376274, 0.672937}, 0.676476f);
AxisAngle axis_angle_yzx = AxisAngle({0.563771, -0.572084, 0.59572}, 0.76844f);
AxisAngle axis_angle_zxy = AxisAngle({0.318609, -0.572084, 0.755783}, 0.76844f);
AxisAngle axis_angle_zyx = AxisAngle({0.359907, -0.646237, 0.672937}, 0.676476f);
AxisAngle axis_angle_xyz = {normalize(float3{0.563771, -0.333098, 0.755783}), 0.76844f};
AxisAngle axis_angle_xzy = {normalize(float3{0.359907, -0.376274, 0.853747}), 0.676476f};
AxisAngle axis_angle_yxz = {normalize(float3{0.636846, -0.376274, 0.672937}), 0.676476f};
AxisAngle axis_angle_yzx = {normalize(float3{0.563771, -0.572084, 0.59572}), 0.76844f};
AxisAngle axis_angle_zxy = {normalize(float3{0.318609, -0.572084, 0.755783}), 0.76844f};
AxisAngle axis_angle_zyx = {normalize(float3{0.359907, -0.646237, 0.672937}), 0.676476f};
EXPECT_V3_NEAR(to_axis_angle(euler3_xyz).axis(), axis_angle_xyz.axis(), 1e-4);
EXPECT_V3_NEAR(to_axis_angle(euler3_xzy).axis(), axis_angle_xzy.axis(), 1e-4);

View File

@ -10,4 +10,4 @@ void main()
tilemaps_clip_buf[index].clip_near = floatBitsToOrderedInt(-FLT_MAX);
tilemaps_clip_buf[index].clip_far = floatBitsToOrderedInt(FLT_MAX);
}
}
}

View File

@ -333,30 +333,26 @@ struct PBVHBatches {
foreach_faces,
GPUVertBufRaw *access)
{
float fno[3];
short no[3];
int last_poly = -1;
const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(args->pdata, CD_PROP_BOOL, "sharp_face"));
short no[3];
int last_poly = -1;
bool flat = false;
foreach_faces([&](int /*buffer_i*/, int /*tri_i*/, int vertex_i, const MLoopTri *tri) {
bool smooth = false;
if (tri->poly != last_poly) {
last_poly = tri->poly;
if (sharp_faces && sharp_faces[tri->poly]) {
smooth = true;
flat = sharp_faces && sharp_faces[tri->poly];
if (flat) {
const MPoly &poly = args->polys[tri->poly];
float fno[3];
BKE_mesh_calc_poly_normal(
&poly, args->mloop + poly.loopstart, args->vert_positions, fno);
normal_float_to_short_v3(no, fno);
}
else {
smooth = false;
}
}
if (!smooth) {
if (!flat) {
normal_float_to_short_v3(no, args->vert_normals[vertex_i]);
}

View File

@ -264,7 +264,7 @@ static bool graphedit_get_context(bAnimContext *ac, SpaceGraph *sipo)
ac->ads = sipo->ads;
/* set settings for Graph Editor - "Selected = Editable" */
if (U.animation_flag & USER_ANIM_ONLY_SHOW_SELECTED_CURVE_KEYS) {
if (U.animation_flag & USER_ANIM_ONLY_SHOW_SELECTED_CURVE_KEYS) {
sipo->ads->filterflag |= ADS_FILTER_SELEDIT;
}
else {

View File

@ -406,10 +406,8 @@ struct ProjPaintState {
SpinLock *tile_lock;
Mesh *me_eval;
int totlooptri_eval;
int totloop_eval;
int totpoly_eval;
int totedge_eval;
int totvert_eval;
const float (*vert_positions_eval)[3];
@ -3920,8 +3918,8 @@ static void proj_paint_state_seam_bleed_init(ProjPaintState *ps)
{
if (ps->seam_bleed_px > 0.0f) {
ps->vertFaces = MEM_cnew_array<LinkNode *>(ps->totvert_eval, "paint-vertFaces");
ps->faceSeamFlags = MEM_cnew_array<ushort>(ps->totlooptri_eval, "paint-faceSeamFlags");
ps->faceWindingFlags = MEM_cnew_array<char>(ps->totlooptri_eval, "paint-faceWindindFlags");
ps->faceSeamFlags = MEM_cnew_array<ushort>(ps->looptris_eval.size(), __func__);
ps->faceWindingFlags = MEM_cnew_array<char>(ps->looptris_eval.size(), __func__);
ps->loopSeamData = static_cast<LoopSeamData *>(
MEM_mallocN(sizeof(LoopSeamData) * ps->totloop_eval, "paint-loopSeamUVs"));
ps->vertSeams = MEM_cnew_array<ListBase>(ps->totvert_eval, "paint-vertSeams");
@ -4083,7 +4081,6 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p
CustomData_get_layer_named(&ps->me_eval->pdata, CD_PROP_BOOL, "sharp_face"));
ps->totvert_eval = ps->me_eval->totvert;
ps->totedge_eval = ps->me_eval->totedge;
ps->totpoly_eval = ps->me_eval->totpoly;
ps->totloop_eval = ps->me_eval->totloop;
@ -4311,7 +4308,7 @@ static void project_paint_prepare_all_faces(ProjPaintState *ps,
BLI_assert(ps->image_tot == 0);
for (tri_index = 0; tri_index < ps->totlooptri_eval; tri_index++) {
for (tri_index = 0; tri_index < ps->looptris_eval.size(); tri_index++) {
bool is_face_sel;
bool skip_tri = false;

View File

@ -1711,7 +1711,11 @@ static int sculpt_trim_gesture_box_invoke(bContext *C, wmOperator *op, const wmE
static int sculpt_trim_gesture_lasso_exec(bContext *C, wmOperator *op)
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Object *object = CTX_data_active_object(C);
BKE_sculpt_update_object_for_edit(depsgraph, object, false, true, false);
SculptSession *ss = object->sculpt;
if (BKE_pbvh_type(ss->pbvh) != PBVH_FACES) {
/* Not supported in Multires and Dyntopo. */

View File

@ -16,9 +16,11 @@
#include "BLI_hash.h"
#include "BLI_math.h"
#include "BLI_math_vector.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_span.hh"
#include "BLI_task.h"
#include "BLI_task.hh"
#include "BLI_vector.hh"
#include "DNA_brush_types.h"
#include "DNA_customdata_types.h"
@ -53,6 +55,9 @@
#include "bmesh.h"
using blender::float3;
using blender::Vector;
/* Utils. */
int ED_sculpt_face_sets_find_next_available_id(struct Mesh *mesh)
@ -1236,34 +1241,45 @@ static void sculpt_face_set_delete_geometry(Object *ob,
static void sculpt_face_set_edit_fair_face_set(Object *ob,
const int active_face_set_id,
const eMeshFairingDepth fair_order)
const eMeshFairingDepth fair_order,
const float strength)
{
SculptSession *ss = ob->sculpt;
const int totvert = SCULPT_vertex_count_get(ss);
Mesh *mesh = static_cast<Mesh *>(ob->data);
bool *fair_verts = static_cast<bool *>(
MEM_malloc_arrayN(totvert, sizeof(bool), "fair vertices"));
Vector<float3> orig_positions;
Vector<bool> fair_verts;
orig_positions.resize(totvert);
fair_verts.resize(totvert);
SCULPT_boundary_info_ensure(ob);
for (int i = 0; i < totvert; i++) {
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
orig_positions[i] = SCULPT_vertex_co_get(ss, vertex);
fair_verts[i] = !SCULPT_vertex_is_boundary(ss, vertex) &&
SCULPT_vertex_has_face_set(ss, vertex, active_face_set_id) &&
SCULPT_vertex_has_unique_face_set(ss, vertex);
}
float(*positions)[3] = SCULPT_mesh_deformed_positions_get(ss);
BKE_mesh_prefair_and_fair_verts(mesh, positions, fair_verts, fair_order);
MEM_freeN(fair_verts);
BKE_mesh_prefair_and_fair_verts(mesh, positions, fair_verts.data(), fair_order);
for (int i = 0; i < totvert; i++) {
if (fair_verts[i]) {
interp_v3_v3v3(positions[i], orig_positions[i], positions[i], strength);
}
}
}
static void sculpt_face_set_apply_edit(Object *ob,
const int active_face_set_id,
const int mode,
const bool modify_hidden)
const bool modify_hidden,
const float strength = 0.0f)
{
SculptSession *ss = ob->sculpt;
@ -1284,10 +1300,12 @@ static void sculpt_face_set_apply_edit(Object *ob,
sculpt_face_set_delete_geometry(ob, ss, active_face_set_id, modify_hidden);
break;
case SCULPT_FACE_SET_EDIT_FAIR_POSITIONS:
sculpt_face_set_edit_fair_face_set(ob, active_face_set_id, MESH_FAIRING_DEPTH_POSITION);
sculpt_face_set_edit_fair_face_set(
ob, active_face_set_id, MESH_FAIRING_DEPTH_POSITION, strength);
break;
case SCULPT_FACE_SET_EDIT_FAIR_TANGENCY:
sculpt_face_set_edit_fair_face_set(ob, active_face_set_id, MESH_FAIRING_DEPTH_TANGENCY);
sculpt_face_set_edit_fair_face_set(
ob, active_face_set_id, MESH_FAIRING_DEPTH_TANGENCY, strength);
break;
}
}
@ -1399,13 +1417,17 @@ static void sculpt_face_set_edit_modify_coordinates(bContext *C,
PBVH *pbvh = ss->pbvh;
PBVHNode **nodes;
int totnode;
BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
const float strength = RNA_float_get(op->ptr, "strength");
SCULPT_undo_push_begin(ob, op);
for (int i = 0; i < totnode; i++) {
BKE_pbvh_node_mark_update(nodes[i]);
SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_COORDS);
}
sculpt_face_set_apply_edit(ob, abs(active_face_set), mode, false);
sculpt_face_set_apply_edit(ob, abs(active_face_set), mode, false, strength);
if (ss->deform_modifiers_active || ss->shapekey_active) {
SCULPT_flush_stroke_deform(sd, ob, true);
@ -1416,32 +1438,37 @@ static void sculpt_face_set_edit_modify_coordinates(bContext *C,
MEM_freeN(nodes);
}
static int sculpt_face_set_edit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static bool sculpt_face_set_edit_init(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
const eSculptFaceSetEditMode mode = static_cast<eSculptFaceSetEditMode>(
RNA_enum_get(op->ptr, "mode"));
const bool modify_hidden = RNA_boolean_get(op->ptr, "modify_hidden");
if (!sculpt_face_set_edit_is_operation_valid(ss, mode, modify_hidden)) {
return OPERATOR_CANCELLED;
return false;
}
ss->face_sets = BKE_sculpt_face_sets_ensure(BKE_mesh_from_object(ob));
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false);
/* Update the current active Face Set and Vertex as the operator can be used directly from the
* tool without brush cursor. */
SculptCursorGeometryInfo sgi;
const float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])};
if (!SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false)) {
/* The cursor is not over the mesh. Cancel to avoid editing the last updated Face Set ID. */
return true;
}
static int sculpt_face_set_edit_exec(bContext *C, wmOperator *op)
{
if (!sculpt_face_set_edit_init(C, op)) {
return OPERATOR_CANCELLED;
}
const int active_face_set = SCULPT_active_face_set_get(ss);
Object *ob = CTX_data_active_object(C);
const int active_face_set = RNA_int_get(op->ptr, "active_face_set");
const eSculptFaceSetEditMode mode = static_cast<eSculptFaceSetEditMode>(
RNA_enum_get(op->ptr, "mode"));
const bool modify_hidden = RNA_boolean_get(op->ptr, "modify_hidden");
switch (mode) {
case SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY:
@ -1462,6 +1489,27 @@ static int sculpt_face_set_edit_invoke(bContext *C, wmOperator *op, const wmEven
return OPERATOR_FINISHED;
}
static int sculpt_face_set_edit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false);
/* Update the current active Face Set and Vertex as the operator can be used directly from the
* tool without brush cursor. */
SculptCursorGeometryInfo sgi;
const float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])};
if (!SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false)) {
/* The cursor is not over the mesh. Cancel to avoid editing the last updated Face Set ID. */
return OPERATOR_CANCELLED;
}
RNA_int_set(op->ptr, "active_face_set", SCULPT_active_face_set_get(ss));
return sculpt_face_set_edit_exec(C, op);
}
void SCULPT_OT_face_sets_edit(struct wmOperatorType *ot)
{
/* Identifiers. */
@ -1471,12 +1519,19 @@ void SCULPT_OT_face_sets_edit(struct wmOperatorType *ot)
/* Api callbacks. */
ot->invoke = sculpt_face_set_edit_invoke;
ot->exec = sculpt_face_set_edit_exec;
ot->poll = SCULPT_mode_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR;
PropertyRNA *prop = RNA_def_int(
ot->srna, "active_face_set", 1, 0, INT_MAX, "Active Face Set", "", 0, 64);
RNA_def_property_flag(prop, PROP_HIDDEN);
RNA_def_enum(
ot->srna, "mode", prop_sculpt_face_sets_edit_types, SCULPT_FACE_SET_EDIT_GROW, "Mode", "");
RNA_def_float(ot->srna, "strength", 1.0f, 0.0f, 1.0f, "Strength", "", 0.0f, 1.0f);
ot->prop = RNA_def_boolean(ot->srna,
"modify_hidden",
true,

View File

@ -195,11 +195,6 @@ struct UnwrapOptions {
bool pin_unselected;
};
struct UnwrapResultInfo {
int count_changed;
int count_failed;
};
static bool uvedit_have_selection(const Scene *scene, BMEditMesh *em, const UnwrapOptions *options)
{
BMFace *efa;
@ -1387,9 +1382,10 @@ static void uvedit_pack_islands_multi(const Scene *scene,
FaceIsland *face_island = island_vector[i];
blender::geometry::PackIsland *pack_island = new blender::geometry::PackIsland();
pack_island->bounds_rect = face_island->bounds_rect;
pack_island->caller_index = i;
pack_island_vector.append(pack_island);
}
BoxPack *box_array = pack_islands(pack_island_vector, *params, scale);
pack_islands(pack_island_vector, *params, scale);
float base_offset[2] = {0.0f, 0.0f};
copy_v2_v2(base_offset, params->udim_base_offset);
@ -1428,8 +1424,9 @@ static void uvedit_pack_islands_multi(const Scene *scene,
float matrix[2][2];
float matrix_inverse[2][2];
float pre_translate[2];
for (int i = 0; i < island_vector.size(); i++) {
FaceIsland *island = island_vector[box_array[i].index];
for (int64_t i : pack_island_vector.index_range()) {
blender::geometry::PackIsland *pack_island = pack_island_vector[i];
FaceIsland *island = island_vector[pack_island->caller_index];
matrix[0][0] = scale[0];
matrix[0][1] = 0.0f;
matrix[1][0] = 0.0f;
@ -1439,11 +1436,16 @@ static void uvedit_pack_islands_multi(const Scene *scene,
/* Add base_offset, post transform. */
mul_v2_m2v2(pre_translate, matrix_inverse, base_offset);
/* Translate to box_array from bounds_rect. */
blender::geometry::PackIsland *pack_island = pack_island_vector[box_array[i].index];
pre_translate[0] += box_array[i].x - pack_island->bounds_rect.xmin;
pre_translate[1] += box_array[i].y - pack_island->bounds_rect.ymin;
/* Add pre-translation from #pack_islands. */
pre_translate[0] += pack_island->pre_translate.x;
pre_translate[1] += pack_island->pre_translate.y;
/* Perform the transformation. */
island_uv_transform(island, matrix, pre_translate);
/* Cleanup memory. */
pack_island_vector[i] = nullptr;
delete pack_island;
}
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
@ -1456,14 +1458,6 @@ static void uvedit_pack_islands_multi(const Scene *scene,
MEM_freeN(island->faces);
MEM_freeN(island);
}
for (int i = 0; i < pack_island_vector.size(); i++) {
blender::geometry::PackIsland *pack_island = pack_island_vector[i];
pack_island_vector[i] = nullptr;
delete pack_island;
}
MEM_freeN(box_array);
}
/* -------------------------------------------------------------------- */
@ -2438,15 +2432,9 @@ static int unwrap_exec(bContext *C, wmOperator *op)
}
/* execute unwrap */
UnwrapResultInfo result_info{};
result_info.count_changed = 0;
result_info.count_failed = 0;
uvedit_unwrap_multi(scene,
objects,
objects_len,
&options,
&result_info.count_changed,
&result_info.count_failed);
int count_changed = 0;
int count_failed = 0;
uvedit_unwrap_multi(scene, objects, objects_len, &options, &count_changed, &count_failed);
UVPackIsland_Params pack_island_params{};
pack_island_params.rotate = true;
@ -2464,17 +2452,17 @@ static int unwrap_exec(bContext *C, wmOperator *op)
MEM_freeN(objects);
if (result_info.count_failed == 0 && result_info.count_changed == 0) {
if (count_failed == 0 && count_changed == 0) {
BKE_report(op->reports,
RPT_WARNING,
"Unwrap could not solve any island(s), edge seams may need to be added");
}
else if (result_info.count_failed) {
else if (count_failed) {
BKE_reportf(op->reports,
RPT_WARNING,
"Unwrap failed to solve %d of %d island(s), edge seams may need to be added",
result_info.count_failed,
result_info.count_changed + result_info.count_failed);
count_failed,
count_changed + count_failed);
}
return OPERATOR_FINISHED;

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_boxpack_2d.h"
#include "BLI_math_matrix.hh"
#include "BLI_span.hh"
#include "DNA_vec_types.h"
@ -46,10 +46,12 @@ namespace blender::geometry {
class PackIsland {
public:
rctf bounds_rect;
float2 pre_translate; /* Output. */
int caller_index; /* Unchanged by #pack_islands, used by caller. */
};
BoxPack *pack_islands(const Span<PackIsland *> &island_vector,
const UVPackIsland_Params &params,
float r_scale[2]);
void pack_islands(const Span<PackIsland *> &islands,
const UVPackIsland_Params &params,
float r_scale[2]);
} // namespace blender::geometry

View File

@ -11,7 +11,6 @@
#include "BLI_convexhull_2d.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_math_matrix.hh"
#include "BLI_rect.h"
#include "BLI_vector.hh"
@ -302,9 +301,9 @@ static float calc_margin_from_aabb_length_sum(const Span<PackIsland *> &island_v
return params.margin * aabb_length_sum * 0.1f;
}
BoxPack *pack_islands(const Span<PackIsland *> &island_vector,
const UVPackIsland_Params &params,
float r_scale[2])
static BoxPack *pack_islands_box_array(const Span<PackIsland *> &island_vector,
const UVPackIsland_Params &params,
float r_scale[2])
{
BoxPack *box_array = static_cast<BoxPack *>(
MEM_mallocN(sizeof(*box_array) * island_vector.size(), __func__));
@ -351,4 +350,20 @@ BoxPack *pack_islands(const Span<PackIsland *> &island_vector,
return box_array;
}
void pack_islands(const Span<PackIsland *> &islands,
const UVPackIsland_Params &params,
float r_scale[2])
{
BoxPack *box_array = pack_islands_box_array(islands, params, r_scale);
for (int64_t i : islands.index_range()) {
BoxPack *box = box_array + i;
PackIsland *island = islands[box->index];
island->pre_translate.x = box->x - island->bounds_rect.xmin;
island->pre_translate.y = box->y - island->bounds_rect.ymin;
}
MEM_freeN(box_array);
}
} // namespace blender::geometry

View File

@ -4167,6 +4167,7 @@ void uv_parametrizer_pack(ParamHandle *handle, float margin, bool do_rotate, boo
}
geometry::PackIsland *pack_island = new geometry::PackIsland();
pack_island->caller_index = i;
pack_island_vector.append(pack_island);
float minv[2];
@ -4192,42 +4193,29 @@ void uv_parametrizer_pack(ParamHandle *handle, float margin, bool do_rotate, boo
params.udim_base_offset[1] = 0.0f;
float scale[2] = {1.0f, 1.0f};
BoxPack *box_array = pack_islands(pack_island_vector, params, scale);
pack_islands(pack_island_vector, params, scale);
for (int64_t i : pack_island_vector.index_range()) {
BoxPack *box = box_array + i;
PackIsland *pack_island = pack_island_vector[box->index];
pack_island->bounds_rect.xmin = box->x - pack_island->bounds_rect.xmin;
pack_island->bounds_rect.ymin = box->y - pack_island->bounds_rect.ymin;
}
unpacked = 0;
for (int i = 0; i < handle->ncharts; i++) {
PChart *chart = handle->charts[i];
if (ignore_pinned && chart->has_pins) {
unpacked++;
continue;
}
PackIsland *pack_island = pack_island_vector[i - unpacked];
PackIsland *pack_island = pack_island_vector[i];
PChart *chart = handle->charts[pack_island->caller_index];
/* TODO: Replace with #mul_v2_m2_add_v2v2 here soon. */
float m[2];
float b[2];
m[0] = scale[0];
m[1] = scale[1];
b[0] = pack_island->bounds_rect.xmin;
b[1] = pack_island->bounds_rect.ymin;
b[0] = pack_island->pre_translate.x;
b[1] = pack_island->pre_translate.y;
for (PVert *v = chart->verts; v; v = v->nextlink) {
/* Unusual accumulate-and-multiply here (will) reduce round-off error. */
v->uv[0] = m[0] * (v->uv[0] + b[0]);
v->uv[1] = m[1] * (v->uv[1] + b[1]);
}
pack_island_vector[i - unpacked] = nullptr;
pack_island_vector[i] = nullptr;
delete pack_island;
}
MEM_freeN(box_array);
if (handle->aspx != handle->aspy) {
uv_parametrizer_scale(handle, handle->aspx, handle->aspy);
}

View File

@ -341,4 +341,4 @@ void main(void)
default:
DISCARD_VERTEX
}
}
}

View File

@ -97,4 +97,4 @@ TEST(std140, fl_vec2)
EXPECT_EQ(offset, 16);
}
} // namespace blender::gpu
} // namespace blender::gpu

View File

@ -114,4 +114,4 @@ void VKDescriptorPools::free(VKDescriptorSet &descriptor_set)
descriptor_set.mark_freed();
}
} // namespace blender::gpu
} // namespace blender::gpu

View File

@ -62,4 +62,4 @@ class VKDescriptorPools {
bool is_last_pool_active();
void add_new_pool();
};
} // namespace blender::gpu
} // namespace blender::gpu

View File

@ -56,4 +56,4 @@ void VKStateManager::texture_unpack_row_length_set(uint /*len*/)
{
}
} // namespace blender::gpu
} // namespace blender::gpu

View File

@ -27,4 +27,4 @@ class VKStateManager : public StateManager {
void texture_unpack_row_length_set(uint len) override;
};
} // namespace blender::gpu
} // namespace blender::gpu

View File

@ -10,10 +10,10 @@ set(INC
../../blenlib
../../bmesh
../../depsgraph
../../geometry
../../makesdna
../../makesrna
../../windowmanager
../../geometry
../../../../extern/fmtlib/include
../../../../intern/guardedalloc
)
@ -23,37 +23,37 @@ set(INC_SYS
)
set(SRC
exporter/ply_export.cc
exporter/ply_export_data.cc
exporter/ply_export_header.cc
exporter/ply_export_load_plydata.cc
exporter/ply_export.cc
exporter/ply_file_buffer.cc
exporter/ply_file_buffer_ascii.cc
exporter/ply_file_buffer_binary.cc
exporter/ply_file_buffer.cc
importer/ply_import.cc
importer/ply_import_ascii.cc
importer/ply_import_binary.cc
importer/ply_import_mesh.cc
importer/ply_import.cc
IO_ply.cc
exporter/ply_export.hh
exporter/ply_export_data.hh
exporter/ply_export_header.hh
exporter/ply_export_load_plydata.hh
exporter/ply_export.hh
exporter/ply_file_buffer.hh
exporter/ply_file_buffer_ascii.hh
exporter/ply_file_buffer_binary.hh
exporter/ply_file_buffer.hh
importer/ply_import.hh
importer/ply_import_ascii.hh
importer/ply_import_binary.hh
importer/ply_import_mesh.hh
importer/ply_import.hh
IO_ply.h
intern/ply_data.hh
intern/ply_functions.hh
intern/ply_functions.cc
intern/ply_functions.hh
)
set(LIB

View File

@ -54,11 +54,11 @@ static void rotate_instances(GeoNodeExecParams &params, bke::Instances &instance
/* Create rotations around the individual axis. This could be optimized to skip some axis
* when the angle is zero. */
const float3x3 rotation_x = from_rotation<float3x3>(
AxisAngle(instance_transform.x_axis(), euler.x));
AxisAngle(normalize(instance_transform.x_axis()), euler.x));
const float3x3 rotation_y = from_rotation<float3x3>(
AxisAngle(instance_transform.y_axis(), euler.y));
AxisAngle(normalize(instance_transform.y_axis()), euler.y));
const float3x3 rotation_z = from_rotation<float3x3>(
AxisAngle(instance_transform.z_axis(), euler.z));
AxisAngle(normalize(instance_transform.z_axis()), euler.z));
/* Combine the previously computed rotations into the final rotation matrix. */
rotation_matrix = float4x4(rotation_z * rotation_y * rotation_x);

View File

@ -141,6 +141,7 @@ dict_custom = {
"instantiable",
"instantiation",
"instantiations",
"interdependencies",
"interferences",
"interocular",
"invariant",