Compare commits
6 Commits
temp-cocoa
...
temp-socke
Author | SHA1 | Date | |
---|---|---|---|
b25697b884 | |||
608c4d40a1 | |||
d021d633ff | |||
0c2c2af0aa | |||
2ffa956983 | |||
19d2f7d9cf |
@@ -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)];
|
||||
|
@@ -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
|
||||
|
@@ -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=[
|
||||
|
@@ -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
|
||||
|
||||
/** \} */
|
||||
|
||||
|
@@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -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 */
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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])
|
||||
|
@@ -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));
|
||||
|
@@ -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();
|
||||
|
@@ -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,
|
||||
|
@@ -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();
|
||||
|
@@ -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) {
|
||||
|
@@ -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;
|
||||
|
@@ -91,10 +91,6 @@ Span<float> PolySpline::tilts() const
|
||||
return tilts_;
|
||||
}
|
||||
|
||||
void PolySpline::reverse_impl()
|
||||
{
|
||||
}
|
||||
|
||||
void PolySpline::mark_cache_invalid()
|
||||
{
|
||||
tangent_cache_dirty_ = true;
|
||||
|
@@ -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);
|
||||
|
@@ -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,
|
||||
|
@@ -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.
|
||||
|
@@ -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};
|
||||
|
@@ -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);
|
||||
|
@@ -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 */
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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. */
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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),
|
||||
|
@@ -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,
|
||||
|
@@ -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) {
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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? */
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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. */
|
||||
{
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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) {
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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", "")
|
||||
|
@@ -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);
|
||||
}
|
@@ -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");
|
||||
}
|
||||
|
||||
|
@@ -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");
|
||||
|
@@ -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");
|
||||
|
@@ -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");
|
||||
|
@@ -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");
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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();
|
||||
}
|
||||
});
|
||||
|
||||
|
@@ -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) {
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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");
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
}
|
@@ -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");
|
||||
|
@@ -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");
|
||||
|
@@ -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);
|
||||
}
|
@@ -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");
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
/**
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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,
|
||||
|
@@ -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()
|
||||
|
||||
|
Reference in New Issue
Block a user