Compare commits

..

6 Commits

Author SHA1 Message Date
b25697b884 cleanup and fix 2021-09-15 13:51:49 +02:00
608c4d40a1 cleanup 2021-09-15 14:33:10 +02:00
d021d633ff cleanup 2021-09-15 13:54:04 +02:00
0c2c2af0aa update remaining node 2021-09-15 13:37:57 +02:00
2ffa956983 cleanup 2021-09-15 13:19:36 +02:00
19d2f7d9cf separate declaration from buildrs 2021-09-15 12:43:49 +02:00
80 changed files with 252 additions and 788 deletions

View File

@@ -1708,42 +1708,16 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
double dx;
double dy;
/* trying to pretend you have nice scrolls... */
dx = [event deltaX];
dy = [event deltaY];
if ((dx == 0) && (dy == 0))
break;
/* with 10.7 nice scrolling deltas are supported */
dx = [event scrollingDeltaX];
dy = [event scrollingDeltaY];
const double deltaMax = 50.0;
/* Quadratic acceleration */
dx = dx * (fabs(dx) + 0.5);
if (dx < 0.0) {
dx -= 0.5;
/* However, Wacom tablet (intuos5) needs old deltas,
* it then has momentum and phase at zero. */
if (phase == NSEventPhaseNone && momentumPhase == NSEventPhaseNone) {
dx = [event deltaX];
dy = [event deltaY];
}
else {
dx += 0.5;
}
if (dx < -deltaMax) {
dx = -deltaMax;
}
else if (dx > deltaMax) {
dx = deltaMax;
}
dy = dy * (fabs(dy) + 0.5);
if (dy < 0.0) {
dy -= 0.5;
}
else {
dy += 0.5;
}
if (dy < -deltaMax) {
dy = -deltaMax;
}
else if (dy > deltaMax) {
dy = deltaMax;
}
window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
NSPoint delta = [[cocoawindow contentView] convertPointToBacking:NSMakePoint(dx, dy)];

View File

@@ -85,9 +85,9 @@ class ASSET_OT_open_containing_blend_file(Operator):
@classmethod
def poll(cls, context):
asset_file_handle = getattr(context, 'asset_file_handle', None)
asset_library_ref = getattr(context, 'asset_library_ref', None)
asset_library = getattr(context, 'asset_library', None)
if not asset_library_ref:
if not asset_library:
cls.poll_message_set("No asset library selected")
return False
if not asset_file_handle:
@@ -100,13 +100,13 @@ class ASSET_OT_open_containing_blend_file(Operator):
def execute(self, context):
asset_file_handle = context.asset_file_handle
asset_library_ref = context.asset_library_ref
asset_library = context.asset_library
if asset_file_handle.local_id:
self.report({'WARNING'}, "This asset is stored in the current blend file")
return {'CANCELLED'}
asset_lib_path = bpy.types.AssetHandle.get_full_library_path(asset_file_handle, asset_library_ref)
asset_lib_path = bpy.types.AssetHandle.get_full_library_path(asset_file_handle, asset_library)
self.open_in_new_blender(asset_lib_path)
wm = context.window_manager

View File

@@ -564,8 +564,6 @@ geometry_node_categories = [
NodeItem("GeometryNodeLegacyMaterialAssign", poll=geometry_nodes_fields_legacy_poll),
NodeItem("GeometryNodeLegacySelectByMaterial", poll=geometry_nodes_fields_legacy_poll),
NodeItem("GeometryNodeMaterialAssign", poll=geometry_nodes_fields_poll),
NodeItem("GeometryNodeMaterialSelection", poll=geometry_nodes_fields_poll),
NodeItem("GeometryNodeMaterialReplace"),
]),
GeometryNodeCategory("GEO_MESH", "Mesh", items=[

View File

@@ -1491,8 +1491,6 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
#define GEO_NODE_INPUT_INDEX 1078
#define GEO_NODE_INPUT_NORMAL 1079
#define GEO_NODE_ATTRIBUTE_CAPTURE 1080
#define GEO_NODE_MATERIAL_SELECTION 1081
#define GEO_NODE_MATERIAL_ASSIGN 1082
/** \} */

View File

@@ -130,11 +130,6 @@ class Spline {
virtual void translate(const blender::float3 &translation);
virtual void transform(const blender::float4x4 &matrix);
/**
* Change the direction of the spline (switch the start and end) without changing its shape.
*/
void reverse();
/**
* Mark all caches for re-computation. This must be called after any operation that would
* change the generated positions, tangents, normals, mapping, etc. of the evaluated points.
@@ -215,7 +210,6 @@ class Spline {
virtual void correct_end_tangents() const = 0;
virtual void copy_settings(Spline &dst) const = 0;
virtual void copy_data(Spline &dst) const = 0;
virtual void reverse_impl() = 0;
};
/**
@@ -359,9 +353,6 @@ class BezierSpline final : public Spline {
void correct_end_tangents() const final;
void copy_settings(Spline &dst) const final;
void copy_data(Spline &dst) const final;
protected:
void reverse_impl() override;
};
/**
@@ -478,7 +469,6 @@ class NURBSpline final : public Spline {
void correct_end_tangents() const final;
void copy_settings(Spline &dst) const final;
void copy_data(Spline &dst) const final;
void reverse_impl() override;
void calculate_knots() const;
blender::Span<BasisCache> calculate_basis_cache() const;
@@ -529,7 +519,6 @@ class PolySpline final : public Spline {
void correct_end_tangents() const final;
void copy_settings(Spline &dst) const final;
void copy_data(Spline &dst) const final;
void reverse_impl() override;
};
/**

View File

@@ -2064,7 +2064,7 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *
}
if (update_normals) {
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
}
/* make a copy of mesh to use as brush data */

View File

@@ -3573,7 +3573,7 @@ static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obje
}
BKE_mesh_calc_edges(result, false, false);
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
return result;
}

View File

@@ -222,37 +222,6 @@ static void adapt_curve_domain_point_to_spline_impl(const CurveEval &curve,
mixer.finalize();
}
/**
* A spline is selected if all of its control points were selected.
*
* \note Theoretically this interpolation does not need to compute all values at once.
* However, doing that makes the implementation simpler, and this can be optimized in the future if
* only some values are required.
*/
template<>
void adapt_curve_domain_point_to_spline_impl(const CurveEval &curve,
const VArray<bool> &old_values,
MutableSpan<bool> r_values)
{
const int splines_len = curve.splines().size();
Array<int> offsets = curve.control_point_offsets();
BLI_assert(r_values.size() == splines_len);
r_values.fill(true);
for (const int i_spline : IndexRange(splines_len)) {
const int spline_offset = offsets[i_spline];
const int spline_point_len = offsets[i_spline + 1] - spline_offset;
for (const int i_point : IndexRange(spline_point_len)) {
if (!old_values[spline_offset + i_point]) {
r_values[i_spline] = false;
break;
}
}
}
}
static GVArrayPtr adapt_curve_domain_point_to_spline(const CurveEval &curve, GVArrayPtr varray)
{
GVArrayPtr new_varray;

View File

@@ -175,34 +175,6 @@ static void adapt_mesh_domain_corner_to_point_impl(const Mesh &mesh,
mixer.finalize();
}
/* A vertex is selected if all connected face corners were selected and it is not loose. */
template<>
void adapt_mesh_domain_corner_to_point_impl(const Mesh &mesh,
const VArray<bool> &old_values,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totvert);
Array<bool> loose_verts(mesh.totvert, true);
r_values.fill(true);
for (const int loop_index : IndexRange(mesh.totloop)) {
const MLoop &loop = mesh.mloop[loop_index];
const int point_index = loop.v;
loose_verts[point_index] = false;
if (!old_values[loop_index]) {
r_values[point_index] = false;
}
}
/* Deselect loose vertices without corners that are still selected from the 'true' default. */
for (const int vert_index : IndexRange(mesh.totvert)) {
if (loose_verts[vert_index]) {
r_values[vert_index] = false;
}
}
}
static GVArrayPtr adapt_mesh_domain_corner_to_point(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
@@ -219,13 +191,6 @@ static GVArrayPtr adapt_mesh_domain_corner_to_point(const Mesh &mesh, GVArrayPtr
return new_varray;
}
/**
* Each corner's value is simply a copy of the value at its vertex.
*
* \note Theoretically this interpolation does not need to compute all values at once.
* However, doing that makes the implementation simpler, and this can be optimized in the future if
* only some values are required.
*/
template<typename T>
static void adapt_mesh_domain_point_to_corner_impl(const Mesh &mesh,
const VArray<T> &old_values,
@@ -244,6 +209,10 @@ static GVArrayPtr adapt_mesh_domain_point_to_corner(const Mesh &mesh, GVArrayPtr
GVArrayPtr new_varray;
attribute_math::convert_to_static_type(varray->type(), [&](auto dummy) {
using T = decltype(dummy);
/* It is not strictly necessary to compute the value for all corners here. Instead one could
* lazily lookup the mesh topology when a specific index accessed. This can be more efficient
* when an algorithm only accesses very few of the corner values. However, for the algorithms
* we currently have, precomputing the array is fine. Also, it is easier to implement. */
Array<T> values(mesh.totloop);
adapt_mesh_domain_point_to_corner_impl<T>(mesh, varray->typed<T>(), values);
new_varray = std::make_unique<fn::GVArray_For_ArrayContainer<Array<T>>>(std::move(values));
@@ -275,26 +244,6 @@ static void adapt_mesh_domain_corner_to_face_impl(const Mesh &mesh,
mixer.finalize();
}
/* A face is selected if all of its corners were selected. */
template<>
void adapt_mesh_domain_corner_to_face_impl(const Mesh &mesh,
const VArray<bool> &old_values,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totpoly);
r_values.fill(true);
for (const int poly_index : IndexRange(mesh.totpoly)) {
const MPoly &poly = mesh.mpoly[poly_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
if (!old_values[loop_index]) {
r_values[poly_index] = false;
break;
}
}
}
}
static GVArrayPtr adapt_mesh_domain_corner_to_face(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
@@ -333,41 +282,6 @@ static void adapt_mesh_domain_corner_to_edge_impl(const Mesh &mesh,
mixer.finalize();
}
/* An edge is selected if all corners on adjacent faces were selected. */
template<>
void adapt_mesh_domain_corner_to_edge_impl(const Mesh &mesh,
const VArray<bool> &old_values,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totedge);
/* It may be possible to rely on the #ME_LOOSEEDGE flag, but that seems error-prone. */
Array<bool> loose_edges(mesh.totedge, true);
r_values.fill(true);
for (const int poly_index : IndexRange(mesh.totpoly)) {
const MPoly &poly = mesh.mpoly[poly_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const int loop_index_next = (loop_index == poly.totloop) ? poly.loopstart : (loop_index + 1);
const MLoop &loop = mesh.mloop[loop_index];
const int edge_index = loop.e;
loose_edges[edge_index] = false;
if (!old_values[loop_index] || !old_values[loop_index_next]) {
r_values[edge_index] = false;
}
}
}
/* Deselect loose edges without corners that are still selected from the 'true' default. */
for (const int edge_index : IndexRange(mesh.totedge)) {
if (loose_edges[edge_index]) {
r_values[edge_index] = false;
}
}
}
static GVArrayPtr adapt_mesh_domain_corner_to_edge(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
@@ -403,27 +317,6 @@ void adapt_mesh_domain_face_to_point_impl(const Mesh &mesh,
mixer.finalize();
}
/* A vertex is selected if any of the connected faces were selected. */
template<>
void adapt_mesh_domain_face_to_point_impl(const Mesh &mesh,
const VArray<bool> &old_values,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totvert);
r_values.fill(false);
for (const int poly_index : IndexRange(mesh.totpoly)) {
const MPoly &poly = mesh.mpoly[poly_index];
if (old_values[poly_index]) {
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const MLoop &loop = mesh.mloop[loop_index];
const int vert_index = loop.v;
r_values[vert_index] = true;
}
}
}
}
static GVArrayPtr adapt_mesh_domain_face_to_point(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
@@ -438,7 +331,6 @@ static GVArrayPtr adapt_mesh_domain_face_to_point(const Mesh &mesh, GVArrayPtr v
return new_varray;
}
/* Each corner's value is simply a copy of the value at its face. */
template<typename T>
void adapt_mesh_domain_face_to_corner_impl(const Mesh &mesh,
const VArray<T> &old_values,
@@ -486,27 +378,6 @@ void adapt_mesh_domain_face_to_edge_impl(const Mesh &mesh,
mixer.finalize();
}
/* An edge is selected if any connected face was selected. */
template<>
void adapt_mesh_domain_face_to_edge_impl(const Mesh &mesh,
const VArray<bool> &old_values,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totedge);
r_values.fill(false);
for (const int poly_index : IndexRange(mesh.totpoly)) {
const MPoly &poly = mesh.mpoly[poly_index];
if (old_values[poly_index]) {
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const MLoop &loop = mesh.mloop[loop_index];
const int edge_index = loop.e;
r_values[edge_index] = true;
}
}
}
}
static GVArrayPtr adapt_mesh_domain_face_to_edge(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
@@ -545,28 +416,6 @@ static void adapt_mesh_domain_point_to_face_impl(const Mesh &mesh,
mixer.finalize();
}
/* A face is selected if all of its vertices were selected too. */
template<>
void adapt_mesh_domain_point_to_face_impl(const Mesh &mesh,
const VArray<bool> &old_values,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totpoly);
r_values.fill(true);
for (const int poly_index : IndexRange(mesh.totpoly)) {
const MPoly &poly = mesh.mpoly[poly_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
MLoop &loop = mesh.mloop[loop_index];
const int vert_index = loop.v;
if (!old_values[vert_index]) {
r_values[poly_index] = false;
break;
}
}
}
}
static GVArrayPtr adapt_mesh_domain_point_to_face(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
@@ -603,20 +452,6 @@ static void adapt_mesh_domain_point_to_edge_impl(const Mesh &mesh,
mixer.finalize();
}
/* An edge is selected if both of its vertices were selected. */
template<>
void adapt_mesh_domain_point_to_edge_impl(const Mesh &mesh,
const VArray<bool> &old_values,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totedge);
for (const int edge_index : IndexRange(mesh.totedge)) {
const MEdge &edge = mesh.medge[edge_index];
r_values[edge_index] = old_values[edge.v1] && old_values[edge.v2];
}
}
static GVArrayPtr adapt_mesh_domain_point_to_edge(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
@@ -655,29 +490,6 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh,
mixer.finalize();
}
/* A corner is selected if its two adjacent edges were selected. */
template<>
void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh,
const VArray<bool> &old_values,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totloop);
r_values.fill(false);
for (const int poly_index : IndexRange(mesh.totpoly)) {
const MPoly &poly = mesh.mpoly[poly_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const int loop_index_prev = loop_index - 1 + (loop_index == poly.loopstart) * poly.totloop;
const MLoop &loop = mesh.mloop[loop_index];
const MLoop &loop_prev = mesh.mloop[loop_index_prev];
if (old_values[loop.e] && old_values[loop_prev.e]) {
r_values[loop_index] = true;
}
}
}
}
static GVArrayPtr adapt_mesh_domain_edge_to_corner(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
@@ -710,24 +522,6 @@ static void adapt_mesh_domain_edge_to_point_impl(const Mesh &mesh,
mixer.finalize();
}
/* A vertex is selected if any connected edge was selected. */
template<>
void adapt_mesh_domain_edge_to_point_impl(const Mesh &mesh,
const VArray<bool> &old_values,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totvert);
r_values.fill(false);
for (const int edge_index : IndexRange(mesh.totedge)) {
const MEdge &edge = mesh.medge[edge_index];
if (old_values[edge_index]) {
r_values[edge.v1] = true;
r_values[edge.v2] = true;
}
}
}
static GVArrayPtr adapt_mesh_domain_edge_to_point(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
@@ -766,28 +560,6 @@ static void adapt_mesh_domain_edge_to_face_impl(const Mesh &mesh,
mixer.finalize();
}
/* A face is selected if all of its edges are selected. */
template<>
void adapt_mesh_domain_edge_to_face_impl(const Mesh &mesh,
const VArray<bool> &old_values,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totpoly);
r_values.fill(true);
for (const int poly_index : IndexRange(mesh.totpoly)) {
const MPoly &poly = mesh.mpoly[poly_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const MLoop &loop = mesh.mloop[loop_index];
const int edge_index = loop.e;
if (!old_values[edge_index]) {
r_values[poly_index] = false;
break;
}
}
}
}
static GVArrayPtr adapt_mesh_domain_edge_to_face(const Mesh &mesh, GVArrayPtr varray)
{
GVArrayPtr new_varray;
@@ -926,7 +698,7 @@ static void tag_normals_dirty_when_writing_position(GeometryComponent &component
{
Mesh *mesh = get_mesh_from_component_for_write(component);
if (mesh != nullptr) {
BKE_mesh_normals_tag_dirty(mesh);
mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
}

View File

@@ -1859,7 +1859,7 @@ void BKE_mesh_vert_coords_apply(Mesh *mesh, const float (*vert_coords)[3])
for (int i = 0; i < mesh->totvert; i++, mv++) {
copy_v3_v3(mv->co, vert_coords[i]);
}
BKE_mesh_normals_tag_dirty(mesh);
mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
void BKE_mesh_vert_coords_apply_with_mat4(Mesh *mesh,
@@ -1872,7 +1872,7 @@ void BKE_mesh_vert_coords_apply_with_mat4(Mesh *mesh,
for (int i = 0; i < mesh->totvert; i++, mv++) {
mul_v3_m4v3(mv->co, mat, vert_coords[i]);
}
BKE_mesh_normals_tag_dirty(mesh);
mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
void BKE_mesh_vert_normals_apply(Mesh *mesh, const short (*vert_normals)[3])

View File

@@ -525,7 +525,7 @@ Mesh *BKE_mesh_new_nomain_from_curve_displist(const Object *ob, const ListBase *
}
mesh = BKE_mesh_new_nomain(totvert, totedge, 0, totloop, totpoly);
BKE_mesh_normals_tag_dirty(mesh);
mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
if (totvert != 0) {
memcpy(mesh->mvert, allvert, totvert * sizeof(MVert));

View File

@@ -5153,9 +5153,6 @@ static void registerGeometryNodes()
{
register_node_type_geo_group();
register_node_type_geo_legacy_material_assign();
register_node_type_geo_legacy_select_by_material();
register_node_type_geo_align_rotation_to_vector();
register_node_type_geo_attribute_clamp();
register_node_type_geo_attribute_color_ramp();
@@ -5228,7 +5225,7 @@ static void registerGeometryNodes()
register_node_type_geo_raycast();
register_node_type_geo_sample_texture();
register_node_type_geo_select_by_handle_type();
register_node_type_geo_material_selection();
register_node_type_geo_select_by_material();
register_node_type_geo_separate_components();
register_node_type_geo_set_position();
register_node_type_geo_subdivision_surface();

View File

@@ -312,7 +312,7 @@ IDTypeInfo IDType_ID_SCR = {
.name = "Screen",
.name_plural = "screens",
.translation_context = BLT_I18NCONTEXT_ID_SCREEN,
.flags = IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_NO_ANIMDATA,
.flags = IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_NO_MAKELOCAL | IDTYPE_FLAGS_NO_ANIMDATA,
.init_data = NULL,
.copy_data = NULL,

View File

@@ -19,8 +19,6 @@
#include "BLI_task.hh"
#include "BLI_timeit.hh"
#include "BKE_attribute_access.hh"
#include "BKE_attribute_math.hh"
#include "BKE_spline.hh"
#include "FN_generic_virtual_array.hh"
@@ -30,8 +28,6 @@ using blender::float3;
using blender::IndexRange;
using blender::MutableSpan;
using blender::Span;
using blender::attribute_math::convert_to_static_type;
using blender::bke::AttributeIDRef;
using blender::fn::GMutableSpan;
using blender::fn::GSpan;
using blender::fn::GVArray;
@@ -114,31 +110,6 @@ void Spline::transform(const blender::float4x4 &matrix)
this->mark_cache_invalid();
}
void Spline::reverse()
{
this->positions().reverse();
this->radii().reverse();
this->tilts().reverse();
this->attributes.foreach_attribute(
[&](const AttributeIDRef &id, const AttributeMetaData &meta_data) {
std::optional<blender::fn::GMutableSpan> attribute = this->attributes.get_for_write(id);
if (!attribute) {
BLI_assert_unreachable();
return false;
}
convert_to_static_type(meta_data.data_type, [&](auto dummy) {
using T = decltype(dummy);
attribute->typed<T>().reverse();
});
return true;
},
ATTR_DOMAIN_POINT);
this->reverse_impl();
this->mark_cache_invalid();
}
int Spline::evaluated_edges_size() const
{
const int eval_size = this->evaluated_points_size();

View File

@@ -166,17 +166,6 @@ MutableSpan<float3> BezierSpline::handle_positions_right()
return handle_positions_right_;
}
void BezierSpline::reverse_impl()
{
this->handle_positions_left().reverse();
this->handle_positions_right().reverse();
std::swap(this->handle_positions_left_, this->handle_positions_right_);
this->handle_types_left().reverse();
this->handle_types_right().reverse();
std::swap(this->handle_types_left_, this->handle_types_right_);
}
static float3 previous_position(Span<float3> positions, const bool cyclic, const int i)
{
if (i == 0) {

View File

@@ -142,11 +142,6 @@ Span<float> NURBSpline::weights() const
return weights_;
}
void NURBSpline::reverse_impl()
{
this->weights().reverse();
}
void NURBSpline::mark_cache_invalid()
{
basis_cache_dirty_ = true;

View File

@@ -91,10 +91,6 @@ Span<float> PolySpline::tilts() const
return tilts_;
}
void PolySpline::reverse_impl()
{
}
void PolySpline::mark_cache_invalid()
{
tangent_cache_dirty_ = true;

View File

@@ -1232,7 +1232,7 @@ Mesh *BKE_subdiv_to_mesh(Subdiv *subdiv,
// BKE_mesh_validate(result, true, true);
BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH);
if (!subdiv_context.can_evaluate_normals) {
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
/* Free used memory. */
subdiv_mesh_context_free(&subdiv_context);

View File

@@ -186,7 +186,7 @@ IDTypeInfo IDType_ID_WS = {
.name = "WorkSpace",
.name_plural = "workspaces",
.translation_context = BLT_I18NCONTEXT_ID_WORKSPACE,
.flags = IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_NO_ANIMDATA,
.flags = IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_NO_MAKELOCAL | IDTYPE_FLAGS_NO_ANIMDATA,
.init_data = workspace_init_data,
.copy_data = NULL,

View File

@@ -643,16 +643,6 @@ template<typename T> class MutableSpan {
return MutableSpan(data_ + size_ - new_size, new_size);
}
/**
* Reverse the data in the MutableSpan.
*/
constexpr void reverse()
{
for (const int i : IndexRange(size_ / 2)) {
std::swap(data_[size_ - 1 - i], data_[i]);
}
}
/**
* Returns an (immutable) Span that references the same array. This is usually not needed,
* due to implicit conversions. However, sometimes automatic type deduction needs some help.

View File

@@ -362,29 +362,6 @@ TEST(span, ReverseIterator)
EXPECT_EQ_ARRAY(reversed_vec.data(), Span({7, 6, 5, 4}).data(), 4);
}
TEST(span, ReverseMutableSpan)
{
std::array<int, 0> src0 = {};
MutableSpan<int> span0 = src0;
span0.reverse();
EXPECT_EQ_ARRAY(span0.data(), Span<int>({}).data(), 0);
std::array<int, 1> src1 = {4};
MutableSpan<int> span1 = src1;
span1.reverse();
EXPECT_EQ_ARRAY(span1.data(), Span<int>({4}).data(), 1);
std::array<int, 2> src2 = {4, 5};
MutableSpan<int> span2 = src2;
span2.reverse();
EXPECT_EQ_ARRAY(span2.data(), Span<int>({5, 4}).data(), 2);
std::array<int, 5> src5 = {4, 5, 6, 7, 8};
MutableSpan<int> span5 = src5;
span5.reverse();
EXPECT_EQ_ARRAY(span5.data(), Span<int>({8, 7, 6, 5, 4}).data(), 5);
}
TEST(span, MutableReverseIterator)
{
std::array<int, 4> src = {4, 5, 6, 7};

View File

@@ -97,6 +97,7 @@ typedef struct {
int launch_event;
float mcenter[2];
void *draw_handle_pixel;
short gizmo_flag;
short value_mode; /* Which value does mouse movement and numeric input affect? */
float segments; /* Segments as float so smooth mouse pan works in small increments */
@@ -306,6 +307,11 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
opdata->draw_handle_pixel = ED_region_draw_cb_activate(
region->type, ED_region_draw_mouse_line_cb, opdata->mcenter, REGION_DRAW_POST_PIXEL);
G.moving = G_TRANSFORM_EDIT;
if (v3d) {
opdata->gizmo_flag = v3d->gizmo_flag;
v3d->gizmo_flag |= V3D_GIZMO_HIDE_DEFAULT_MODAL;
}
}
return true;
@@ -427,11 +433,15 @@ static void edbm_bevel_exit(bContext *C, wmOperator *op)
}
if (opdata->is_modal) {
View3D *v3d = CTX_wm_view3d(C);
ARegion *region = CTX_wm_region(C);
for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
EDBM_redo_state_free(&opdata->ob_store[ob_index].mesh_backup);
}
ED_region_draw_cb_exit(region->type, opdata->draw_handle_pixel);
if (v3d) {
v3d->gizmo_flag = opdata->gizmo_flag;
}
G.moving = 0;
}
MEM_SAFE_FREE(opdata->ob_store);

View File

@@ -72,6 +72,7 @@ typedef struct {
bool is_dirty;
} * backup;
int backup_len;
short gizmo_flag;
} BisectData;
static void mesh_bisect_interactive_calc(bContext *C,
@@ -156,6 +157,8 @@ static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
if (ret & OPERATOR_RUNNING_MODAL) {
View3D *v3d = CTX_wm_view3d(C);
wmGesture *gesture = op->customdata;
BisectData *opdata;
@@ -178,6 +181,8 @@ static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* Misc other vars. */
G.moving = G_TRANSFORM_EDIT;
opdata->gizmo_flag = v3d->gizmo_flag;
v3d->gizmo_flag |= V3D_GIZMO_HIDE_DEFAULT_MODAL;
/* Initialize modal callout. */
ED_workspace_status_text(C, TIP_("LMB: Click and drag to draw cut line"));
@@ -186,8 +191,10 @@ static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return ret;
}
static void edbm_bisect_exit(BisectData *opdata)
static void edbm_bisect_exit(bContext *C, BisectData *opdata)
{
View3D *v3d = CTX_wm_view3d(C);
v3d->gizmo_flag = opdata->gizmo_flag;
G.moving = 0;
for (int ob_index = 0; ob_index < opdata->backup_len; ob_index++) {
@@ -218,7 +225,7 @@ static int mesh_bisect_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
if (ret & (OPERATOR_FINISHED | OPERATOR_CANCELLED)) {
edbm_bisect_exit(&opdata_back);
edbm_bisect_exit(C, &opdata_back);
#ifdef USE_GIZMO
/* Setup gizmos */

View File

@@ -76,6 +76,7 @@ typedef struct {
int launch_event;
float mcenter[2];
void *draw_handle_pixel;
short gizmo_flag;
} InsetData;
static void edbm_inset_update_header(wmOperator *op, bContext *C)
@@ -176,6 +177,7 @@ static bool edbm_inset_init(bContext *C, wmOperator *op, const bool is_modal)
opdata->num_input.unit_type[1] = B_UNIT_LENGTH;
if (is_modal) {
View3D *v3d = CTX_wm_view3d(C);
ARegion *region = CTX_wm_region(C);
for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
@@ -187,6 +189,10 @@ static bool edbm_inset_init(bContext *C, wmOperator *op, const bool is_modal)
opdata->draw_handle_pixel = ED_region_draw_cb_activate(
region->type, ED_region_draw_mouse_line_cb, opdata->mcenter, REGION_DRAW_POST_PIXEL);
G.moving = G_TRANSFORM_EDIT;
if (v3d) {
opdata->gizmo_flag = v3d->gizmo_flag;
v3d->gizmo_flag |= V3D_GIZMO_HIDE_DEFAULT_MODAL;
}
}
return true;
@@ -200,11 +206,15 @@ static void edbm_inset_exit(bContext *C, wmOperator *op)
opdata = op->customdata;
if (opdata->is_modal) {
View3D *v3d = CTX_wm_view3d(C);
ARegion *region = CTX_wm_region(C);
for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
EDBM_redo_state_free(&opdata->ob_store[ob_index].mesh_backup);
}
ED_region_draw_cb_exit(region->type, opdata->draw_handle_pixel);
if (v3d) {
v3d->gizmo_flag = opdata->gizmo_flag;
}
G.moving = 0;
}

View File

@@ -1300,7 +1300,7 @@ static void sculpt_gesture_apply_trim(SculptGestureContext *sgcontext)
}),
sculpt_mesh);
BM_mesh_free(bm);
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
BKE_mesh_nomain_to_mesh(
result, sgcontext->vc.obact->data, sgcontext->vc.obact, &CD_MASK_MESH, true);
}

View File

@@ -461,7 +461,7 @@ static void IMAGE_GGT_gizmo2d(wmGizmoGroupType *gzgt)
gzgt->name = "UV Transform Gizmo";
gzgt->idname = "IMAGE_GGT_gizmo2d";
gzgt->flag |= (WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE | WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP |
gzgt->flag |= (WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP |
WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK);
gzgt->gzmap_params.spaceid = SPACE_IMAGE;
@@ -475,7 +475,7 @@ static void IMAGE_GGT_gizmo2d_translate(wmGizmoGroupType *gzgt)
gzgt->name = "UV Translate Gizmo";
gzgt->idname = "IMAGE_GGT_gizmo2d_translate";
gzgt->flag |= (WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE | WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP |
gzgt->flag |= (WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP |
WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK);
gzgt->gzmap_params.spaceid = SPACE_IMAGE;
@@ -489,7 +489,7 @@ static void IMAGE_GGT_gizmo2d_resize(wmGizmoGroupType *gzgt)
gzgt->name = "UV Transform Gizmo Resize";
gzgt->idname = "IMAGE_GGT_gizmo2d_resize";
gzgt->flag |= (WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE | WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP |
gzgt->flag |= (WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP |
WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK);
gzgt->gzmap_params.spaceid = SPACE_IMAGE;
@@ -503,7 +503,7 @@ static void IMAGE_GGT_gizmo2d_rotate(wmGizmoGroupType *gzgt)
gzgt->name = "UV Transform Gizmo Resize";
gzgt->idname = "IMAGE_GGT_gizmo2d_rotate";
gzgt->flag |= (WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE | WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP |
gzgt->flag |= (WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP |
WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK);
gzgt->gzmap_params.spaceid = SPACE_IMAGE;

View File

@@ -618,6 +618,9 @@ typedef struct TransInfo {
O_SET,
} orient_curr;
/** backup from view3d, to restore on end. */
short gizmo_flag;
short prop_mode;
/** Value taken as input, either through mouse coordinates or entered as a parameter. */

View File

@@ -249,6 +249,12 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->view = v3d;
t->animtimer = (animscreen) ? animscreen->animtimer : NULL;
/* turn gizmo off during transform */
if (t->flag & T_MODAL) {
t->gizmo_flag = v3d->gizmo_flag;
v3d->gizmo_flag |= V3D_GIZMO_HIDE_DEFAULT_MODAL;
}
if (t->scene->toolsettings->transform_flag & SCE_XFORM_AXIS_ALIGN) {
t->flag |= T_V3D_ALIGN;
}
@@ -736,6 +742,13 @@ void postTrans(bContext *C, TransInfo *t)
}
}
}
else if (t->spacetype == SPACE_VIEW3D) {
View3D *v3d = t->area->spacedata.first;
/* restore gizmo */
if (t->flag & T_MODAL) {
v3d->gizmo_flag = t->gizmo_flag;
}
}
if (t->mouse.data) {
MEM_freeN(t->mouse.data);

View File

@@ -1974,8 +1974,8 @@ void VIEW3D_GGT_xform_gizmo(wmGizmoGroupType *gzgt)
gzgt->name = "3D View: Transform Gizmo";
gzgt->idname = "VIEW3D_GGT_xform_gizmo";
gzgt->flag = WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE |
WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK;
gzgt->flag = WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP |
WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK;
gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
@@ -2216,8 +2216,8 @@ void VIEW3D_GGT_xform_cage(wmGizmoGroupType *gzgt)
gzgt->name = "Transform Cage";
gzgt->idname = "VIEW3D_GGT_xform_cage";
gzgt->flag |= WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE |
WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK;
gzgt->flag |= WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP |
WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK;
gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
@@ -2459,8 +2459,8 @@ void VIEW3D_GGT_xform_shear(wmGizmoGroupType *gzgt)
gzgt->name = "Transform Shear";
gzgt->idname = "VIEW3D_GGT_xform_shear";
gzgt->flag |= WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE |
WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK;
gzgt->flag |= WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP |
WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK;
gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;

View File

@@ -108,6 +108,27 @@ static void applyLength(LengthGpencilModifierData *lmd, bGPdata *gpd, bGPDstroke
}
}
static void bakeModifier(Main *UNUSED(bmain),
Depsgraph *UNUSED(depsgraph),
GpencilModifierData *md,
Object *ob)
{
bGPdata *gpd = ob->data;
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
LengthGpencilModifierData *lmd = (LengthGpencilModifierData *)md;
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
applyLength(lmd, gpd, gps);
}
}
}
}
/* -------------------------------- */
/* Generic "generateStrokes" callback */
static void deformStroke(GpencilModifierData *md,
Depsgraph *UNUSED(depsgraph),
Object *ob,
@@ -133,23 +154,6 @@ static void deformStroke(GpencilModifierData *md,
}
}
static void bakeModifier(Main *UNUSED(bmain),
Depsgraph *depsgraph,
GpencilModifierData *md,
Object *ob)
{
bGPdata *gpd = ob->data;
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
deformStroke(md, depsgraph, ob, gpl, gpf, gps);
}
}
}
}
static void foreachIDLink(GpencilModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
LengthGpencilModifierData *mmd = (LengthGpencilModifierData *)md;

View File

@@ -610,6 +610,14 @@ enum {
V3D_GIZMO_HIDE_TOOL = (1 << 3),
};
/**
* Hide these gizmos when modal operators are active,
* the intention is to hide all gizmos except for navigation since from a user-perspective
* these are closer to UI-level interface elements. Hiding them makes the UI flicker, also,
* the 3D view-axis can be useful to see during interactions.
*/
#define V3D_GIZMO_HIDE_DEFAULT_MODAL (V3D_GIZMO_HIDE_CONTEXT | V3D_GIZMO_HIDE_TOOL)
/** #View3d.gizmo_show_object */
enum {
V3D_GIZMO_SHOW_OBJECT_TRANSLATE = (1 << 0),

View File

@@ -1402,11 +1402,6 @@ static void rna_def_gizmogroup(BlenderRNA *brna)
0,
"Show Modal All",
"Show all while interacting, as well as this group when another is being interacted with"},
{WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE,
"EXCLUDE_MODAL",
0,
"Exclude Modal",
"Show all except this group while interacting"},
{WM_GIZMOGROUPTYPE_TOOL_INIT,
"TOOL_INIT",
0,

View File

@@ -786,7 +786,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
* TODO: we may need to set other dirty flags as well?
*/
if (use_recalc_normals) {
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
if (vgroup_start_cap_remap) {

View File

@@ -243,7 +243,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
BM_mesh_free(bm);
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
return result;
}

View File

@@ -161,7 +161,7 @@ static Mesh *get_quick_mesh(
mul_m4_v3(omat, mv->co);
}
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
break;
@@ -506,7 +506,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
result = BKE_mesh_from_bmesh_for_eval_nomain(bm, nullptr, mesh);
BM_mesh_free(bm);
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
if (result == nullptr) {
@@ -541,7 +541,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
result = BKE_mesh_from_bmesh_for_eval_nomain(bm, nullptr, mesh);
BM_mesh_free(bm);
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
}
}

View File

@@ -281,7 +281,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct
MEM_freeN(faceMap);
if (mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) {
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
/* TODO(sybren): also copy flags & tags? */

View File

@@ -222,7 +222,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
TIMEIT_END(decim);
#endif
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
return result;
}

View File

@@ -115,7 +115,7 @@ Mesh *doEdgeSplit(const Mesh *mesh, EdgeSplitModifierData *emd)
result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
BM_mesh_free(bm);
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
return result;
}

View File

@@ -814,7 +814,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx)
}
BKE_mesh_calc_edges_loose(result);
BKE_mesh_normals_tag_dirty(result);
/* Tag to recalculate normals later. */
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
return result;
}

View File

@@ -117,7 +117,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
result = mirrorModifier__doMirror(mmd, ctx->object, mesh);
if (result != mesh) {
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
return result;
}

View File

@@ -450,7 +450,7 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd,
if (do_polynors_fix &&
polygons_check_flip(mloop, nos, &mesh->ldata, mpoly, polynors, num_polys)) {
BKE_mesh_normals_tag_dirty(mesh);
mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
BKE_mesh_normals_loop_custom_set(mvert,

View File

@@ -317,7 +317,7 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, co
}
}
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
return result;
}
@@ -510,7 +510,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
result = doOcean(md, ctx, mesh);
if (result != mesh) {
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
return result;

View File

@@ -545,7 +545,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
MEM_SAFE_FREE(vert_part_index);
MEM_SAFE_FREE(vert_part_value);
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
return result;
}

View File

@@ -220,7 +220,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx)
BKE_mesh_copy_parameters_for_eval(result, mesh);
BKE_mesh_calc_edges(result, true, false);
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
return result;
}

View File

@@ -1135,12 +1135,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
ob_axis != NULL ? mtx_tx[3] : NULL,
ltmd->merge_dist);
if (result != result_prev) {
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
}
if ((ltmd->flag & MOD_SCREW_NORMAL_CALC) == 0) {
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
return result;

View File

@@ -1960,7 +1960,7 @@ static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd, eSkinErrorFlag *r_
result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, origmesh);
BM_mesh_free(bm);
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
skin_set_orig_indices(result);

View File

@@ -988,7 +988,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
/* must recalculate normals with vgroups since they can displace unevenly T26888. */
if ((mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) || do_rim || dvert) {
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
else if (do_shell) {
uint i;

View File

@@ -1955,7 +1955,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
}
}
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
/* Make edges. */
{

View File

@@ -107,7 +107,7 @@ Mesh *triangulate_mesh(Mesh *mesh,
me->flag |= ME_EDGEDRAW | ME_EDGERENDER;
}
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
return result;
}

View File

@@ -216,6 +216,7 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob,
* we really need vertexCos here. */
else if (vertexCos) {
BKE_mesh_vert_coords_apply(mesh, vertexCos);
mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
if (use_orco) {

View File

@@ -1979,7 +1979,8 @@ static Mesh *weldModifier_doWeld(WeldModifierData *wmd,
BLI_assert(loop_cur == result_nloops);
/* is this needed? */
BKE_mesh_normals_tag_dirty(result);
/* recalculate normals */
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
weld_mesh_context_free(&weld_mesh);
}

View File

@@ -109,7 +109,7 @@ static Mesh *WireframeModifier_do(WireframeModifierData *wmd, Object *ob, Mesh *
result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
BM_mesh_free(bm);
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
return result;
}

View File

@@ -141,9 +141,6 @@ set(SRC
function/nodes/node_fn_random_float.cc
function/node_function_util.cc
geometry/nodes/legacy/node_geo_material_assign.cc
geometry/nodes/legacy/node_geo_select_by_material.cc
geometry/nodes/node_geo_align_rotation_to_vector.cc
geometry/nodes/node_geo_attribute_capture.cc
geometry/nodes/node_geo_attribute_clamp.cc
@@ -198,7 +195,6 @@ set(SRC
geometry/nodes/node_geo_join_geometry.cc
geometry/nodes/node_geo_material_assign.cc
geometry/nodes/node_geo_material_replace.cc
geometry/nodes/node_geo_material_selection.cc
geometry/nodes/node_geo_mesh_primitive_circle.cc
geometry/nodes/node_geo_mesh_primitive_cone.cc
geometry/nodes/node_geo_mesh_primitive_cube.cc
@@ -218,6 +214,7 @@ set(SRC
geometry/nodes/node_geo_point_translate.cc
geometry/nodes/node_geo_points_to_volume.cc
geometry/nodes/node_geo_raycast.cc
geometry/nodes/node_geo_select_by_material.cc
geometry/nodes/node_geo_separate_components.cc
geometry/nodes/node_geo_set_position.cc
geometry/nodes/node_geo_subdivision_surface.cc

View File

@@ -29,9 +29,6 @@ void register_node_tree_type_geo(void);
void register_node_type_geo_group(void);
void register_node_type_geo_custom_group(bNodeType *ntype);
void register_node_type_geo_legacy_material_assign(void);
void register_node_type_geo_legacy_select_by_material(void);
void register_node_type_geo_align_rotation_to_vector(void);
void register_node_type_geo_attribute_clamp(void);
void register_node_type_geo_attribute_color_ramp(void);
@@ -83,7 +80,6 @@ void register_node_type_geo_is_viewport(void);
void register_node_type_geo_join_geometry(void);
void register_node_type_geo_material_assign(void);
void register_node_type_geo_material_replace(void);
void register_node_type_geo_material_selection(void);
void register_node_type_geo_mesh_primitive_circle(void);
void register_node_type_geo_mesh_primitive_cone(void);
void register_node_type_geo_mesh_primitive_cube(void);
@@ -105,6 +101,7 @@ void register_node_type_geo_points_to_volume(void);
void register_node_type_geo_raycast(void);
void register_node_type_geo_sample_texture(void);
void register_node_type_geo_select_by_handle_type(void);
void register_node_type_geo_select_by_material(void);
void register_node_type_geo_separate_components(void);
void register_node_type_geo_set_position(void);
void register_node_type_geo_subdivision_surface(void);

View File

@@ -76,19 +76,19 @@ class SocketDeclarationBuilder : public BaseSocketDeclarationBuilder {
friend class NodeDeclarationBuilder;
public:
Self &hide_label(bool value = true)
Self &hide_label(bool value)
{
decl_->hide_label_ = value;
return *(Self *)this;
}
Self &hide_value(bool value = true)
Self &hide_value(bool value)
{
decl_->hide_value_ = value;
return *(Self *)this;
}
Self &multi_input(bool value = true)
Self &multi_input(bool value)
{
decl_->is_multi_input_ = value;
return *(Self *)this;

View File

@@ -332,9 +332,7 @@ DefNode(GeometryNode, GEO_NODE_INPUT_NORMAL, 0, "INPUT_NORMAL", InputNormal, "No
DefNode(GeometryNode, GEO_NODE_INPUT_POSITION, 0, "POSITION", InputPosition, "Position", "")
DefNode(GeometryNode, GEO_NODE_IS_VIEWPORT, 0, "IS_VIEWPORT", IsViewport, "Is Viewport", "")
DefNode(GeometryNode, GEO_NODE_JOIN_GEOMETRY, 0, "JOIN_GEOMETRY", JoinGeometry, "Join Geometry", "")
DefNode(GeometryNode, GEO_NODE_MATERIAL_ASSIGN, 0, "MATERIAL_ASSIGN", MaterialAssign, "Material Assign", "")
DefNode(GeometryNode, GEO_NODE_MATERIAL_REPLACE, 0, "MATERIAL_REPLACE", MaterialReplace, "Material Replace", "")
DefNode(GeometryNode, GEO_NODE_MATERIAL_SELECTION, 0, "MATERIAL_SELECTION", MaterialSelection, "Material Selection", "")
DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CIRCLE, def_geo_mesh_circle, "MESH_PRIMITIVE_CIRCLE", MeshCircle, "Mesh Circle", "")
DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CONE, def_geo_mesh_cone, "MESH_PRIMITIVE_CONE", MeshCone, "Cone", "")
DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CUBE, 0, "MESH_PRIMITIVE_CUBE", MeshCube, "Cube", "")

View File

@@ -1,95 +0,0 @@
/*
* 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 "node_geometry_util.hh"
#include "UI_interface.h"
#include "UI_resources.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BKE_material.h"
namespace blender::nodes {
static void geo_node_legacy_material_assign_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Geometry");
b.add_input<decl::Material>("Material").hide_label(true);
b.add_input<decl::String>("Selection");
b.add_output<decl::Geometry>("Geometry");
}
static void assign_material_to_faces(Mesh &mesh, const VArray<bool> &face_mask, Material *material)
{
int new_material_index = -1;
for (const int i : IndexRange(mesh.totcol)) {
Material *other_material = mesh.mat[i];
if (other_material == material) {
new_material_index = i;
break;
}
}
if (new_material_index == -1) {
/* Append a new material index. */
new_material_index = mesh.totcol;
BKE_id_material_eval_assign(&mesh.id, new_material_index + 1, material);
}
mesh.mpoly = (MPoly *)CustomData_duplicate_referenced_layer(&mesh.pdata, CD_MPOLY, mesh.totpoly);
for (const int i : IndexRange(mesh.totpoly)) {
if (face_mask[i]) {
MPoly &poly = mesh.mpoly[i];
poly.mat_nr = new_material_index;
}
}
}
static void geo_node_legacy_material_assign_exec(GeoNodeExecParams params)
{
Material *material = params.extract_input<Material *>("Material");
const std::string mask_name = params.extract_input<std::string>("Selection");
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
geometry_set = geometry_set_realize_instances(geometry_set);
if (geometry_set.has<MeshComponent>()) {
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
Mesh *mesh = mesh_component.get_for_write();
if (mesh != nullptr) {
GVArray_Typed<bool> face_mask = mesh_component.attribute_get_for_read<bool>(
mask_name, ATTR_DOMAIN_FACE, true);
assign_material_to_faces(*mesh, face_mask, material);
}
}
params.set_output("Geometry", std::move(geometry_set));
}
} // namespace blender::nodes
void register_node_type_geo_legacy_material_assign()
{
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_LEGACY_MATERIAL_ASSIGN, "Material Assign", NODE_CLASS_GEOMETRY, 0);
ntype.declare = blender::nodes::geo_node_legacy_material_assign_declare;
ntype.geometry_node_execute = blender::nodes::geo_node_legacy_material_assign_exec;
nodeRegisterType(&ntype);
}

View File

@@ -21,7 +21,7 @@ namespace blender::nodes {
static void geo_node_attribute_remove_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Geometry");
b.add_input<decl::String>("Attribute").multi_input();
b.add_input<decl::String>("Attribute").multi_input(true);
b.add_output<decl::Geometry>("Geometry");
}

View File

@@ -33,7 +33,7 @@ namespace blender::nodes {
static void geo_node_attribute_sample_texture_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Geometry");
b.add_input<decl::Texture>("Texture").hide_label();
b.add_input<decl::Texture>("Texture").hide_label(true);
b.add_input<decl::String>("Mapping");
b.add_input<decl::String>("Result");
b.add_output<decl::Geometry>("Geometry");

View File

@@ -27,7 +27,7 @@ static void geo_node_attribute_vector_rotate_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Geometry");
b.add_input<decl::String>("Vector");
b.add_input<decl::Vector>("Vector", "Vector_001").min(0.0f).max(1.0f).hide_value();
b.add_input<decl::Vector>("Vector", "Vector_001").min(0.0f).max(1.0f).hide_value(true);
b.add_input<decl::String>("Center");
b.add_input<decl::Vector>("Center", "Center_001").subtype(PROP_XYZ);
b.add_input<decl::String>("Axis");

View File

@@ -28,7 +28,7 @@ namespace blender::nodes {
static void geo_node_boolean_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Geometry 1");
b.add_input<decl::Geometry>("Geometry 2").multi_input();
b.add_input<decl::Geometry>("Geometry 2").multi_input(true);
b.add_input<decl::Bool>("Self Intersection");
b.add_input<decl::Bool>("Hole Tolerant");
b.add_output<decl::Geometry>("Geometry");

View File

@@ -27,7 +27,7 @@ namespace blender::nodes {
static void geo_node_collection_info_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Collection>("Collection").hide_label();
b.add_input<decl::Collection>("Collection").hide_label(true);
b.add_output<decl::Geometry>("Geometry");
}

View File

@@ -41,7 +41,7 @@ static std::unique_ptr<CurveEval> create_spiral_curve(const float rotations,
std::unique_ptr<CurveEval> curve = std::make_unique<CurveEval>();
std::unique_ptr<PolySpline> spline = std::make_unique<PolySpline>();
const int totalpoints = std::max(int(resolution * rotations), 1);
const int totalpoints = resolution * rotations;
const float delta_radius = (end_radius - start_radius) / (float)totalpoints;
float radius = start_radius;
const float delta_height = height / (float)totalpoints;

View File

@@ -29,6 +29,31 @@ static void geo_node_curve_reverse_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>("Curve");
}
/**
* Reverse the data in a MutableSpan object.
*/
template<typename T> static void reverse_data(MutableSpan<T> r_data)
{
const int size = r_data.size();
for (const int i : IndexRange(size / 2)) {
std::swap(r_data[size - 1 - i], r_data[i]);
}
}
/**
* Reverse and Swap the data between 2 MutableSpans.
*/
template<typename T> static void reverse_data(MutableSpan<T> left, MutableSpan<T> right)
{
BLI_assert(left.size() == right.size());
const int size = left.size();
for (const int i : IndexRange(size / 2 + size % 2)) {
std::swap(left[i], right[size - 1 - i]);
std::swap(right[i], left[size - 1 - i]);
}
}
static void geo_node_curve_reverse_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
@@ -49,9 +74,42 @@ static void geo_node_curve_reverse_exec(GeoNodeExecParams params)
threading::parallel_for(splines.index_range(), 128, [&](IndexRange range) {
for (const int i : range) {
if (selection[i]) {
splines[i]->reverse();
if (!selection[i]) {
continue;
}
reverse_data<float3>(splines[i]->positions());
reverse_data<float>(splines[i]->radii());
reverse_data<float>(splines[i]->tilts());
splines[i]->attributes.foreach_attribute(
[&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
std::optional<blender::fn::GMutableSpan> output_attribute =
splines[i]->attributes.get_for_write(attribute_id);
if (!output_attribute) {
BLI_assert_unreachable();
return false;
}
attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) {
using T = decltype(dummy);
reverse_data(output_attribute->typed<T>());
});
return true;
},
ATTR_DOMAIN_POINT);
/* Deal with extra info on derived types. */
if (BezierSpline *spline = dynamic_cast<BezierSpline *>(splines[i].get())) {
reverse_data<BezierSpline::HandleType>(spline->handle_types_left());
reverse_data<BezierSpline::HandleType>(spline->handle_types_right());
reverse_data<float3>(spline->handle_positions_left(), spline->handle_positions_right());
}
else if (NURBSpline *spline = dynamic_cast<NURBSpline *>(splines[i].get())) {
reverse_data<float>(spline->weights());
}
/* Nothing to do for poly splines. */
splines[i]->mark_cache_invalid();
}
});

View File

@@ -294,7 +294,8 @@ static Mesh *curve_to_mesh_calculate(const CurveEval &curve, const CurveEval &pr
BKE_id_material_eval_ensure_default_slot(&mesh->id);
mesh->flag |= ME_AUTOSMOOTH;
mesh->smoothresh = DEG2RADF(180.0f);
BKE_mesh_normals_tag_dirty(mesh);
mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
mesh->runtime.cd_dirty_poly |= CD_MASK_NORMAL;
threading::parallel_for(curves.index_range(), 128, [&](IndexRange curves_range) {
for (const int i_spline : curves_range) {

View File

@@ -559,7 +559,7 @@ static Mesh *delete_mesh_selection(const Mesh &mesh_in,
mesh_in, *result, vertex_map, edge_map, selected_poly_indices, new_loop_starts);
BKE_mesh_calc_edges_loose(result);
/* Tag to recalculate normals later. */
BKE_mesh_normals_tag_dirty(result);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
return result;
}

View File

@@ -33,7 +33,7 @@ namespace blender::nodes {
static void geo_node_join_geometry_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Geometry").multi_input();
b.add_input<decl::Geometry>("Geometry").multi_input(true);
b.add_output<decl::Geometry>("Geometry");
}

View File

@@ -29,12 +29,12 @@ namespace blender::nodes {
static void geo_node_material_assign_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Geometry");
b.add_input<decl::Material>("Material").hide_label();
b.add_input<decl::Bool>("Selection").default_value(true).hide_value();
b.add_input<decl::Material>("Material").hide_label(true);
b.add_input<decl::String>("Selection");
b.add_output<decl::Geometry>("Geometry");
}
static void assign_material_to_faces(Mesh &mesh, const IndexMask selection, Material *material)
static void assign_material_to_faces(Mesh &mesh, const VArray<bool> &face_mask, Material *material)
{
int new_material_index = -1;
for (const int i : IndexRange(mesh.totcol)) {
@@ -51,16 +51,18 @@ static void assign_material_to_faces(Mesh &mesh, const IndexMask selection, Mate
}
mesh.mpoly = (MPoly *)CustomData_duplicate_referenced_layer(&mesh.pdata, CD_MPOLY, mesh.totpoly);
for (const int i : selection) {
MPoly &poly = mesh.mpoly[i];
poly.mat_nr = new_material_index;
for (const int i : IndexRange(mesh.totpoly)) {
if (face_mask[i]) {
MPoly &poly = mesh.mpoly[i];
poly.mat_nr = new_material_index;
}
}
}
static void geo_node_material_assign_exec(GeoNodeExecParams params)
{
Material *material = params.extract_input<Material *>("Material");
const Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
const std::string mask_name = params.extract_input<std::string>("Selection");
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
@@ -70,15 +72,9 @@ static void geo_node_material_assign_exec(GeoNodeExecParams params)
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
Mesh *mesh = mesh_component.get_for_write();
if (mesh != nullptr) {
GeometryComponentFieldContext field_context{mesh_component, ATTR_DOMAIN_FACE};
fn::FieldEvaluator selection_evaluator{field_context, mesh->totpoly};
selection_evaluator.add(selection_field);
selection_evaluator.evaluate();
const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
assign_material_to_faces(*mesh, selection, material);
GVArray_Typed<bool> face_mask = mesh_component.attribute_get_for_read<bool>(
mask_name, ATTR_DOMAIN_FACE, true);
assign_material_to_faces(*mesh, face_mask, material);
}
}
@@ -91,7 +87,8 @@ void register_node_type_geo_material_assign()
{
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_MATERIAL_ASSIGN, "Material Assign", NODE_CLASS_GEOMETRY, 0);
geo_node_type_base(
&ntype, GEO_NODE_LEGACY_MATERIAL_ASSIGN, "Material Assign", NODE_CLASS_GEOMETRY, 0);
ntype.declare = blender::nodes::geo_node_material_assign_declare;
ntype.geometry_node_execute = blender::nodes::geo_node_material_assign_exec;
nodeRegisterType(&ntype);

View File

@@ -1,131 +0,0 @@
/*
* 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 "node_geometry_util.hh"
#include "UI_interface.h"
#include "UI_resources.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BLI_task.hh"
#include "BKE_material.h"
namespace blender::nodes {
static void geo_node_material_selection_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Material>("Material").hide_label(true);
b.add_output<decl::Bool>("Selection");
}
static void select_mesh_by_material(const Mesh &mesh,
const Material *material,
const IndexMask mask,
const MutableSpan<bool> r_selection)
{
BLI_assert(mesh.totpoly >= r_selection.size());
Vector<int> material_indices;
for (const int i : IndexRange(mesh.totcol)) {
if (mesh.mat[i] == material) {
material_indices.append(i);
}
}
threading::parallel_for(mask.index_range(), 1024, [&](IndexRange range) {
for (const int i : range) {
const int face_index = mask[i];
r_selection[i] = material_indices.contains(mesh.mpoly[face_index].mat_nr);
}
});
}
class MaterialSelectionFieldInput final : public fn::FieldInput {
Material *material_;
public:
MaterialSelectionFieldInput(Material *material)
: fn::FieldInput(CPPType::get<bool>(), "Material Selection"), material_(material)
{
}
const GVArray *get_varray_for_context(const fn::FieldContext &context,
IndexMask mask,
ResourceScope &scope) const final
{
if (const GeometryComponentFieldContext *geometry_context =
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
const GeometryComponent &component = geometry_context->geometry_component();
const AttributeDomain domain = geometry_context->domain();
if (component.type() != GEO_COMPONENT_TYPE_MESH) {
return nullptr;
}
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
const Mesh *mesh = mesh_component.get_for_read();
if (mesh == nullptr) {
return nullptr;
}
if (domain == ATTR_DOMAIN_FACE) {
Array<bool> selection(mask.min_array_size());
select_mesh_by_material(*mesh, material_, mask, selection);
return &scope.construct<fn::GVArray_For_ArrayContainer<Array<bool>>>(std::move(selection));
}
Array<bool> selection(mesh->totpoly);
select_mesh_by_material(*mesh, material_, IndexMask(mesh->totpoly), selection);
GVArrayPtr face_selection = std::make_unique<fn::GVArray_For_ArrayContainer<Array<bool>>>(
std::move(selection));
GVArrayPtr final_selection = mesh_component.attribute_try_adapt_domain(
std::move(face_selection), ATTR_DOMAIN_FACE, domain);
return scope.add_value(std::move(final_selection)).get();
}
return nullptr;
}
uint64_t hash() const override
{
/* Some random constant hash. */
return 91619626;
}
bool is_equal_to(const fn::FieldNode &other) const override
{
return dynamic_cast<const MaterialSelectionFieldInput *>(&other) != nullptr;
}
};
static void geo_node_material_selection_exec(GeoNodeExecParams params)
{
Material *material = params.extract_input<Material *>("Material");
Field<bool> material_field{std::make_shared<MaterialSelectionFieldInput>(material)};
params.set_output("Selection", std::move(material_field));
}
} // namespace blender::nodes
void register_node_type_geo_material_selection()
{
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_MATERIAL_SELECTION, "Material Selection", NODE_CLASS_GEOMETRY, 0);
ntype.declare = blender::nodes::geo_node_material_selection_declare;
ntype.geometry_node_execute = blender::nodes::geo_node_material_selection_exec;
nodeRegisterType(&ntype);
}

View File

@@ -25,7 +25,7 @@ namespace blender::nodes {
static void geo_node_object_info_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Object>("Object").hide_label();
b.add_input<decl::Object>("Object").hide_label(true);
b.add_output<decl::Vector>("Location");
b.add_output<decl::Vector>("Rotation");
b.add_output<decl::Vector>("Scale");

View File

@@ -29,8 +29,8 @@ namespace blender::nodes {
static void geo_node_point_instance_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Geometry");
b.add_input<decl::Object>("Object").hide_label();
b.add_input<decl::Collection>("Collection").hide_label();
b.add_input<decl::Object>("Object").hide_label(true);
b.add_input<decl::Collection>("Collection").hide_label(true);
b.add_input<decl::Geometry>("Instance Geometry");
b.add_input<decl::Int>("Seed").min(-10000).max(10000);
b.add_output<decl::Geometry>("Geometry");

View File

@@ -28,10 +28,10 @@
namespace blender::nodes {
static void geo_node_legacy_select_by_material_declare(NodeDeclarationBuilder &b)
static void geo_node_select_by_material_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Geometry");
b.add_input<decl::Material>("Material").hide_label();
b.add_input<decl::Material>("Material").hide_label(true);
b.add_input<decl::String>("Selection");
b.add_output<decl::Geometry>("Geometry");
}
@@ -54,7 +54,7 @@ static void select_mesh_by_material(const Mesh &mesh,
});
}
static void geo_node_legacy_select_by_material_exec(GeoNodeExecParams params)
static void geo_node_select_by_material_exec(GeoNodeExecParams params)
{
Material *material = params.extract_input<Material *>("Material");
const std::string selection_name = params.extract_input<std::string>("Selection");
@@ -80,13 +80,13 @@ static void geo_node_legacy_select_by_material_exec(GeoNodeExecParams params)
} // namespace blender::nodes
void register_node_type_geo_legacy_select_by_material()
void register_node_type_geo_select_by_material()
{
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_LEGACY_SELECT_BY_MATERIAL, "Select by Material", NODE_CLASS_GEOMETRY, 0);
ntype.declare = blender::nodes::geo_node_legacy_select_by_material_declare;
ntype.geometry_node_execute = blender::nodes::geo_node_legacy_select_by_material_exec;
ntype.declare = blender::nodes::geo_node_select_by_material_declare;
ntype.geometry_node_execute = blender::nodes::geo_node_select_by_material_exec;
nodeRegisterType(&ntype);
}

View File

@@ -24,7 +24,7 @@ static void geo_node_set_position_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Geometry");
b.add_input<decl::Vector>("Position");
b.add_input<decl::Bool>("Selection").default_value(true).hide_value();
b.add_input<decl::Bool>("Selection").default_value(true);
b.add_output<decl::Geometry>("Geometry");
}

View File

@@ -37,13 +37,14 @@ static void geo_node_subdivision_surface_layout(uiLayout *layout,
bContext *UNUSED(C),
PointerRNA *ptr)
{
#ifdef WITH_OPENSUBDIV
#ifndef WITH_OPENSUBDIV
UNUSED_VARS(ptr);
uiItemL(layout, IFACE_("Disabled, built without OpenSubdiv"), ICON_ERROR);
#else
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
uiItemR(layout, ptr, "uv_smooth", 0, nullptr, ICON_NONE);
uiItemR(layout, ptr, "boundary_smooth", 0, nullptr, ICON_NONE);
#else
UNUSED_VARS(layout, ptr);
#endif
}

View File

@@ -69,7 +69,8 @@ void transform_mesh(Mesh *mesh,
else {
const float4x4 matrix = float4x4::from_loc_eul_scale(translation, rotation, scale);
BKE_mesh_transform(mesh, matrix.values, false);
BKE_mesh_normals_tag_dirty(mesh);
mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
mesh->runtime.cd_dirty_poly |= CD_MASK_NORMAL;
}
}

View File

@@ -250,9 +250,6 @@ RenderPass *render_layer_add_pass(RenderResult *rr,
BLI_addtail(&rl->passes, rpass);
/* The result contains non-allocated pass now, so tag it as such. */
rr->passes_allocated = false;
return rpass;
}

View File

@@ -120,10 +120,6 @@ typedef enum eWM_GizmoFlagGroupTypeFlag {
* Also show this group when another group is being interacted with.
*/
WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL = (1 << 5),
/** Don't draw this gizmo group when it is modal. */
WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE = (1 << 6),
/**
* When used with tool, only run when activating the tool,
* instead of linking the gizmo while the tool is active.
@@ -134,7 +130,7 @@ typedef enum eWM_GizmoFlagGroupTypeFlag {
* when a tool can activate multiple operators based on the key-map.
* We could even move the options into the key-map item.
* ~ campbell. */
WM_GIZMOGROUPTYPE_TOOL_INIT = (1 << 7),
WM_GIZMOGROUPTYPE_TOOL_INIT = (1 << 6),
/**
* This gizmo type supports using the fallback tools keymap.
@@ -142,7 +138,7 @@ typedef enum eWM_GizmoFlagGroupTypeFlag {
*
* Often useful in combination with #WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK
*/
WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP = (1 << 8),
WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP = (1 << 7),
/**
* Use this from a gizmos refresh callback so we can postpone the refresh operation
@@ -153,14 +149,14 @@ typedef enum eWM_GizmoFlagGroupTypeFlag {
* for selection operations. This means gizmos that use this check don't interfere
* with click drag events by popping up under the cursor and catching the tweak event.
*/
WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK = (1 << 9),
WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK = (1 << 8),
/**
* Cause continuous redraws, i.e. set the region redraw flag on every main loop iteration. This
* should really be avoided by using proper region redraw tagging, notifiers and the message-bus,
* however for VR it's sometimes needed.
*/
WM_GIZMOGROUPTYPE_VR_REDRAWS = (1 << 10),
WM_GIZMOGROUPTYPE_VR_REDRAWS = (1 << 9),
} eWM_GizmoFlagGroupTypeFlag;
/**

View File

@@ -387,21 +387,14 @@ static void gizmomap_prepare_drawing(wmGizmoMap *gzmap,
LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, &gzmap->groups) {
/* check group visibility - drawstep first to avoid unnecessary call of group poll callback */
if (!wm_gizmogroup_is_visible_in_drawstep(gzgroup, drawstep)) {
if (!wm_gizmogroup_is_visible_in_drawstep(gzgroup, drawstep) ||
!WM_gizmo_group_type_poll(C, gzgroup->type)) {
continue;
}
if (gz_modal && (gzgroup == gz_modal->parent_gzgroup)) {
if (gzgroup->type->flag & WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE) {
continue;
}
}
else { /* Don't poll modal gizmo since some poll functions unlink. */
if (!WM_gizmo_group_type_poll(C, gzgroup->type)) {
continue;
}
/* When modal only show other gizmo groups tagged with #WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL. */
if (gz_modal && ((gzgroup->type->flag & WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL) == 0)) {
/* When modal only show other gizmo groups tagged with #WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL. */
if (gz_modal && (gzgroup != gz_modal->parent_gzgroup)) {
if ((gzgroup->type->flag & WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL) == 0) {
continue;
}
}

View File

@@ -383,12 +383,6 @@ static void wm_append_loose_data_instantiate(WMLinkAppendData *lapp_data,
ViewLayer *view_layer,
const View3D *v3d)
{
if (scene == NULL) {
/* In some cases, like the asset drag&drop e.g., the caller code manages instantiation itself.
*/
return;
}
LinkNode *itemlink;
Collection *active_collection = NULL;
const bool do_obdata = (lapp_data->flag & FILE_OBDATA_INSTANCE) != 0;
@@ -1287,10 +1281,6 @@ static ID *wm_file_link_append_datablock_ex(Main *bmain,
return id;
}
/*
* NOTE: `scene` (and related `view_layer` and `v3d`) pointers may be NULL, in which case no
* instantiation of linked objects, collections etc. will be performed.
*/
ID *WM_file_link_datablock(Main *bmain,
Scene *scene,
ViewLayer *view_layer,
@@ -1303,10 +1293,6 @@ ID *WM_file_link_datablock(Main *bmain,
bmain, scene, view_layer, v3d, filepath, id_code, id_name, false);
}
/*
* NOTE: `scene` (and related `view_layer` and `v3d`) pointers may be NULL, in which case no
* instantiation of appended objects, collections etc. will be performed.
*/
ID *WM_file_append_datablock(Main *bmain,
Scene *scene,
ViewLayer *view_layer,

View File

@@ -766,7 +766,7 @@ foreach(geo_node_test ${geo_node_tests})
)
endforeach()
else()
MESSAGE(STATUS "Directory named ${TEST_SRC_DIR}/modeling/geometry_nodes/${geo_node_test}/ Not Found, disabling test.")
MESSAGE(STATUS "No directory named ${TEST_SRC_DIR}/modeling/geometry_nodes/${geo_node_test}/ found, disabling test.")
endif()
endforeach()