From 17243337d7317045a46c521cfc74c3739a5404d6 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sat, 31 Jul 2021 14:26:01 -0400 Subject: [PATCH 01/24] Cleanup: Remove unecessary helper function Retrieving a mesh's looptris now take's a const mesh after rB5f8969bb4b4, which removes the need for this function. Since it's only two lines, avoiding the use of a separate function in this case is simpler. --- source/blender/blenkernel/BKE_mesh_sample.hh | 2 -- .../blender/blenkernel/intern/mesh_sample.cc | 23 ++++++++----------- .../nodes/node_geo_attribute_transfer.cc | 3 ++- .../nodes/node_geo_point_distribute.cc | 16 +++++-------- 4 files changed, 18 insertions(+), 26 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh_sample.hh b/source/blender/blenkernel/BKE_mesh_sample.hh index dc747ba5b42..2fbf7372a09 100644 --- a/source/blender/blenkernel/BKE_mesh_sample.hh +++ b/source/blender/blenkernel/BKE_mesh_sample.hh @@ -40,8 +40,6 @@ using fn::GMutableSpan; using fn::GSpan; using fn::GVArray; -Span get_mesh_looptris(const Mesh &mesh); - void sample_point_attribute(const Mesh &mesh, Span looptri_indices, Span bary_coords, diff --git a/source/blender/blenkernel/intern/mesh_sample.cc b/source/blender/blenkernel/intern/mesh_sample.cc index bd46407d060..5388f6e530e 100644 --- a/source/blender/blenkernel/intern/mesh_sample.cc +++ b/source/blender/blenkernel/intern/mesh_sample.cc @@ -24,14 +24,6 @@ namespace blender::bke::mesh_surface_sample { -Span get_mesh_looptris(const Mesh &mesh) -{ - /* This only updates a cache and can be considered to be logically const. */ - const MLoopTri *looptris = BKE_mesh_runtime_looptri_ensure(const_cast(&mesh)); - const int looptris_len = BKE_mesh_runtime_looptri_len(&mesh); - return {looptris, looptris_len}; -} - template BLI_NOINLINE static void sample_point_attribute(const Mesh &mesh, const Span looptri_indices, @@ -39,7 +31,8 @@ BLI_NOINLINE static void sample_point_attribute(const Mesh &mesh, const VArray &data_in, const MutableSpan data_out) { - const Span looptris = get_mesh_looptris(mesh); + const Span looptris{BKE_mesh_runtime_looptri_ensure(&mesh), + BKE_mesh_runtime_looptri_len(&mesh)}; for (const int i : bary_coords.index_range()) { const int looptri_index = looptri_indices[i]; @@ -85,7 +78,8 @@ BLI_NOINLINE static void sample_corner_attribute(const Mesh &mesh, const VArray &data_in, const MutableSpan data_out) { - Span looptris = get_mesh_looptris(mesh); + const Span looptris{BKE_mesh_runtime_looptri_ensure(&mesh), + BKE_mesh_runtime_looptri_len(&mesh)}; for (const int i : bary_coords.index_range()) { const int looptri_index = looptri_indices[i]; @@ -130,7 +124,8 @@ void sample_face_attribute(const Mesh &mesh, const VArray &data_in, const MutableSpan data_out) { - Span looptris = get_mesh_looptris(mesh); + const Span looptris{BKE_mesh_runtime_looptri_ensure(&mesh), + BKE_mesh_runtime_looptri_len(&mesh)}; for (const int i : data_out.index_range()) { const int looptri_index = looptri_indices[i]; @@ -172,7 +167,8 @@ Span MeshAttributeInterpolator::ensure_barycentric_coords() } bary_coords_.reinitialize(positions_.size()); - Span looptris = get_mesh_looptris(*mesh_); + const Span looptris{BKE_mesh_runtime_looptri_ensure(mesh_), + BKE_mesh_runtime_looptri_len(mesh_)}; for (const int i : bary_coords_.index_range()) { const int looptri_index = looptri_indices_[i]; @@ -199,7 +195,8 @@ Span MeshAttributeInterpolator::ensure_nearest_weights() } nearest_weights_.reinitialize(positions_.size()); - Span looptris = get_mesh_looptris(*mesh_); + const Span looptris{BKE_mesh_runtime_looptri_ensure(mesh_), + BKE_mesh_runtime_looptri_len(mesh_)}; for (const int i : nearest_weights_.index_range()) { const int looptri_index = looptri_indices_[i]; diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_transfer.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_transfer.cc index 6a23443d3ab..ab2136f4e8d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_transfer.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_transfer.cc @@ -204,7 +204,8 @@ static void get_closest_mesh_polygons(const Mesh &mesh, Array looptri_indices(positions.size()); get_closest_mesh_looptris(mesh, positions, looptri_indices, r_distances_sq, r_positions); - Span looptris = bke::mesh_surface_sample::get_mesh_looptris(mesh); + const Span looptris{BKE_mesh_runtime_looptri_ensure(&mesh), + BKE_mesh_runtime_looptri_len(&mesh)}; for (const int i : positions.index_range()) { const MLoopTri &looptri = looptris[looptri_indices[i]]; r_poly_indices[i] = looptri.poly; diff --git a/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc b/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc index d456c72744f..99930b5ae46 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc @@ -81,13 +81,6 @@ static float3 normal_to_euler_rotation(const float3 normal) return rotation; } -static Span get_mesh_looptris(const Mesh &mesh) -{ - const MLoopTri *looptris = BKE_mesh_runtime_looptri_ensure(&mesh); - const int looptris_len = BKE_mesh_runtime_looptri_len(&mesh); - return {looptris, looptris_len}; -} - static void sample_mesh_surface(const Mesh &mesh, const float4x4 &transform, const float base_density, @@ -97,7 +90,8 @@ static void sample_mesh_surface(const Mesh &mesh, Vector &r_bary_coords, Vector &r_looptri_indices) { - Span looptris = get_mesh_looptris(mesh); + const Span looptris{BKE_mesh_runtime_looptri_ensure(&mesh), + BKE_mesh_runtime_looptri_len(&mesh)}; for (const int looptri_index : looptris.index_range()) { const MLoopTri &looptri = looptris[looptri_index]; @@ -208,7 +202,8 @@ BLI_NOINLINE static void update_elimination_mask_based_on_density_factors( Span looptri_indices, MutableSpan elimination_mask) { - Span looptris = get_mesh_looptris(mesh); + const Span looptris{BKE_mesh_runtime_looptri_ensure(&mesh), + BKE_mesh_runtime_looptri_len(&mesh)}; for (const int i : bary_coords.index_range()) { if (elimination_mask[i]) { continue; @@ -365,7 +360,8 @@ BLI_NOINLINE static void compute_special_attributes(Span const GeometrySet &set = set_group.geometry_set; const MeshComponent &component = *set.get_component_for_read(); const Mesh &mesh = *component.get_for_read(); - Span looptris = get_mesh_looptris(mesh); + const Span looptris{BKE_mesh_runtime_looptri_ensure(&mesh), + BKE_mesh_runtime_looptri_len(&mesh)}; for (const float4x4 &transform : set_group.transforms) { const int offset = instance_start_offsets[i_instance]; From 79277986c299eaa3df9364e6d9f2b88d2b4f2dea Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sat, 31 Jul 2021 23:22:36 -0400 Subject: [PATCH 02/24] Cleanup: Sort node types alphabetically --- source/blender/nodes/NOD_static_types.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 1298acf475d..a091f28f3a0 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -291,22 +291,22 @@ DefNode(GeometryNode, GEO_NODE_BOOLEAN, def_geo_boolean, "BOOLEAN", Boolean, "Bo DefNode(GeometryNode, GEO_NODE_BOUNDING_BOX, 0, "BOUNDING_BOX", BoundBox, "Bounding Box", "") DefNode(GeometryNode, GEO_NODE_COLLECTION_INFO, def_geo_collection_info, "COLLECTION_INFO", CollectionInfo, "Collection Info", "") DefNode(GeometryNode, GEO_NODE_CONVEX_HULL, 0, "CONVEX_HULL", ConvexHull, "Convex Hull", "") +DefNode(GeometryNode, GEO_NODE_CURVE_ENDPOINTS, 0, "CURVE_ENDPOINTS", CurveEndpoints, "Curve Endpoints", "") DefNode(GeometryNode, GEO_NODE_CURVE_LENGTH, 0, "CURVE_LENGTH", CurveLength, "Curve Length", "") DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_BEZIER_SEGMENT, def_geo_curve_primitive_bezier_segment, "CURVE_PRIMITIVE_BEZIER_SEGMENT", CurvePrimitiveBezierSegment, "Bezier Segment", "") DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_CIRCLE, def_geo_curve_primitive_circle, "CURVE_PRIMITIVE_CIRCLE", CurvePrimitiveCircle, "Curve Circle", "") DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_LINE, def_geo_curve_primitive_line, "CURVE_PRIMITIVE_LINE", CurvePrimitiveLine, "Curve Line", "") -DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_QUADRILATERAL, def_geo_curve_primitive_quadrilateral, "CURVE_PRIMITIVE_QUADRILATERAL", CurvePrimitiveQuadrilateral, "Quadrilateral", "") DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_QUADRATIC_BEZIER, 0, "CURVE_PRIMITIVE_QUADRATIC_BEZIER", CurveQuadraticBezier, "Quadratic Bezier", "") -DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_STAR, 0, "CURVE_PRIMITIVE_STAR", CurveStar, "Star", "") +DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_QUADRILATERAL, def_geo_curve_primitive_quadrilateral, "CURVE_PRIMITIVE_QUADRILATERAL", CurvePrimitiveQuadrilateral, "Quadrilateral", "") DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_SPIRAL, 0, "CURVE_PRIMITIVE_SPIRAL", CurveSpiral, "Curve Spiral", "") +DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_STAR, 0, "CURVE_PRIMITIVE_STAR", CurveStar, "Star", "") DefNode(GeometryNode, GEO_NODE_CURVE_RESAMPLE, def_geo_curve_resample, "CURVE_RESAMPLE", CurveResample, "Resample Curve", "") +DefNode(GeometryNode, GEO_NODE_CURVE_REVERSE, 0, "CURVE_REVERSE", CurveReverse, "Curve Reverse", "") DefNode(GeometryNode, GEO_NODE_CURVE_SET_HANDLES, def_geo_curve_set_handles, "CURVE_SET_HANDLES", CurveSetHandles, "Set Handle Type", "") DefNode(GeometryNode, GEO_NODE_CURVE_SUBDIVIDE, def_geo_curve_subdivide, "CURVE_SUBDIVIDE", CurveSubdivide, "Curve Subdivide", "") DefNode(GeometryNode, GEO_NODE_CURVE_TO_MESH, 0, "CURVE_TO_MESH", CurveToMesh, "Curve to Mesh", "") -DefNode(GeometryNode, GEO_NODE_CURVE_TRIM, def_geo_curve_trim, "CURVE_TRIM", CurveTrim, "Curve Trim", "") -DefNode(GeometryNode, GEO_NODE_CURVE_REVERSE, 0, "CURVE_REVERSE", CurveReverse, "Curve Reverse", "") DefNode(GeometryNode, GEO_NODE_CURVE_TO_POINTS, def_geo_curve_to_points, "CURVE_TO_POINTS", CurveToPoints, "Curve to Points", "") -DefNode(GeometryNode, GEO_NODE_CURVE_ENDPOINTS, 0, "CURVE_ENDPOINTS", CurveEndpoints, "Curve Endpoints", "") +DefNode(GeometryNode, GEO_NODE_CURVE_TRIM, def_geo_curve_trim, "CURVE_TRIM", CurveTrim, "Curve Trim", "") DefNode(GeometryNode, GEO_NODE_DELETE_GEOMETRY, 0, "DELETE_GEOMETRY", DeleteGeometry, "Delete Geometry", "") DefNode(GeometryNode, GEO_NODE_EDGE_SPLIT, 0, "EDGE_SPLIT", EdgeSplit, "Edge Split", "") DefNode(GeometryNode, GEO_NODE_INPUT_MATERIAL, def_geo_input_material, "INPUT_MATERIAL", InputMaterial, "Material", "") @@ -322,6 +322,7 @@ DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_GRID, 0, "MESH_PRIMITIVE_GRID", Me DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_ICO_SPHERE, 0, "MESH_PRIMITIVE_ICO_SPHERE", MeshIcoSphere, "Ico Sphere", "") DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_LINE, def_geo_mesh_line, "MESH_PRIMITIVE_LINE", MeshLine, "Mesh Line", "") DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_UV_SPHERE, 0, "MESH_PRIMITIVE_UV_SPHERE", MeshUVSphere, "UV Sphere", "") +DefNode(GeometryNode, GEO_NODE_MESH_SUBDIVIDE, 0, "MESH_SUBDIVIDE", MeshSubdivide, "Mesh Subdivide", "") DefNode(GeometryNode, GEO_NODE_MESH_TO_CURVE, 0, "MESH_TO_CURVE", MeshToCurve, "Mesh to Curve", "") DefNode(GeometryNode, GEO_NODE_OBJECT_INFO, def_geo_object_info, "OBJECT_INFO", ObjectInfo, "Object Info", "") DefNode(GeometryNode, GEO_NODE_POINT_DISTRIBUTE, def_geo_point_distribute, "POINT_DISTRIBUTE", PointDistribute, "Point Distribute", "") @@ -334,7 +335,6 @@ DefNode(GeometryNode, GEO_NODE_POINTS_TO_VOLUME, def_geo_points_to_volume, "POIN DefNode(GeometryNode, GEO_NODE_RAYCAST, def_geo_raycast, "RAYCAST", Raycast, "Raycast", "") DefNode(GeometryNode, GEO_NODE_SELECT_BY_MATERIAL, 0, "SELECT_BY_MATERIAL", SelectByMaterial, "Select by Material", "") DefNode(GeometryNode, GEO_NODE_SEPARATE_COMPONENTS, 0, "SEPARATE_COMPONENTS", SeparateComponents, "Separate Components", "") -DefNode(GeometryNode, GEO_NODE_MESH_SUBDIVIDE, 0, "MESH_SUBDIVIDE", MeshSubdivide, "Mesh Subdivide", "") DefNode(GeometryNode, GEO_NODE_SUBDIVISION_SURFACE, 0, "SUBDIVISION_SURFACE", SubdivisionSurface, "Subdivision Surface", "") DefNode(GeometryNode, GEO_NODE_SWITCH, def_geo_switch, "SWITCH", Switch, "Switch", "") DefNode(GeometryNode, GEO_NODE_TRANSFORM, 0, "TRANSFORM", Transform, "Transform", "") From 836aeebf70776791866c8cc82a0ca2ad7ffb8e4d Mon Sep 17 00:00:00 2001 From: Takahiro Shizuki Date: Sun, 1 Aug 2021 11:52:22 -0700 Subject: [PATCH 03/24] IME Win32: Fix Duplicated Initial Character When entering characters using IME on Windows, Japanese and Chinese will both usually result in the first keystroke being duplicated. The problem is that we are informed too late, after the first key is pressed, that we are IME composing. This patch ensures we are entering non-English characters using ImmGetConversionStatus() and then deals with editing keys (like arrows and backspace) on a per-language basis. see D11929 for more details. Differential Revision: https://developer.blender.org/D11929 Reviewed by Brecht Van Lommel --- intern/ghost/intern/GHOST_ImeWin32.cpp | 59 +++++++++++++++++++++++ intern/ghost/intern/GHOST_ImeWin32.h | 18 +++++++ intern/ghost/intern/GHOST_SystemWin32.cpp | 16 +++++- 3 files changed, 91 insertions(+), 2 deletions(-) diff --git a/intern/ghost/intern/GHOST_ImeWin32.cpp b/intern/ghost/intern/GHOST_ImeWin32.cpp index 112a266ae28..412f7e4276c 100644 --- a/intern/ghost/intern/GHOST_ImeWin32.cpp +++ b/intern/ghost/intern/GHOST_ImeWin32.cpp @@ -34,6 +34,8 @@ GHOST_ImeWin32::GHOST_ImeWin32() : is_composing_(false), ime_status_(false), input_language_id_(LANG_USER_DEFAULT), + conversion_modes_(IME_CMODE_ALPHANUMERIC), + sentence_mode_(IME_SMODE_NONE), system_caret_(false), caret_rect_(-1, -1, 0, 0), is_first(true), @@ -59,6 +61,63 @@ bool GHOST_ImeWin32::SetInputLanguage() return ime_status_; } +WORD GHOST_ImeWin32::GetInputLanguage() +{ + return input_language_id_; +} + +void GHOST_ImeWin32::UpdateConversionStatus(HWND window_handle) +{ + HIMC imm_context = ::ImmGetContext(window_handle); + if (imm_context) { + if (::ImmGetOpenStatus(imm_context)) { + ::ImmGetConversionStatus(imm_context, &conversion_modes_, &sentence_mode_); + } + else { + conversion_modes_ = IME_CMODE_ALPHANUMERIC; + sentence_mode_ = IME_SMODE_NONE; + } + ::ImmReleaseContext(window_handle, imm_context); + } + else { + conversion_modes_ = IME_CMODE_ALPHANUMERIC; + sentence_mode_ = IME_SMODE_NONE; + } +} + +bool GHOST_ImeWin32::IsEnglishMode() +{ + return (conversion_modes_ & IME_CMODE_NOCONVERSION) || + !(conversion_modes_ & (IME_CMODE_NATIVE | IME_CMODE_FULLSHAPE)); +} + +bool GHOST_ImeWin32::IsImeKeyEvent(char ascii) +{ + if (!(IsEnglishMode())) { + /* In Chinese, Japanese, Korena, all alpha keys are processed by IME. */ + if ((ascii >= 'A' && ascii <= 'Z') || (ascii >= 'a' && ascii <= 'z')) { + return true; + } + switch (PRIMARYLANGID(GetInputLanguage())) { + /* In Japanese, all symbolic characters are also processed by IME. */ + case LANG_JAPANESE: { + if (ascii >= ' ' && ascii <= '~') { + return true; + } + break; + } + /* In Chinese, some symbolic characters are also processed by IME. */ + case LANG_CHINESE: { + if (ascii && strchr("!\"$'(),.:;<>?[\\]^_`", ascii)) { + return true; + } + break; + } + } + } + return false; +} + void GHOST_ImeWin32::CreateImeWindow(HWND window_handle) { /** diff --git a/intern/ghost/intern/GHOST_ImeWin32.h b/intern/ghost/intern/GHOST_ImeWin32.h index 4af988aef6e..bcc4b6eef7c 100644 --- a/intern/ghost/intern/GHOST_ImeWin32.h +++ b/intern/ghost/intern/GHOST_ImeWin32.h @@ -156,6 +156,18 @@ class GHOST_ImeWin32 { */ bool SetInputLanguage(); + /* Returns the current input language id. */ + WORD GetInputLanguage(); + + /* Saves the current conversion status. */ + void UpdateConversionStatus(HWND window_handle); + + /* Is the IME currently in conversion mode? */ + bool IsEnglishMode(); + + /* Checks a key whether IME has to do handling. */ + bool IsImeKeyEvent(char ascii); + /** * Create the IME windows, and allocate required resources for them. * Parameters @@ -371,6 +383,12 @@ class GHOST_ImeWin32 { */ LANGID input_language_id_; + /* Current Conversion Mode Values. Retrieved with ImmGetConversionStatus. */ + DWORD conversion_modes_; + + /* Current Sentence Mode. Retrieved with ImmGetConversionStatus. */ + DWORD sentence_mode_; + /** * Represents whether or not the current input context has created a system * caret to set the position of its IME candidate window. diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 694efaaaf03..60fd175dbf7 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -1219,6 +1219,12 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA ascii = utf8_char[0] & 0x80 ? '?' : utf8_char[0]; } +#ifdef WITH_INPUT_IME + if (window->getImeInput()->IsImeKeyEvent(ascii)) { + return NULL; + } +#endif /* WITH_INPUT_IME */ + event = new GHOST_EventKey(system->getMilliSeconds(), keyDown ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, @@ -1419,6 +1425,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, system->handleKeyboardChange(); #ifdef WITH_INPUT_IME window->getImeInput()->SetInputLanguage(); + window->getImeInput()->UpdateConversionStatus(hwnd); #endif break; } @@ -1455,6 +1462,13 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, //////////////////////////////////////////////////////////////////////// // IME events, processed, read more in GHOST_IME.h //////////////////////////////////////////////////////////////////////// + case WM_IME_NOTIFY: { + /* Update conversion status when IME is changed or input mode is changed. */ + if (wParam == IMN_SETOPENSTATUS || wParam == IMN_SETCONVERSIONMODE) { + window->getImeInput()->UpdateConversionStatus(hwnd); + } + break; + } case WM_IME_SETCONTEXT: { GHOST_ImeWin32 *ime = window->getImeInput(); ime->SetInputLanguage(); @@ -1466,8 +1480,6 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, case WM_IME_STARTCOMPOSITION: { GHOST_ImeWin32 *ime = window->getImeInput(); eventHandled = true; - /* remove input event before start comp event, avoid redundant input */ - eventManager->removeTypeEvents(GHOST_kEventKeyDown, window); ime->CreateImeWindow(hwnd); ime->ResetComposition(hwnd); event = processImeEvent(GHOST_kEventImeCompositionStart, window, &ime->eventImeData); From 1cf45fe10f7f99905343012798be6dbac51c3384 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 2 Aug 2021 15:22:54 +1000 Subject: [PATCH 04/24] Cleanup: spelling --- intern/ghost/intern/GHOST_ImeWin32.cpp | 2 +- source/blender/blenkernel/intern/mesh_remesh_voxel.cc | 2 +- source/blender/blenlib/intern/mesh_intersect.cc | 4 ++-- source/blender/gpu/intern/gpu_material.c | 4 ++-- source/blender/simulation/intern/implicit_blender.c | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/intern/ghost/intern/GHOST_ImeWin32.cpp b/intern/ghost/intern/GHOST_ImeWin32.cpp index 412f7e4276c..8daa07b5003 100644 --- a/intern/ghost/intern/GHOST_ImeWin32.cpp +++ b/intern/ghost/intern/GHOST_ImeWin32.cpp @@ -94,7 +94,7 @@ bool GHOST_ImeWin32::IsEnglishMode() bool GHOST_ImeWin32::IsImeKeyEvent(char ascii) { if (!(IsEnglishMode())) { - /* In Chinese, Japanese, Korena, all alpha keys are processed by IME. */ + /* In Chinese, Japanese, Korean, all alpha keys are processed by IME. */ if ((ascii >= 'A' && ascii <= 'Z') || (ascii >= 'a' && ascii <= 'z')) { return true; } diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc index 1ac6ec1b9c1..8364b0ec024 100644 --- a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc +++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc @@ -72,7 +72,7 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh, /* Ensure that the triangulated mesh data is up to data */ const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(input_mesh); - /* Gather the required data for export to the internal quadiflow mesh format */ + /* Gather the required data for export to the internal quadriflow mesh format. */ MVertTri *verttri = (MVertTri *)MEM_callocN( sizeof(*verttri) * BKE_mesh_runtime_looptri_len(input_mesh), "remesh_looptri"); BKE_mesh_runtime_verttri_from_looptri( diff --git a/source/blender/blenlib/intern/mesh_intersect.cc b/source/blender/blenlib/intern/mesh_intersect.cc index dcd432a88d5..5651e52799e 100644 --- a/source/blender/blenlib/intern/mesh_intersect.cc +++ b/source/blender/blenlib/intern/mesh_intersect.cc @@ -1165,8 +1165,8 @@ static int filter_plane_side(const double3 &p, * interesect_tri_tri and helper functions. * This code uses the algorithm of Guigue and Devillers, as described * in "Faster Triangle-Triangle Intersection Tests". - * Adapted from github code by Eric Haines: - * github.com/erich666/jgt-code/tree/master/Volume_08/Number_1/Guigue2003 + * Adapted from code by Eric Haines: + * https://github.com/erich666/jgt-code/tree/master/Volume_08/Number_1/Guigue2003 */ /** diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 675036b31c3..37089785e0e 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -452,8 +452,8 @@ static void compute_sss_translucence_kernel(const GPUSssKernelData *kd, /* Distance from surface. */ float d = kd->max_radius * ((float)i + 0.00001f) / ((float)resolution); - /* For each distance d we compute the radiance incoming from an hypothetic parallel plane. */ - /* Compute radius of the footprint on the hypothetic plane */ + /* For each distance d we compute the radiance incoming from an hypothetical parallel plane. */ + /* Compute radius of the footprint on the hypothetical plane. */ float r_fp = sqrtf(kd->max_radius * kd->max_radius - d * d); float r_step = r_fp / INTEGRAL_RESOLUTION; float area_accum = 0.0f; diff --git a/source/blender/simulation/intern/implicit_blender.c b/source/blender/simulation/intern/implicit_blender.c index 10a5f153662..ad903e9da4a 100644 --- a/source/blender/simulation/intern/implicit_blender.c +++ b/source/blender/simulation/intern/implicit_blender.c @@ -2204,7 +2204,7 @@ bool SIM_mass_spring_force_spring_bending_hair(Implicit_Data *data, world_to_root_v3(data, j, goal, target); spring_hairbend_forces(data, i, j, k, goal, stiffness, damping, k, vecnull, vecnull, fk); - negate_v3_v3(fj, fk); /* counterforce */ + negate_v3_v3(fj, fk); /* Counter-force. */ spring_hairbend_estimate_dfdx(data, i, j, k, goal, stiffness, damping, i, dfk_dxi); spring_hairbend_estimate_dfdx(data, i, j, k, goal, stiffness, damping, j, dfk_dxj); From 48722e8971133dbe14ecc6825a2451637df77eab Mon Sep 17 00:00:00 2001 From: YimingWu Date: Mon, 2 Aug 2021 13:45:30 +0800 Subject: [PATCH 05/24] LineArt: Prevent depsgraph warning when camera is NULL. --- .../gpencil_modifiers/intern/MOD_gpencillineart.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c index ac458041ca3..73ca4b9c529 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c @@ -261,10 +261,12 @@ static void updateDepsgraph(GpencilModifierData *md, else { add_this_collection(ctx->scene->master_collection, ctx, mode); } - DEG_add_object_relation( - ctx->node, ctx->scene->camera, DEG_OB_COMP_TRANSFORM, "Line Art Modifier"); - DEG_add_object_relation( - ctx->node, ctx->scene->camera, DEG_OB_COMP_PARAMETERS, "Line Art Modifier"); + if (ctx->scene->camera) { + DEG_add_object_relation( + ctx->node, ctx->scene->camera, DEG_OB_COMP_TRANSFORM, "Line Art Modifier"); + DEG_add_object_relation( + ctx->node, ctx->scene->camera, DEG_OB_COMP_PARAMETERS, "Line Art Modifier"); + } } static void foreachIDLink(GpencilModifierData *md, Object *ob, IDWalkFunc walk, void *userData) From de91cdd930614d5396ca4691b37cc0502481ead7 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Mon, 2 Aug 2021 10:34:50 +0200 Subject: [PATCH 06/24] Cleanup: separate base and geometry nodes specific socket cpp type This simplifies changing how geometry nodes handles different socket types without affecting other systems. --- source/blender/blenkernel/BKE_node.h | 13 +++- source/blender/modifiers/intern/MOD_nodes.cc | 8 +-- .../modifiers/intern/MOD_nodes_evaluator.cc | 15 +++- source/blender/nodes/NOD_type_callbacks.hh | 2 - .../nodes/intern/node_geometry_exec.cc | 4 +- source/blender/nodes/intern/node_socket.cc | 68 +++++++++++++------ source/blender/nodes/intern/type_callbacks.cc | 27 ++------ 7 files changed, 80 insertions(+), 57 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index cecb3118038..a1bc6fa505b 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -125,6 +125,9 @@ using NodeExpandInMFNetworkFunction = void (*)(blender::nodes::NodeMFNetworkBuil using NodeGeometryExecFunction = void (*)(blender::nodes::GeoNodeExecParams params); using SocketGetCPPTypeFunction = const blender::fn::CPPType *(*)(); using SocketGetCPPValueFunction = void (*)(const struct bNodeSocket &socket, void *r_value); +using SocketGetGeometryNodesCPPTypeFunction = const blender::fn::CPPType *(*)(); +using SocketGetGeometryNodesCPPValueFunction = void (*)(const struct bNodeSocket &socket, + void *r_value); using SocketExpandInMFNetworkFunction = void (*)(blender::nodes::SocketMFNetworkBuilder &builder); #else @@ -132,6 +135,8 @@ typedef void *NodeExpandInMFNetworkFunction; typedef void *SocketExpandInMFNetworkFunction; typedef void *NodeGeometryExecFunction; typedef void *SocketGetCPPTypeFunction; +typedef void *SocketGetGeometryNodesCPPTypeFunction; +typedef void *SocketGetGeometryNodesCPPValueFunction; typedef void *SocketGetCPPValueFunction; #endif @@ -194,9 +199,13 @@ typedef struct bNodeSocketType { /* Expands the socket into a multi-function node that outputs the socket value. */ SocketExpandInMFNetworkFunction expand_in_mf_network; /* Return the CPPType of this socket. */ - SocketGetCPPTypeFunction get_cpp_type; + SocketGetCPPTypeFunction get_base_cpp_type; /* Get the value of this socket in a generic way. */ - SocketGetCPPValueFunction get_cpp_value; + SocketGetCPPValueFunction get_base_cpp_value; + /* Get geometry nodes cpp type. */ + SocketGetGeometryNodesCPPTypeFunction get_geometry_nodes_cpp_type; + /* Get geometry nodes cpp value. */ + SocketGetGeometryNodesCPPValueFunction get_geometry_nodes_cpp_value; } bNodeSocketType; typedef void *(*NodeInitExecFunction)(struct bNodeExecContext *context, diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 5fa11ffdd10..3853b345c14 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -721,17 +721,17 @@ static void initialize_group_input(NodesModifierData &nmd, return; } if (nmd.settings.properties == nullptr) { - blender::nodes::socket_cpp_value_get(socket, r_value); + socket.typeinfo->get_geometry_nodes_cpp_value(socket, r_value); return; } const IDProperty *property = IDP_GetPropertyFromGroup(nmd.settings.properties, socket.identifier); if (property == nullptr) { - blender::nodes::socket_cpp_value_get(socket, r_value); + socket.typeinfo->get_geometry_nodes_cpp_value(socket, r_value); return; } if (!property_type->is_correct_type(*property)) { - blender::nodes::socket_cpp_value_get(socket, r_value); + socket.typeinfo->get_geometry_nodes_cpp_value(socket, r_value); return; } property_type->init_cpp_value(*property, r_value); @@ -883,7 +883,7 @@ static GeometrySet compute_geometry(const DerivedNodeTree &tree, /* Initialize remaining group inputs. */ for (const OutputSocketRef *socket : remaining_input_sockets) { - const CPPType &cpp_type = *blender::nodes::socket_cpp_type_get(*socket->typeinfo()); + const CPPType &cpp_type = *socket->typeinfo()->get_geometry_nodes_cpp_type(); void *value_in = allocator.allocate(cpp_type.size(), cpp_type.alignment()); initialize_group_input(*nmd, *socket->bsocket(), cpp_type, value_in); group_inputs.add_new({root_context, socket}, {cpp_type, value_in}); diff --git a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc index e652eb8353d..2157092d639 100644 --- a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc +++ b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc @@ -294,7 +294,11 @@ class LockedNode : NonCopyable, NonMovable { static const CPPType *get_socket_cpp_type(const SocketRef &socket) { - const CPPType *type = nodes::socket_cpp_type_get(*socket.typeinfo()); + const bNodeSocketType *typeinfo = socket.typeinfo(); + if (typeinfo->get_geometry_nodes_cpp_type == nullptr) { + return nullptr; + } + const CPPType *type = typeinfo->get_geometry_nodes_cpp_type(); if (type == nullptr) { return nullptr; } @@ -310,6 +314,12 @@ static const CPPType *get_socket_cpp_type(const DSocket socket) return get_socket_cpp_type(*socket.socket_ref()); } +static void get_socket_value(const SocketRef &socket, void *r_value) +{ + const bNodeSocketType *typeinfo = socket.typeinfo(); + typeinfo->get_geometry_nodes_cpp_value(*socket.bsocket(), r_value); +} + static bool node_supports_laziness(const DNode node) { return node->typeinfo()->geometry_node_execute_supports_laziness; @@ -1363,10 +1373,9 @@ class GeometryNodesEvaluator { { LinearAllocator<> &allocator = local_allocators_.local(); - bNodeSocket *bsocket = socket->bsocket(); const CPPType &type = *get_socket_cpp_type(socket); void *buffer = allocator.allocate(type.size(), type.alignment()); - blender::nodes::socket_cpp_value_get(*bsocket, buffer); + get_socket_value(*socket.socket_ref(), buffer); if (type == required_type) { return {type, buffer}; diff --git a/source/blender/nodes/NOD_type_callbacks.hh b/source/blender/nodes/NOD_type_callbacks.hh index d1a4bd3ad7a..2be78f929db 100644 --- a/source/blender/nodes/NOD_type_callbacks.hh +++ b/source/blender/nodes/NOD_type_callbacks.hh @@ -27,10 +27,8 @@ namespace blender::nodes { using fn::CPPType; using fn::MFDataType; -const CPPType *socket_cpp_type_get(const bNodeSocketType &stype); std::optional socket_mf_type_get(const bNodeSocketType &stype); bool socket_is_mf_data_socket(const bNodeSocketType &stype); -bool socket_cpp_value_get(const bNodeSocket &socket, void *r_value); void socket_expand_in_mf_network(SocketMFNetworkBuilder &builder); } // namespace blender::nodes diff --git a/source/blender/nodes/intern/node_geometry_exec.cc b/source/blender/nodes/intern/node_geometry_exec.cc index bfd1ad02d36..ffa20579acc 100644 --- a/source/blender/nodes/intern/node_geometry_exec.cc +++ b/source/blender/nodes/intern/node_geometry_exec.cc @@ -218,7 +218,7 @@ void GeoNodeExecParams::check_input_access(StringRef identifier, BLI_assert_unreachable(); } else if (requested_type != nullptr) { - const CPPType &expected_type = *socket_cpp_type_get(*found_socket->typeinfo); + const CPPType &expected_type = *found_socket->typeinfo->get_geometry_nodes_cpp_type(); if (*requested_type != expected_type) { std::cout << "The requested type '" << requested_type->name() << "' is incorrect. Expected '" << expected_type.name() << "'.\n"; @@ -258,7 +258,7 @@ void GeoNodeExecParams::check_output_access(StringRef identifier, const CPPType BLI_assert_unreachable(); } else { - const CPPType &expected_type = *socket_cpp_type_get(*found_socket->typeinfo); + const CPPType &expected_type = *found_socket->typeinfo->get_geometry_nodes_cpp_type(); if (value_type != expected_type) { std::cout << "The value type '" << value_type.name() << "' is incorrect. Expected '" << expected_type.name() << "'.\n"; diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc index 8fdad0bb242..4be3fd2468b 100644 --- a/source/blender/nodes/intern/node_socket.cc +++ b/source/blender/nodes/intern/node_socket.cc @@ -607,60 +607,74 @@ static bNodeSocketType *make_socket_type_virtual() static bNodeSocketType *make_socket_type_bool() { bNodeSocketType *socktype = make_standard_socket_type(SOCK_BOOLEAN, PROP_NONE); - socktype->get_cpp_type = []() { return &blender::fn::CPPType::get(); }; - socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) { + socktype->get_base_cpp_type = []() { return &blender::fn::CPPType::get(); }; + socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) { *(bool *)r_value = ((bNodeSocketValueBoolean *)socket.default_value)->value; }; + socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type; + socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value; return socktype; } static bNodeSocketType *make_socket_type_float(PropertySubType subtype) { bNodeSocketType *socktype = make_standard_socket_type(SOCK_FLOAT, subtype); - socktype->get_cpp_type = []() { return &blender::fn::CPPType::get(); }; - socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) { + socktype->get_base_cpp_type = []() { return &blender::fn::CPPType::get(); }; + socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) { *(float *)r_value = ((bNodeSocketValueFloat *)socket.default_value)->value; }; + socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type; + socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value; return socktype; } static bNodeSocketType *make_socket_type_int(PropertySubType subtype) { bNodeSocketType *socktype = make_standard_socket_type(SOCK_INT, subtype); - socktype->get_cpp_type = []() { return &blender::fn::CPPType::get(); }; - socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) { + socktype->get_base_cpp_type = []() { return &blender::fn::CPPType::get(); }; + socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) { *(int *)r_value = ((bNodeSocketValueInt *)socket.default_value)->value; }; + socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type; + socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value; return socktype; } static bNodeSocketType *make_socket_type_vector(PropertySubType subtype) { bNodeSocketType *socktype = make_standard_socket_type(SOCK_VECTOR, subtype); - socktype->get_cpp_type = []() { return &blender::fn::CPPType::get(); }; - socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) { + socktype->get_base_cpp_type = []() { return &blender::fn::CPPType::get(); }; + socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) { *(blender::float3 *)r_value = ((bNodeSocketValueVector *)socket.default_value)->value; }; + socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type; + socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value; return socktype; } static bNodeSocketType *make_socket_type_rgba() { bNodeSocketType *socktype = make_standard_socket_type(SOCK_RGBA, PROP_NONE); - socktype->get_cpp_type = []() { return &blender::fn::CPPType::get(); }; - socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) { + socktype->get_base_cpp_type = []() { + return &blender::fn::CPPType::get(); + }; + socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) { *(blender::ColorGeometry4f *)r_value = ((bNodeSocketValueRGBA *)socket.default_value)->value; }; + socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type; + socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value; return socktype; } static bNodeSocketType *make_socket_type_string() { bNodeSocketType *socktype = make_standard_socket_type(SOCK_STRING, PROP_NONE); - socktype->get_cpp_type = []() { return &blender::fn::CPPType::get(); }; - socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) { + socktype->get_base_cpp_type = []() { return &blender::fn::CPPType::get(); }; + socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) { new (r_value) std::string(((bNodeSocketValueString *)socket.default_value)->value); }; + socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type; + socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value; return socktype; } @@ -672,50 +686,60 @@ MAKE_CPP_TYPE(Material, Material *, CPPTypeFlags::BasicType) static bNodeSocketType *make_socket_type_object() { bNodeSocketType *socktype = make_standard_socket_type(SOCK_OBJECT, PROP_NONE); - socktype->get_cpp_type = []() { return &blender::fn::CPPType::get(); }; - socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) { + socktype->get_base_cpp_type = []() { return &blender::fn::CPPType::get(); }; + socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) { *(Object **)r_value = ((bNodeSocketValueObject *)socket.default_value)->value; }; + socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type; + socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value; return socktype; } static bNodeSocketType *make_socket_type_geometry() { bNodeSocketType *socktype = make_standard_socket_type(SOCK_GEOMETRY, PROP_NONE); - socktype->get_cpp_type = []() { return &blender::fn::CPPType::get(); }; - socktype->get_cpp_value = [](const bNodeSocket &UNUSED(socket), void *r_value) { + socktype->get_base_cpp_type = []() { return &blender::fn::CPPType::get(); }; + socktype->get_base_cpp_value = [](const bNodeSocket &UNUSED(socket), void *r_value) { new (r_value) GeometrySet(); }; + socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type; + socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value; return socktype; } static bNodeSocketType *make_socket_type_collection() { bNodeSocketType *socktype = make_standard_socket_type(SOCK_COLLECTION, PROP_NONE); - socktype->get_cpp_type = []() { return &blender::fn::CPPType::get(); }; - socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) { + socktype->get_base_cpp_type = []() { return &blender::fn::CPPType::get(); }; + socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) { *(Collection **)r_value = ((bNodeSocketValueCollection *)socket.default_value)->value; }; + socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type; + socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value; return socktype; } static bNodeSocketType *make_socket_type_texture() { bNodeSocketType *socktype = make_standard_socket_type(SOCK_TEXTURE, PROP_NONE); - socktype->get_cpp_type = []() { return &blender::fn::CPPType::get(); }; - socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) { + socktype->get_base_cpp_type = []() { return &blender::fn::CPPType::get(); }; + socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) { *(Tex **)r_value = ((bNodeSocketValueTexture *)socket.default_value)->value; }; + socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type; + socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value; return socktype; } static bNodeSocketType *make_socket_type_material() { bNodeSocketType *socktype = make_standard_socket_type(SOCK_MATERIAL, PROP_NONE); - socktype->get_cpp_type = []() { return &blender::fn::CPPType::get(); }; - socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) { + socktype->get_base_cpp_type = []() { return &blender::fn::CPPType::get(); }; + socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) { *(Material **)r_value = ((bNodeSocketValueMaterial *)socket.default_value)->value; }; + socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type; + socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value; return socktype; } diff --git a/source/blender/nodes/intern/type_callbacks.cc b/source/blender/nodes/intern/type_callbacks.cc index 5160432aea5..881a02c92e9 100644 --- a/source/blender/nodes/intern/type_callbacks.cc +++ b/source/blender/nodes/intern/type_callbacks.cc @@ -19,17 +19,9 @@ namespace blender::nodes { -const CPPType *socket_cpp_type_get(const bNodeSocketType &stype) -{ - if (stype.get_cpp_type != nullptr) { - return stype.get_cpp_type(); - } - return nullptr; -} - std::optional socket_mf_type_get(const bNodeSocketType &stype) { - const CPPType *cpp_type = socket_cpp_type_get(stype); + const CPPType *cpp_type = stype.get_base_cpp_type ? stype.get_base_cpp_type() : nullptr; if (cpp_type != nullptr) { return MFDataType::ForSingle(*cpp_type); } @@ -41,32 +33,23 @@ bool socket_is_mf_data_socket(const bNodeSocketType &stype) if (!socket_mf_type_get(stype).has_value()) { return false; } - if (stype.expand_in_mf_network == nullptr && stype.get_cpp_value == nullptr) { + if (stype.expand_in_mf_network == nullptr && stype.get_base_cpp_value == nullptr) { return false; } return true; } -bool socket_cpp_value_get(const bNodeSocket &socket, void *r_value) -{ - if (socket.typeinfo->get_cpp_value != nullptr) { - socket.typeinfo->get_cpp_value(socket, r_value); - return true; - } - return false; -} - void socket_expand_in_mf_network(SocketMFNetworkBuilder &builder) { bNodeSocket &socket = builder.bsocket(); if (socket.typeinfo->expand_in_mf_network != nullptr) { socket.typeinfo->expand_in_mf_network(builder); } - else if (socket.typeinfo->get_cpp_value != nullptr) { - const CPPType &type = *socket_cpp_type_get(*socket.typeinfo); + else if (socket.typeinfo->get_base_cpp_value != nullptr) { + const CPPType &type = *socket.typeinfo->get_base_cpp_type(); void *buffer = builder.resource_scope().linear_allocator().allocate(type.size(), type.alignment()); - socket.typeinfo->get_cpp_value(socket, buffer); + socket.typeinfo->get_base_cpp_value(socket, buffer); builder.set_constant_value(type, buffer); } else { From 3fd5c93f9ce805b1a59bb6a03a9d39767697e336 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Mon, 2 Aug 2021 10:38:11 +0200 Subject: [PATCH 07/24] Geometry Nodes: increase threshold to make regression tests pass The real fix here is to use some kind of relative error in `customdata_compare` instead of the absolute error used now. If vertex coordinates get larger in magnitude, the allowed error should increase as well. --- tests/python/geo_node_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/python/geo_node_test.py b/tests/python/geo_node_test.py index fa87fb23bee..5da28977ba4 100644 --- a/tests/python/geo_node_test.py +++ b/tests/python/geo_node_test.py @@ -25,7 +25,7 @@ import sys sys.path.append(os.path.dirname(os.path.realpath(__file__))) from modules.mesh_test import BlendFileTest -geo_node_test = BlendFileTest("test_object", "expected_object") +geo_node_test = BlendFileTest("test_object", "expected_object", threshold=1e-4) result = geo_node_test.run_test() # Telling `ctest` about the failed test by raising Exception. From 1f0d6f763573b22772dcdb61320a12e1c11949e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Mon, 2 Aug 2021 11:02:47 +0200 Subject: [PATCH 08/24] Asset Catalogs: loading a catalog definition file Initial, limited implementation of loading a single asset catalog definition file. These files are structured as follows: CATALOG_ID virtual/path/of/catalog SUBCATALOG_ID virtual/path/of/catalog/child SOMETHING_ELSE some/unrelated/hierarchy These virtual paths will be used to show the catalog in a tree structure; the tree structure itself is not part of this commit. Each asset will have one catalog ID that determines where in that tree the asset shows up. Currently only a single catalog definition file can be read; merging data from multiple such files, and writing them out again after changes are made, is for future commits. This commit only contains the code to load a single file, and unittests to check that this actually works. No UI, no user-facing functionality yet. --- .../blender/blenkernel/BKE_asset_catalog.hh | 97 ++++++++++++ source/blender/blenkernel/CMakeLists.txt | 3 + .../blenkernel/intern/asset_catalog.cc | 148 ++++++++++++++++++ .../blenkernel/intern/asset_catalog_test.cc | 62 ++++++++ 4 files changed, 310 insertions(+) create mode 100644 source/blender/blenkernel/BKE_asset_catalog.hh create mode 100644 source/blender/blenkernel/intern/asset_catalog.cc create mode 100644 source/blender/blenkernel/intern/asset_catalog_test.cc diff --git a/source/blender/blenkernel/BKE_asset_catalog.hh b/source/blender/blenkernel/BKE_asset_catalog.hh new file mode 100644 index 00000000000..82449bcdbcc --- /dev/null +++ b/source/blender/blenkernel/BKE_asset_catalog.hh @@ -0,0 +1,97 @@ +/* + * 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. + */ + +/** \file + * \ingroup bke + */ + +#pragma once + +#ifndef __cplusplus +# error This is a C++ header. The C interface is yet to be implemented/designed. +#endif + +#include "BLI_map.hh" +#include "BLI_set.hh" +#include "BLI_string_ref.hh" +#include "BLI_vector_set.hh" + +#include +#include +#include + +namespace blender::bke { + +using CatalogID = std::string; +using CatalogPath = std::string; +using CatalogPathReference = StringRef; +using CatalogPathComponent = std::string; +using CatalogFilePath = std::filesystem::path; + +class AssetCatalog; +class AssetCatalogDefinitionFile; +class AssetCatalogTreeNode; + +/* Manages the asset catalogs of a single asset library (i.e. of catalogs defined in a single + * directory hierarchy). */ +class AssetCatalogService { + const char path_separator = '/'; + + /* TODO(@sybren): determine which properties should be private / get accessors. */ + + // These pointers are owned by this AssetCatalogService. + Map> catalogs; + std::unique_ptr catalog_definition_file; + + public: + AssetCatalogService(); + + // Return nullptr if not found. + AssetCatalog *find_catalog(const CatalogID &catalog_id); + + void load_from_disk(const CatalogFilePath &asset_library_root); + + protected: + void load_directory_recursive(const CatalogFilePath &directory_path); + void load_single_file(const CatalogFilePath &catalog_definition_file_path); + + std::unique_ptr parse_catalog_file( + const CatalogFilePath &catalog_definition_file_path); + + std::unique_ptr parse_catalog_line( + StringRef line, const AssetCatalogDefinitionFile *catalog_definition_file); +}; + +class AssetCatalogDefinitionFile { + /* TODO(@sybren): determine which properties should be private / get accessors. */ + public: + CatalogFilePath file_path; + Map catalogs; + + AssetCatalogDefinitionFile(); +}; + +class AssetCatalog { + /* TODO(@sybren): determine which properties should be private / get accessors. */ + public: + AssetCatalog(); + AssetCatalog(const CatalogID &catalog_id, const CatalogPath &name); + + CatalogID catalog_id; + CatalogPath path; +}; + +} // namespace blender::bke diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 78bfe8c9afb..7c02ffbc105 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -82,6 +82,7 @@ set(SRC intern/armature_deform.c intern/armature_pose.cc intern/armature_update.c + intern/asset_catalog.cc intern/asset.cc intern/attribute.c intern/attribute_access.cc @@ -298,6 +299,7 @@ set(SRC BKE_appdir.h BKE_armature.h BKE_armature.hh + BKE_asset_catalog.hh BKE_asset.h BKE_attribute.h BKE_attribute_access.hh @@ -771,6 +773,7 @@ if(WITH_GTESTS) set(TEST_SRC intern/action_test.cc intern/armature_test.cc + intern/asset_catalog_test.cc intern/cryptomatte_test.cc intern/fcurve_test.cc intern/lattice_deform_test.cc diff --git a/source/blender/blenkernel/intern/asset_catalog.cc b/source/blender/blenkernel/intern/asset_catalog.cc new file mode 100644 index 00000000000..0139b7a4abf --- /dev/null +++ b/source/blender/blenkernel/intern/asset_catalog.cc @@ -0,0 +1,148 @@ +/* + * 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. + */ + +/** \file + * \ingroup bke + */ + +#include "BKE_asset_catalog.hh" + +#include "BLI_string_ref.hh" + +#include +#include + +namespace fs = std::filesystem; + +namespace blender::bke { + +AssetCatalogService::AssetCatalogService() +{ +} + +AssetCatalog *AssetCatalogService::find_catalog(const CatalogID &catalog_id) +{ + std::unique_ptr *catalog_uptr_ptr = this->catalogs.lookup_ptr(catalog_id); + if (catalog_uptr_ptr == nullptr) { + return nullptr; + } + return catalog_uptr_ptr->get(); +} + +void AssetCatalogService::load_from_disk(const CatalogFilePath &asset_library_root) +{ + fs::file_status status = fs::status(asset_library_root); + switch (status.type()) { + case fs::file_type::regular: + load_single_file(asset_library_root); + break; + case fs::file_type::directory: + load_directory_recursive(asset_library_root); + break; + default: + // TODO(@sybren): throw an appropriate exception. + return; + } +} + +void AssetCatalogService::load_directory_recursive(const CatalogFilePath & /*directory_path*/) +{ + // TODO(@sybren): implement +} + +void AssetCatalogService::load_single_file(const CatalogFilePath &catalog_definition_file_path) +{ + std::unique_ptr cdf = parse_catalog_file( + catalog_definition_file_path); + + BLI_assert_msg(!this->catalog_definition_file, + "Only loading of a single catalog definition file is supported."); + this->catalog_definition_file = std::move(cdf); +} + +std::unique_ptr AssetCatalogService::parse_catalog_file( + const CatalogFilePath &catalog_definition_file_path) +{ + auto cdf = std::make_unique(); + cdf->file_path = catalog_definition_file_path; + + std::fstream infile(catalog_definition_file_path); + std::string line; + while (std::getline(infile, line)) { + const StringRef trimmed_line = StringRef(line).trim().trim(path_separator); + if (trimmed_line.is_empty() || trimmed_line[0] == '#') { + continue; + } + + std::unique_ptr catalog = this->parse_catalog_line(trimmed_line, cdf.get()); + + const bool is_catalog_id_reused_in_file = cdf->catalogs.contains(catalog->catalog_id); + /* The AssetDefinitionFile should include this catalog when writing it back to disk, even if it + * was a duplicate. */ + cdf->catalogs.add_new(catalog->catalog_id, catalog.get()); + + if (is_catalog_id_reused_in_file) { + std::cerr << catalog_definition_file_path << ": multiple definitions of catalog " + << catalog->catalog_id << ", using first occurrence." << std::endl; + /* Don't store 'catalog'; unique_ptr will free its memory. */ + continue; + } + + if (this->catalogs.contains(catalog->catalog_id)) { + // TODO(@sybren): apparently another CDF was already loaded. This is not supported yet. + std::cerr << catalog_definition_file_path << ": multiple definitions of catalog " + << catalog->catalog_id << " in multiple files, ignoring this one." << std::endl; + /* Don't store 'catalog'; unique_ptr will free its memory. */ + continue; + } + + /* The AssetCatalog pointer is owned by the AssetCatalogService. */ + this->catalogs.add_new(catalog->catalog_id, std::move(catalog)); + } + + return cdf; +} + +std::unique_ptr AssetCatalogService::parse_catalog_line( + const StringRef line, const AssetCatalogDefinitionFile *catalog_definition_file) +{ + const int64_t first_space = line.find_first_of(' '); + if (first_space == StringRef::not_found) { + std::cerr << "Invalid line in " << catalog_definition_file->file_path << ": " << line + << std::endl; + return std::unique_ptr(nullptr); + } + + const StringRef catalog_id = line.substr(0, first_space); + const StringRef catalog_path = line.substr(first_space + 1).trim().trim(path_separator); + + return std::make_unique(catalog_id, catalog_path); +} + +AssetCatalogDefinitionFile::AssetCatalogDefinitionFile() +{ +} + +AssetCatalog::AssetCatalog() +{ +} + +AssetCatalog::AssetCatalog(const CatalogID &catalog_id, const CatalogPath &path) + : catalog_id(catalog_id), path(path) +{ +} + +} // namespace blender::bke diff --git a/source/blender/blenkernel/intern/asset_catalog_test.cc b/source/blender/blenkernel/intern/asset_catalog_test.cc new file mode 100644 index 00000000000..d6c00670bd6 --- /dev/null +++ b/source/blender/blenkernel/intern/asset_catalog_test.cc @@ -0,0 +1,62 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 Blender Foundation + * All rights reserved. + */ + +#include "BKE_asset_catalog.hh" + +#include "testing/testing.h" + +#include + +namespace fs = std::filesystem; + +namespace blender::bke::tests { + +TEST(AssetCatalogTest, load_single_file) +{ + const fs::path test_files_dir = blender::tests::flags_test_asset_dir(); + if (test_files_dir.empty()) { + FAIL(); + } + + AssetCatalogService service; + service.load_from_disk(test_files_dir / "asset_library/single_catalog_definition_file.cats.txt"); + + // Test getting a non-existant catalog ID. + EXPECT_EQ(nullptr, service.find_catalog("NONEXISTANT")); + + // Test getting a 7-bit ASCII catalog ID. + AssetCatalog *poses_elly = service.find_catalog("POSES_ELLY"); + ASSERT_NE(nullptr, poses_elly); + EXPECT_EQ("POSES_ELLY", poses_elly->catalog_id); + EXPECT_EQ("character/Elly/poselib", poses_elly->path); + + // Test whitespace stripping. + AssetCatalog *poses_whitespace = service.find_catalog("POSES_ELLY_WHITESPACE"); + ASSERT_NE(nullptr, poses_whitespace); + EXPECT_EQ("POSES_ELLY_WHITESPACE", poses_whitespace->catalog_id); + EXPECT_EQ("character/Elly/poselib/whitespace", poses_whitespace->path); + + // Test getting a UTF-8 catalog ID. + AssetCatalog *poses_ruzena = service.find_catalog("POSES_RUŽENA"); + ASSERT_NE(nullptr, poses_ruzena); + EXPECT_EQ("POSES_RUŽENA", poses_ruzena->catalog_id); + EXPECT_EQ("character/Ružena/poselib", poses_ruzena->path); +} + +} // namespace blender::bke::tests From 06cb48e1b284e6438ce14f1ea543143fcc74ca59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Mon, 2 Aug 2021 11:15:50 +0200 Subject: [PATCH 09/24] Cleanup: Asset catalogs, C++ to C-style comments No functional changes. --- source/blender/blenkernel/BKE_asset_catalog.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/BKE_asset_catalog.hh b/source/blender/blenkernel/BKE_asset_catalog.hh index 82449bcdbcc..981c5338469 100644 --- a/source/blender/blenkernel/BKE_asset_catalog.hh +++ b/source/blender/blenkernel/BKE_asset_catalog.hh @@ -52,14 +52,14 @@ class AssetCatalogService { /* TODO(@sybren): determine which properties should be private / get accessors. */ - // These pointers are owned by this AssetCatalogService. + /* These pointers are owned by this AssetCatalogService. */ Map> catalogs; std::unique_ptr catalog_definition_file; public: AssetCatalogService(); - // Return nullptr if not found. + /* Return nullptr if not found. */ AssetCatalog *find_catalog(const CatalogID &catalog_id); void load_from_disk(const CatalogFilePath &asset_library_root); From aa60416361364f56f9a173db9649e36f81442ce3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Mon, 2 Aug 2021 12:07:40 +0200 Subject: [PATCH 10/24] Revert "Asset Catalogs: loading a catalog definition file" This reverts commit 1f0d6f763573b22772dcdb61320a12e1c11949e0 and the cleanup 06cb48e1b284e6438ce14f1ea543143fcc74ca59. Committed too early on Monday morning, still has issues that should be resolved first. --- .../blender/blenkernel/BKE_asset_catalog.hh | 97 ------------ source/blender/blenkernel/CMakeLists.txt | 3 - .../blenkernel/intern/asset_catalog.cc | 148 ------------------ .../blenkernel/intern/asset_catalog_test.cc | 62 -------- 4 files changed, 310 deletions(-) delete mode 100644 source/blender/blenkernel/BKE_asset_catalog.hh delete mode 100644 source/blender/blenkernel/intern/asset_catalog.cc delete mode 100644 source/blender/blenkernel/intern/asset_catalog_test.cc diff --git a/source/blender/blenkernel/BKE_asset_catalog.hh b/source/blender/blenkernel/BKE_asset_catalog.hh deleted file mode 100644 index 981c5338469..00000000000 --- a/source/blender/blenkernel/BKE_asset_catalog.hh +++ /dev/null @@ -1,97 +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. - */ - -/** \file - * \ingroup bke - */ - -#pragma once - -#ifndef __cplusplus -# error This is a C++ header. The C interface is yet to be implemented/designed. -#endif - -#include "BLI_map.hh" -#include "BLI_set.hh" -#include "BLI_string_ref.hh" -#include "BLI_vector_set.hh" - -#include -#include -#include - -namespace blender::bke { - -using CatalogID = std::string; -using CatalogPath = std::string; -using CatalogPathReference = StringRef; -using CatalogPathComponent = std::string; -using CatalogFilePath = std::filesystem::path; - -class AssetCatalog; -class AssetCatalogDefinitionFile; -class AssetCatalogTreeNode; - -/* Manages the asset catalogs of a single asset library (i.e. of catalogs defined in a single - * directory hierarchy). */ -class AssetCatalogService { - const char path_separator = '/'; - - /* TODO(@sybren): determine which properties should be private / get accessors. */ - - /* These pointers are owned by this AssetCatalogService. */ - Map> catalogs; - std::unique_ptr catalog_definition_file; - - public: - AssetCatalogService(); - - /* Return nullptr if not found. */ - AssetCatalog *find_catalog(const CatalogID &catalog_id); - - void load_from_disk(const CatalogFilePath &asset_library_root); - - protected: - void load_directory_recursive(const CatalogFilePath &directory_path); - void load_single_file(const CatalogFilePath &catalog_definition_file_path); - - std::unique_ptr parse_catalog_file( - const CatalogFilePath &catalog_definition_file_path); - - std::unique_ptr parse_catalog_line( - StringRef line, const AssetCatalogDefinitionFile *catalog_definition_file); -}; - -class AssetCatalogDefinitionFile { - /* TODO(@sybren): determine which properties should be private / get accessors. */ - public: - CatalogFilePath file_path; - Map catalogs; - - AssetCatalogDefinitionFile(); -}; - -class AssetCatalog { - /* TODO(@sybren): determine which properties should be private / get accessors. */ - public: - AssetCatalog(); - AssetCatalog(const CatalogID &catalog_id, const CatalogPath &name); - - CatalogID catalog_id; - CatalogPath path; -}; - -} // namespace blender::bke diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 7c02ffbc105..78bfe8c9afb 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -82,7 +82,6 @@ set(SRC intern/armature_deform.c intern/armature_pose.cc intern/armature_update.c - intern/asset_catalog.cc intern/asset.cc intern/attribute.c intern/attribute_access.cc @@ -299,7 +298,6 @@ set(SRC BKE_appdir.h BKE_armature.h BKE_armature.hh - BKE_asset_catalog.hh BKE_asset.h BKE_attribute.h BKE_attribute_access.hh @@ -773,7 +771,6 @@ if(WITH_GTESTS) set(TEST_SRC intern/action_test.cc intern/armature_test.cc - intern/asset_catalog_test.cc intern/cryptomatte_test.cc intern/fcurve_test.cc intern/lattice_deform_test.cc diff --git a/source/blender/blenkernel/intern/asset_catalog.cc b/source/blender/blenkernel/intern/asset_catalog.cc deleted file mode 100644 index 0139b7a4abf..00000000000 --- a/source/blender/blenkernel/intern/asset_catalog.cc +++ /dev/null @@ -1,148 +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. - */ - -/** \file - * \ingroup bke - */ - -#include "BKE_asset_catalog.hh" - -#include "BLI_string_ref.hh" - -#include -#include - -namespace fs = std::filesystem; - -namespace blender::bke { - -AssetCatalogService::AssetCatalogService() -{ -} - -AssetCatalog *AssetCatalogService::find_catalog(const CatalogID &catalog_id) -{ - std::unique_ptr *catalog_uptr_ptr = this->catalogs.lookup_ptr(catalog_id); - if (catalog_uptr_ptr == nullptr) { - return nullptr; - } - return catalog_uptr_ptr->get(); -} - -void AssetCatalogService::load_from_disk(const CatalogFilePath &asset_library_root) -{ - fs::file_status status = fs::status(asset_library_root); - switch (status.type()) { - case fs::file_type::regular: - load_single_file(asset_library_root); - break; - case fs::file_type::directory: - load_directory_recursive(asset_library_root); - break; - default: - // TODO(@sybren): throw an appropriate exception. - return; - } -} - -void AssetCatalogService::load_directory_recursive(const CatalogFilePath & /*directory_path*/) -{ - // TODO(@sybren): implement -} - -void AssetCatalogService::load_single_file(const CatalogFilePath &catalog_definition_file_path) -{ - std::unique_ptr cdf = parse_catalog_file( - catalog_definition_file_path); - - BLI_assert_msg(!this->catalog_definition_file, - "Only loading of a single catalog definition file is supported."); - this->catalog_definition_file = std::move(cdf); -} - -std::unique_ptr AssetCatalogService::parse_catalog_file( - const CatalogFilePath &catalog_definition_file_path) -{ - auto cdf = std::make_unique(); - cdf->file_path = catalog_definition_file_path; - - std::fstream infile(catalog_definition_file_path); - std::string line; - while (std::getline(infile, line)) { - const StringRef trimmed_line = StringRef(line).trim().trim(path_separator); - if (trimmed_line.is_empty() || trimmed_line[0] == '#') { - continue; - } - - std::unique_ptr catalog = this->parse_catalog_line(trimmed_line, cdf.get()); - - const bool is_catalog_id_reused_in_file = cdf->catalogs.contains(catalog->catalog_id); - /* The AssetDefinitionFile should include this catalog when writing it back to disk, even if it - * was a duplicate. */ - cdf->catalogs.add_new(catalog->catalog_id, catalog.get()); - - if (is_catalog_id_reused_in_file) { - std::cerr << catalog_definition_file_path << ": multiple definitions of catalog " - << catalog->catalog_id << ", using first occurrence." << std::endl; - /* Don't store 'catalog'; unique_ptr will free its memory. */ - continue; - } - - if (this->catalogs.contains(catalog->catalog_id)) { - // TODO(@sybren): apparently another CDF was already loaded. This is not supported yet. - std::cerr << catalog_definition_file_path << ": multiple definitions of catalog " - << catalog->catalog_id << " in multiple files, ignoring this one." << std::endl; - /* Don't store 'catalog'; unique_ptr will free its memory. */ - continue; - } - - /* The AssetCatalog pointer is owned by the AssetCatalogService. */ - this->catalogs.add_new(catalog->catalog_id, std::move(catalog)); - } - - return cdf; -} - -std::unique_ptr AssetCatalogService::parse_catalog_line( - const StringRef line, const AssetCatalogDefinitionFile *catalog_definition_file) -{ - const int64_t first_space = line.find_first_of(' '); - if (first_space == StringRef::not_found) { - std::cerr << "Invalid line in " << catalog_definition_file->file_path << ": " << line - << std::endl; - return std::unique_ptr(nullptr); - } - - const StringRef catalog_id = line.substr(0, first_space); - const StringRef catalog_path = line.substr(first_space + 1).trim().trim(path_separator); - - return std::make_unique(catalog_id, catalog_path); -} - -AssetCatalogDefinitionFile::AssetCatalogDefinitionFile() -{ -} - -AssetCatalog::AssetCatalog() -{ -} - -AssetCatalog::AssetCatalog(const CatalogID &catalog_id, const CatalogPath &path) - : catalog_id(catalog_id), path(path) -{ -} - -} // namespace blender::bke diff --git a/source/blender/blenkernel/intern/asset_catalog_test.cc b/source/blender/blenkernel/intern/asset_catalog_test.cc deleted file mode 100644 index d6c00670bd6..00000000000 --- a/source/blender/blenkernel/intern/asset_catalog_test.cc +++ /dev/null @@ -1,62 +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. - * - * The Original Code is Copyright (C) 2020 Blender Foundation - * All rights reserved. - */ - -#include "BKE_asset_catalog.hh" - -#include "testing/testing.h" - -#include - -namespace fs = std::filesystem; - -namespace blender::bke::tests { - -TEST(AssetCatalogTest, load_single_file) -{ - const fs::path test_files_dir = blender::tests::flags_test_asset_dir(); - if (test_files_dir.empty()) { - FAIL(); - } - - AssetCatalogService service; - service.load_from_disk(test_files_dir / "asset_library/single_catalog_definition_file.cats.txt"); - - // Test getting a non-existant catalog ID. - EXPECT_EQ(nullptr, service.find_catalog("NONEXISTANT")); - - // Test getting a 7-bit ASCII catalog ID. - AssetCatalog *poses_elly = service.find_catalog("POSES_ELLY"); - ASSERT_NE(nullptr, poses_elly); - EXPECT_EQ("POSES_ELLY", poses_elly->catalog_id); - EXPECT_EQ("character/Elly/poselib", poses_elly->path); - - // Test whitespace stripping. - AssetCatalog *poses_whitespace = service.find_catalog("POSES_ELLY_WHITESPACE"); - ASSERT_NE(nullptr, poses_whitespace); - EXPECT_EQ("POSES_ELLY_WHITESPACE", poses_whitespace->catalog_id); - EXPECT_EQ("character/Elly/poselib/whitespace", poses_whitespace->path); - - // Test getting a UTF-8 catalog ID. - AssetCatalog *poses_ruzena = service.find_catalog("POSES_RUŽENA"); - ASSERT_NE(nullptr, poses_ruzena); - EXPECT_EQ("POSES_RUŽENA", poses_ruzena->catalog_id); - EXPECT_EQ("character/Ružena/poselib", poses_ruzena->path); -} - -} // namespace blender::bke::tests From 8edb2222ae0c954771a9cddc2d8c02a7a4d68eae Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Mon, 2 Aug 2021 12:43:35 +0200 Subject: [PATCH 11/24] Cleanup: simplify subclassing CPPType `CPPType` can wrap any C++ type so that code can work with the wrapped type in a generic way. The goal of subclassing `CPPType` is to provide additional methods for some types. For example, the `CPPType` for `Array` could have a `.element_type()` method that returns the `CPPType` for `int`. --- source/blender/functions/FN_cpp_type.hh | 196 +++++++++--------- source/blender/functions/FN_cpp_type_make.hh | 96 ++++----- .../multi_function_network_optimization.cc | 2 +- 3 files changed, 142 insertions(+), 152 deletions(-) diff --git a/source/blender/functions/FN_cpp_type.hh b/source/blender/functions/FN_cpp_type.hh index bc3f398c8e9..7277bf99c12 100644 --- a/source/blender/functions/FN_cpp_type.hh +++ b/source/blender/functions/FN_cpp_type.hh @@ -70,64 +70,73 @@ #include "BLI_string_ref.hh" #include "BLI_utility_mixins.hh" +/** + * Different types support different features. Features like copy constructability can be detected + * automatically easily. For some features this is harder as of C++17. Those have flags in this + * enum and need to be determined by the programmer. + */ +enum class CPPTypeFlags { + None = 0, + Hashable = 1 << 0, + Printable = 1 << 1, + EqualityComparable = 1 << 2, + + BasicType = Hashable | Printable | EqualityComparable, +}; +ENUM_OPERATORS(CPPTypeFlags, CPPTypeFlags::EqualityComparable) + namespace blender::fn { -struct CPPTypeMembers { - int64_t size = 0; - int64_t alignment = 0; - uintptr_t alignment_mask = 0; - bool is_trivially_destructible = false; - bool has_special_member_functions = false; - - void (*default_construct)(void *ptr) = nullptr; - void (*default_construct_indices)(void *ptr, IndexMask mask) = nullptr; - - void (*destruct)(void *ptr) = nullptr; - void (*destruct_indices)(void *ptr, IndexMask mask) = nullptr; - - void (*copy_assign)(const void *src, void *dst) = nullptr; - void (*copy_assign_indices)(const void *src, void *dst, IndexMask mask) = nullptr; - - void (*copy_construct)(const void *src, void *dst) = nullptr; - void (*copy_construct_indices)(const void *src, void *dst, IndexMask mask) = nullptr; - - void (*move_assign)(void *src, void *dst) = nullptr; - void (*move_assign_indices)(void *src, void *dst, IndexMask mask) = nullptr; - - void (*move_construct)(void *src, void *dst) = nullptr; - void (*move_construct_indices)(void *src, void *dst, IndexMask mask) = nullptr; - - void (*relocate_assign)(void *src, void *dst) = nullptr; - void (*relocate_assign_indices)(void *src, void *dst, IndexMask mask) = nullptr; - - void (*relocate_construct)(void *src, void *dst) = nullptr; - void (*relocate_construct_indices)(void *src, void *dst, IndexMask mask) = nullptr; - - void (*fill_assign_indices)(const void *value, void *dst, IndexMask mask) = nullptr; - - void (*fill_construct_indices)(const void *value, void *dst, IndexMask mask) = nullptr; - - void (*print)(const void *value, std::stringstream &ss) = nullptr; - bool (*is_equal)(const void *a, const void *b) = nullptr; - uint64_t (*hash)(const void *value) = nullptr; - - const void *default_value = nullptr; - std::string name; +/** Utility class to pass template parameters to constructor of `CPPType`. */ +template struct CPPTypeParam { }; class CPPType : NonCopyable, NonMovable { private: - CPPTypeMembers m_; + int64_t size_ = 0; + int64_t alignment_ = 0; + uintptr_t alignment_mask_ = 0; + bool is_trivially_destructible_ = false; + bool has_special_member_functions_ = false; + + void (*default_construct_)(void *ptr) = nullptr; + void (*default_construct_indices_)(void *ptr, IndexMask mask) = nullptr; + + void (*destruct_)(void *ptr) = nullptr; + void (*destruct_indices_)(void *ptr, IndexMask mask) = nullptr; + + void (*copy_assign_)(const void *src, void *dst) = nullptr; + void (*copy_assign_indices_)(const void *src, void *dst, IndexMask mask) = nullptr; + + void (*copy_construct_)(const void *src, void *dst) = nullptr; + void (*copy_construct_indices_)(const void *src, void *dst, IndexMask mask) = nullptr; + + void (*move_assign_)(void *src, void *dst) = nullptr; + void (*move_assign_indices_)(void *src, void *dst, IndexMask mask) = nullptr; + + void (*move_construct_)(void *src, void *dst) = nullptr; + void (*move_construct_indices_)(void *src, void *dst, IndexMask mask) = nullptr; + + void (*relocate_assign_)(void *src, void *dst) = nullptr; + void (*relocate_assign_indices_)(void *src, void *dst, IndexMask mask) = nullptr; + + void (*relocate_construct_)(void *src, void *dst) = nullptr; + void (*relocate_construct_indices_)(void *src, void *dst, IndexMask mask) = nullptr; + + void (*fill_assign_indices_)(const void *value, void *dst, IndexMask mask) = nullptr; + + void (*fill_construct_indices_)(const void *value, void *dst, IndexMask mask) = nullptr; + + void (*print_)(const void *value, std::stringstream &ss) = nullptr; + bool (*is_equal_)(const void *a, const void *b) = nullptr; + uint64_t (*hash_)(const void *value) = nullptr; + + const void *default_value_ = nullptr; + std::string debug_name_; public: - CPPType(CPPTypeMembers members) : m_(std::move(members)) - { - BLI_assert(is_power_of_2_i(m_.alignment)); - m_.alignment_mask = (uintptr_t)members.alignment - (uintptr_t)1; - m_.has_special_member_functions = (m_.default_construct && m_.copy_construct && - m_.copy_assign && m_.move_construct && m_.move_assign && - m_.destruct); - } + template CPPType(CPPTypeParam, StringRef debug_name); + virtual ~CPPType() = default; /** * Two types only compare equal when their pointer is equal. No two instances of CPPType for the @@ -148,7 +157,11 @@ class CPPType : NonCopyable, NonMovable { * This only works for types that actually implement the template specialization using * `MAKE_CPP_TYPE`. */ - template static const CPPType &get(); + template static const CPPType &get() + { + return CPPType::get_impl>(); + } + template static const CPPType &get_impl(); /** * Returns the name of the type for debugging purposes. This name should not be used as @@ -156,7 +169,7 @@ class CPPType : NonCopyable, NonMovable { */ StringRefNull name() const { - return m_.name; + return debug_name_; } /** @@ -167,7 +180,7 @@ class CPPType : NonCopyable, NonMovable { */ int64_t size() const { - return m_.size; + return size_; } /** @@ -178,7 +191,7 @@ class CPPType : NonCopyable, NonMovable { */ int64_t alignment() const { - return m_.alignment; + return alignment_; } /** @@ -190,52 +203,52 @@ class CPPType : NonCopyable, NonMovable { */ bool is_trivially_destructible() const { - return m_.is_trivially_destructible; + return is_trivially_destructible_; } bool is_default_constructible() const { - return m_.default_construct != nullptr; + return default_construct_ != nullptr; } bool is_copy_constructible() const { - return m_.copy_assign != nullptr; + return copy_assign_ != nullptr; } bool is_move_constructible() const { - return m_.move_assign != nullptr; + return move_assign_ != nullptr; } bool is_destructible() const { - return m_.destruct != nullptr; + return destruct_ != nullptr; } bool is_copy_assignable() const { - return m_.copy_assign != nullptr; + return copy_assign_ != nullptr; } bool is_move_assignable() const { - return m_.copy_construct != nullptr; + return copy_construct_ != nullptr; } bool is_printable() const { - return m_.print != nullptr; + return print_ != nullptr; } bool is_equality_comparable() const { - return m_.is_equal != nullptr; + return is_equal_ != nullptr; } bool is_hashable() const { - return m_.hash != nullptr; + return hash_ != nullptr; } /** @@ -249,7 +262,7 @@ class CPPType : NonCopyable, NonMovable { */ bool has_special_member_functions() const { - return m_.has_special_member_functions; + return has_special_member_functions_; } /** @@ -257,7 +270,7 @@ class CPPType : NonCopyable, NonMovable { */ bool pointer_has_valid_alignment(const void *ptr) const { - return ((uintptr_t)ptr & m_.alignment_mask) == 0; + return ((uintptr_t)ptr & alignment_mask_) == 0; } bool pointer_can_point_to_instance(const void *ptr) const @@ -277,7 +290,7 @@ class CPPType : NonCopyable, NonMovable { { BLI_assert(this->pointer_can_point_to_instance(ptr)); - m_.default_construct(ptr); + default_construct_(ptr); } void default_construct_n(void *ptr, int64_t n) const @@ -289,7 +302,7 @@ class CPPType : NonCopyable, NonMovable { { BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(ptr)); - m_.default_construct_indices(ptr, mask); + default_construct_indices_(ptr, mask); } /** @@ -304,7 +317,7 @@ class CPPType : NonCopyable, NonMovable { { BLI_assert(this->pointer_can_point_to_instance(ptr)); - m_.destruct(ptr); + destruct_(ptr); } void destruct_n(void *ptr, int64_t n) const @@ -316,7 +329,7 @@ class CPPType : NonCopyable, NonMovable { { BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(ptr)); - m_.destruct_indices(ptr, mask); + destruct_indices_(ptr, mask); } /** @@ -331,7 +344,7 @@ class CPPType : NonCopyable, NonMovable { BLI_assert(this->pointer_can_point_to_instance(src)); BLI_assert(this->pointer_can_point_to_instance(dst)); - m_.copy_assign(src, dst); + copy_assign_(src, dst); } void copy_assign_n(const void *src, void *dst, int64_t n) const @@ -345,7 +358,7 @@ class CPPType : NonCopyable, NonMovable { BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src)); BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst)); - m_.copy_assign_indices(src, dst, mask); + copy_assign_indices_(src, dst, mask); } /** @@ -362,7 +375,7 @@ class CPPType : NonCopyable, NonMovable { BLI_assert(this->pointer_can_point_to_instance(src)); BLI_assert(this->pointer_can_point_to_instance(dst)); - m_.copy_construct(src, dst); + copy_construct_(src, dst); } void copy_construct_n(const void *src, void *dst, int64_t n) const @@ -376,7 +389,7 @@ class CPPType : NonCopyable, NonMovable { BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src)); BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst)); - m_.copy_construct_indices(src, dst, mask); + copy_construct_indices_(src, dst, mask); } /** @@ -393,7 +406,7 @@ class CPPType : NonCopyable, NonMovable { BLI_assert(this->pointer_can_point_to_instance(src)); BLI_assert(this->pointer_can_point_to_instance(dst)); - m_.move_assign(src, dst); + move_assign_(src, dst); } void move_assign_n(void *src, void *dst, int64_t n) const @@ -407,7 +420,7 @@ class CPPType : NonCopyable, NonMovable { BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src)); BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst)); - m_.move_assign_indices(src, dst, mask); + move_assign_indices_(src, dst, mask); } /** @@ -424,7 +437,7 @@ class CPPType : NonCopyable, NonMovable { BLI_assert(this->pointer_can_point_to_instance(src)); BLI_assert(this->pointer_can_point_to_instance(dst)); - m_.move_construct(src, dst); + move_construct_(src, dst); } void move_construct_n(void *src, void *dst, int64_t n) const @@ -438,7 +451,7 @@ class CPPType : NonCopyable, NonMovable { BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src)); BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst)); - m_.move_construct_indices(src, dst, mask); + move_construct_indices_(src, dst, mask); } /** @@ -455,7 +468,7 @@ class CPPType : NonCopyable, NonMovable { BLI_assert(this->pointer_can_point_to_instance(src)); BLI_assert(this->pointer_can_point_to_instance(dst)); - m_.relocate_assign(src, dst); + relocate_assign_(src, dst); } void relocate_assign_n(void *src, void *dst, int64_t n) const @@ -469,7 +482,7 @@ class CPPType : NonCopyable, NonMovable { BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src)); BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst)); - m_.relocate_assign_indices(src, dst, mask); + relocate_assign_indices_(src, dst, mask); } /** @@ -486,7 +499,7 @@ class CPPType : NonCopyable, NonMovable { BLI_assert(this->pointer_can_point_to_instance(src)); BLI_assert(this->pointer_can_point_to_instance(dst)); - m_.relocate_construct(src, dst); + relocate_construct_(src, dst); } void relocate_construct_n(void *src, void *dst, int64_t n) const @@ -500,7 +513,7 @@ class CPPType : NonCopyable, NonMovable { BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src)); BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst)); - m_.relocate_construct_indices(src, dst, mask); + relocate_construct_indices_(src, dst, mask); } /** @@ -518,7 +531,7 @@ class CPPType : NonCopyable, NonMovable { BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(value)); BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst)); - m_.fill_assign_indices(value, dst, mask); + fill_assign_indices_(value, dst, mask); } /** @@ -536,13 +549,13 @@ class CPPType : NonCopyable, NonMovable { BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(value)); BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst)); - m_.fill_construct_indices(value, dst, mask); + fill_construct_indices_(value, dst, mask); } void print(const void *value, std::stringstream &ss) const { BLI_assert(this->pointer_can_point_to_instance(value)); - m_.print(value, ss); + print_(value, ss); } std::string to_string(const void *value) const @@ -566,7 +579,7 @@ class CPPType : NonCopyable, NonMovable { { BLI_assert(this->pointer_can_point_to_instance(a)); BLI_assert(this->pointer_can_point_to_instance(b)); - return m_.is_equal(a, b); + return is_equal_(a, b); } bool is_equal_or_false(const void *a, const void *b) const @@ -580,7 +593,7 @@ class CPPType : NonCopyable, NonMovable { uint64_t hash(const void *value) const { BLI_assert(this->pointer_can_point_to_instance(value)); - return m_.hash(value); + return hash_(value); } uint64_t hash_or_fallback(const void *value, uint64_t fallback_hash) const @@ -597,7 +610,7 @@ class CPPType : NonCopyable, NonMovable { */ const void *default_value() const { - return m_.default_value; + return default_value_; } uint64_t hash() const @@ -605,12 +618,9 @@ class CPPType : NonCopyable, NonMovable { return get_default_hash(this); } - /** - * Low level access to the callbacks for this CPPType. - */ - const CPPTypeMembers &members() const + void (*destruct_fn() const)(void *) { - return m_; + return destruct_; } template bool is() const diff --git a/source/blender/functions/FN_cpp_type_make.hh b/source/blender/functions/FN_cpp_type_make.hh index b8e5373ccf7..088f6b469f4 100644 --- a/source/blender/functions/FN_cpp_type_make.hh +++ b/source/blender/functions/FN_cpp_type_make.hh @@ -185,100 +185,80 @@ template uint64_t hash_cb(const void *value) } // namespace blender::fn::cpp_type_util -/** - * Different types support different features. Features like copy constructability can be detected - * automatically easily. For some features this is harder as of C++17. Those have flags in this - * enum and need to be determined by the programmer. - */ -enum class CPPTypeFlags { - None = 0, - Hashable = 1 << 0, - Printable = 1 << 1, - EqualityComparable = 1 << 2, - - BasicType = Hashable | Printable | EqualityComparable, -}; -ENUM_OPERATORS(CPPTypeFlags, CPPTypeFlags::EqualityComparable) - namespace blender::fn { -template -inline std::unique_ptr create_cpp_type(StringRef name) +template +CPPType::CPPType(CPPTypeParam /* unused */, StringRef debug_name) { using namespace cpp_type_util; - CPPTypeMembers m; - m.name = name; - m.size = (int64_t)sizeof(T); - m.alignment = (int64_t)alignof(T); - m.is_trivially_destructible = std::is_trivially_destructible_v; + debug_name_ = debug_name; + size_ = (int64_t)sizeof(T); + alignment_ = (int64_t)alignof(T); + is_trivially_destructible_ = std::is_trivially_destructible_v; if constexpr (std::is_default_constructible_v) { - m.default_construct = default_construct_cb; - m.default_construct_indices = default_construct_indices_cb; + default_construct_ = default_construct_cb; + default_construct_indices_ = default_construct_indices_cb; static T default_value; - m.default_value = (void *)&default_value; + default_value_ = (void *)&default_value; } if constexpr (std::is_destructible_v) { - m.destruct = destruct_cb; - m.destruct_indices = destruct_indices_cb; + destruct_ = destruct_cb; + destruct_indices_ = destruct_indices_cb; } if constexpr (std::is_copy_assignable_v) { - m.copy_assign = copy_assign_cb; - m.copy_assign_indices = copy_assign_indices_cb; + copy_assign_ = copy_assign_cb; + copy_assign_indices_ = copy_assign_indices_cb; } if constexpr (std::is_copy_constructible_v) { - m.copy_construct = copy_construct_cb; - m.copy_construct_indices = copy_construct_indices_cb; + copy_construct_ = copy_construct_cb; + copy_construct_indices_ = copy_construct_indices_cb; } if constexpr (std::is_move_assignable_v) { - m.move_assign = move_assign_cb; - m.move_assign_indices = move_assign_indices_cb; + move_assign_ = move_assign_cb; + move_assign_indices_ = move_assign_indices_cb; } if constexpr (std::is_move_constructible_v) { - m.move_construct = move_construct_cb; - m.move_construct_indices = move_construct_indices_cb; + move_construct_ = move_construct_cb; + move_construct_indices_ = move_construct_indices_cb; } if constexpr (std::is_destructible_v) { if constexpr (std::is_move_assignable_v) { - m.relocate_assign = relocate_assign_cb; - m.relocate_assign_indices = relocate_assign_indices_cb; + relocate_assign_ = relocate_assign_cb; + relocate_assign_indices_ = relocate_assign_indices_cb; } if constexpr (std::is_move_constructible_v) { - m.relocate_construct = relocate_construct_cb; - m.relocate_construct_indices = relocate_construct_indices_cb; + relocate_construct_ = relocate_construct_cb; + relocate_construct_indices_ = relocate_construct_indices_cb; } } if constexpr (std::is_copy_assignable_v) { - m.fill_assign_indices = fill_assign_indices_cb; + fill_assign_indices_ = fill_assign_indices_cb; } if constexpr (std::is_copy_constructible_v) { - m.fill_construct_indices = fill_construct_indices_cb; + fill_construct_indices_ = fill_construct_indices_cb; } - if constexpr ((bool)(flags & CPPTypeFlags::Hashable)) { - m.hash = hash_cb; + if constexpr ((bool)(Flags & CPPTypeFlags::Hashable)) { + hash_ = hash_cb; } - if constexpr ((bool)(flags & CPPTypeFlags::Printable)) { - m.print = print_cb; + if constexpr ((bool)(Flags & CPPTypeFlags::Printable)) { + print_ = print_cb; } - if constexpr ((bool)(flags & CPPTypeFlags::EqualityComparable)) { - m.is_equal = is_equal_cb; + if constexpr ((bool)(Flags & CPPTypeFlags::EqualityComparable)) { + is_equal_ = is_equal_cb; } - const CPPType *type = new CPPType(std::move(m)); - return std::unique_ptr(type); + alignment_mask_ = (uintptr_t)alignment_ - (uintptr_t)1; + has_special_member_functions_ = (default_construct_ && copy_construct_ && copy_assign_ && + move_construct_ && move_assign_ && destruct_); } } // namespace blender::fn #define MAKE_CPP_TYPE(IDENTIFIER, TYPE_NAME, FLAGS) \ - template<> const blender::fn::CPPType &blender::fn::CPPType::get() \ + template<> const blender::fn::CPPType &blender::fn::CPPType::get_impl() \ { \ - static std::unique_ptr cpp_type = \ - blender::fn::create_cpp_type(STRINGIFY(IDENTIFIER)); \ - return *cpp_type; \ - } \ - /* Support using `CPPType::get()`. Otherwise the caller would have to remove const. */ \ - template<> const blender::fn::CPPType &blender::fn::CPPType::get() \ - { \ - return blender::fn::CPPType::get(); \ + static CPPType cpp_type{blender::fn::CPPTypeParam(), \ + STRINGIFY(IDENTIFIER)}; \ + return cpp_type; \ } diff --git a/source/blender/functions/intern/multi_function_network_optimization.cc b/source/blender/functions/intern/multi_function_network_optimization.cc index 0f65d320f62..75c3583c5e5 100644 --- a/source/blender/functions/intern/multi_function_network_optimization.cc +++ b/source/blender/functions/intern/multi_function_network_optimization.cc @@ -263,7 +263,7 @@ static Array add_constant_folded_sockets(const MultiFunction & const CPPType &cpp_type = data_type.single_type(); GMutableSpan array = params.computed_array(param_index); void *buffer = array.data(); - scope.add(buffer, array.type().members().destruct, AT); + scope.add(buffer, array.type().destruct_fn(), AT); constant_fn = &scope.construct(AT, cpp_type, buffer); break; From d60a7a87445c140a42b6470ef2c54c411d8e4bf3 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 2 Aug 2021 15:09:15 +0200 Subject: [PATCH 12/24] WindowManager: Support Dynamic tooltips when dragging. Originally the operator name was drawn next to the dragging content. After that there was an option to add custom, static text with the dragging content. This patch allows dynamic text to be drawn. The custom text was implemented as out parameter of the poll function what made the code unclear. This patch introduces a tooltip function that separates tooltip generation from the poll function. NOTE: the text should always be returned in its own memory block. This block will be freed after it is copied in the drag struct. Reviewed By: Severin Differential Revision: https://developer.blender.org/D12104 --- source/blender/editors/include/UI_interface.h | 5 +- .../blender/editors/interface/interface_ops.c | 5 +- source/blender/editors/screen/screen_ops.c | 10 +- .../blender/editors/space_clip/space_clip.c | 7 +- .../editors/space_console/space_console.c | 14 +- .../blender/editors/space_file/space_file.c | 7 +- .../blender/editors/space_image/space_image.c | 7 +- .../blender/editors/space_node/space_node.c | 46 ++--- .../space_outliner/outliner_dragdrop.c | 168 ++++++++++-------- .../editors/space_sequencer/space_sequencer.c | 24 +-- .../blender/editors/space_text/space_text.c | 14 +- .../editors/space_view3d/space_view3d.c | 77 ++++---- source/blender/windowmanager/WM_api.h | 7 +- source/blender/windowmanager/WM_types.h | 16 +- .../windowmanager/intern/wm_dragdrop.c | 82 +++++---- .../windowmanager/intern/wm_event_system.c | 3 +- 16 files changed, 234 insertions(+), 258 deletions(-) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index a6e465d04e8..30be3588b5a 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -2577,10 +2577,7 @@ void ED_keymap_ui(struct wmKeyConfig *keyconf); void ED_uilisttypes_ui(void); void UI_drop_color_copy(struct wmDrag *drag, struct wmDropBox *drop); -bool UI_drop_color_poll(struct bContext *C, - struct wmDrag *drag, - const struct wmEvent *event, - const char **r_tooltip); +bool UI_drop_color_poll(struct bContext *C, struct wmDrag *drag, const struct wmEvent *event); bool UI_context_copy_to_selected_list(struct bContext *C, struct PointerRNA *ptr, diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 3ab49b8773b..20af3054882 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -1759,10 +1759,7 @@ static void UI_OT_button_string_clear(wmOperatorType *ot) /** \name Drop Color Operator * \{ */ -bool UI_drop_color_poll(struct bContext *C, - wmDrag *drag, - const wmEvent *UNUSED(event), - const char **UNUSED(r_tooltip)) +bool UI_drop_color_poll(struct bContext *C, wmDrag *drag, const wmEvent *UNUSED(event)) { /* should only return true for regions that include buttons, for now * return true always */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 8d7d742e44b..9534be3509b 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -5695,10 +5695,7 @@ static void keymap_modal_set(wmKeyConfig *keyconf) WM_modalkeymap_assign(keymap, "SCREEN_OT_area_move"); } -static bool blend_file_drop_poll(bContext *UNUSED(C), - wmDrag *drag, - const wmEvent *UNUSED(event), - const char **UNUSED(r_tooltip)) +static bool blend_file_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) { if (drag->type == WM_DRAG_PATH) { if (drag->icon == ICON_FILE_BLEND) { @@ -5728,8 +5725,9 @@ void ED_keymap_screen(wmKeyConfig *keyconf) /* dropbox for entire window */ ListBase *lb = WM_dropboxmap_find("Window", 0, 0); - WM_dropbox_add(lb, "WM_OT_drop_blend_file", blend_file_drop_poll, blend_file_drop_copy, NULL); - WM_dropbox_add(lb, "UI_OT_drop_color", UI_drop_color_poll, UI_drop_color_copy, NULL); + WM_dropbox_add( + lb, "WM_OT_drop_blend_file", blend_file_drop_poll, blend_file_drop_copy, NULL, NULL); + WM_dropbox_add(lb, "UI_OT_drop_color", UI_drop_color_poll, UI_drop_color_copy, NULL, NULL); keymap_modal_set(keyconf); } diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index aef3385f2dc..e2fbb4a5a59 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -605,10 +605,7 @@ static int /*eContextResult*/ clip_context(const bContext *C, } /* dropboxes */ -static bool clip_drop_poll(bContext *UNUSED(C), - wmDrag *drag, - const wmEvent *UNUSED(event), - const char **UNUSED(r_tooltip)) +static bool clip_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) { if (drag->type == WM_DRAG_PATH) { /* rule might not work? */ @@ -639,7 +636,7 @@ static void clip_dropboxes(void) { ListBase *lb = WM_dropboxmap_find("Clip", SPACE_CLIP, 0); - WM_dropbox_add(lb, "CLIP_OT_open", clip_drop_poll, clip_drop_copy, NULL); + WM_dropbox_add(lb, "CLIP_OT_open", clip_drop_poll, clip_drop_copy, NULL, NULL); } static void clip_refresh(const bContext *C, ScrArea *area) diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index 3029eed1017..47d15efb6ca 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -158,10 +158,7 @@ static void console_cursor(wmWindow *win, ScrArea *UNUSED(area), ARegion *region /* ************* dropboxes ************* */ -static bool id_drop_poll(bContext *UNUSED(C), - wmDrag *drag, - const wmEvent *UNUSED(event), - const char **UNUSED(tooltip)) +static bool id_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) { return WM_drag_get_local_ID(drag, 0) != NULL; } @@ -176,10 +173,7 @@ static void id_drop_copy(wmDrag *drag, wmDropBox *drop) MEM_freeN(text); } -static bool path_drop_poll(bContext *UNUSED(C), - wmDrag *drag, - const wmEvent *UNUSED(event), - const char **UNUSED(tooltip)) +static bool path_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) { return (drag->type == WM_DRAG_PATH); } @@ -196,8 +190,8 @@ static void console_dropboxes(void) { ListBase *lb = WM_dropboxmap_find("Console", SPACE_CONSOLE, RGN_TYPE_WINDOW); - WM_dropbox_add(lb, "CONSOLE_OT_insert", id_drop_poll, id_drop_copy, NULL); - WM_dropbox_add(lb, "CONSOLE_OT_insert", path_drop_poll, path_drop_copy, NULL); + WM_dropbox_add(lb, "CONSOLE_OT_insert", id_drop_poll, id_drop_copy, NULL, NULL); + WM_dropbox_add(lb, "CONSOLE_OT_insert", path_drop_poll, path_drop_copy, NULL, NULL); } /* ************* end drop *********** */ diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 46cc96ba0d4..d7a6523de26 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -815,10 +815,7 @@ static void file_ui_region_listener(const wmRegionListenerParams *listener_param } } -static bool filepath_drop_poll(bContext *C, - wmDrag *drag, - const wmEvent *UNUSED(event), - const char **UNUSED(r_tooltip)) +static bool filepath_drop_poll(bContext *C, wmDrag *drag, const wmEvent *UNUSED(event)) { if (drag->type == WM_DRAG_PATH) { SpaceFile *sfile = CTX_wm_space_file(C); @@ -839,7 +836,7 @@ static void file_dropboxes(void) { ListBase *lb = WM_dropboxmap_find("Window", SPACE_EMPTY, RGN_TYPE_WINDOW); - WM_dropbox_add(lb, "FILE_OT_filepath_drop", filepath_drop_poll, filepath_drop_copy, NULL); + WM_dropbox_add(lb, "FILE_OT_filepath_drop", filepath_drop_poll, filepath_drop_copy, NULL, NULL); } static int file_space_subtype_get(ScrArea *area) diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 5a03b4f6ef0..4107fd619aa 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -253,10 +253,7 @@ static void image_keymap(struct wmKeyConfig *keyconf) } /* dropboxes */ -static bool image_drop_poll(bContext *C, - wmDrag *drag, - const wmEvent *event, - const char **UNUSED(r_tooltip)) +static bool image_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) { ScrArea *area = CTX_wm_area(C); if (ED_region_overlap_isect_any_xy(area, &event->x)) { @@ -282,7 +279,7 @@ static void image_dropboxes(void) { ListBase *lb = WM_dropboxmap_find("Image", SPACE_IMAGE, 0); - WM_dropbox_add(lb, "IMAGE_OT_open", image_drop_poll, image_drop_copy, NULL); + WM_dropbox_add(lb, "IMAGE_OT_open", image_drop_poll, image_drop_copy, NULL, NULL); } /** diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index ff848a7bb95..956fb3aa867 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -664,42 +664,29 @@ static void node_main_region_draw(const bContext *C, ARegion *region) /* ************* dropboxes ************* */ -static bool node_group_drop_poll(bContext *UNUSED(C), - wmDrag *drag, - const wmEvent *UNUSED(event), - const char **UNUSED(r_tooltip)) +static bool node_group_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) { return WM_drag_is_ID_type(drag, ID_NT); } -static bool node_object_drop_poll(bContext *UNUSED(C), - wmDrag *drag, - const wmEvent *UNUSED(event), - const char **UNUSED(r_tooltip)) +static bool node_object_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) { return WM_drag_is_ID_type(drag, ID_OB); } static bool node_collection_drop_poll(bContext *UNUSED(C), wmDrag *drag, - const wmEvent *UNUSED(event), - const char **UNUSED(r_tooltip)) + const wmEvent *UNUSED(event)) { return WM_drag_is_ID_type(drag, ID_GR); } -static bool node_texture_drop_poll(bContext *UNUSED(C), - wmDrag *drag, - const wmEvent *UNUSED(event), - const char **UNUSED(r_tooltip)) +static bool node_texture_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) { return WM_drag_is_ID_type(drag, ID_TE); } -static bool node_ima_drop_poll(bContext *UNUSED(C), - wmDrag *drag, - const wmEvent *UNUSED(event), - const char **UNUSED(r_tooltip)) +static bool node_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) { if (drag->type == WM_DRAG_PATH) { /* rule might not work? */ @@ -708,10 +695,7 @@ static bool node_ima_drop_poll(bContext *UNUSED(C), return WM_drag_is_ID_type(drag, ID_IM); } -static bool node_mask_drop_poll(bContext *UNUSED(C), - wmDrag *drag, - const wmEvent *UNUSED(event), - const char **UNUSED(r_tooltip)) +static bool node_mask_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) { return WM_drag_is_ID_type(drag, ID_MSK); } @@ -753,32 +737,38 @@ static void node_dropboxes(void) "NODE_OT_add_object", node_object_drop_poll, node_id_drop_copy, - WM_drag_free_imported_drag_ID); + WM_drag_free_imported_drag_ID, + NULL); WM_dropbox_add(lb, "NODE_OT_add_collection", node_collection_drop_poll, node_id_drop_copy, - WM_drag_free_imported_drag_ID); + WM_drag_free_imported_drag_ID, + NULL); WM_dropbox_add(lb, "NODE_OT_add_texture", node_texture_drop_poll, node_id_drop_copy, - WM_drag_free_imported_drag_ID); + WM_drag_free_imported_drag_ID, + NULL); WM_dropbox_add(lb, "NODE_OT_add_group", node_group_drop_poll, node_group_drop_copy, - WM_drag_free_imported_drag_ID); + WM_drag_free_imported_drag_ID, + NULL); WM_dropbox_add(lb, "NODE_OT_add_file", node_ima_drop_poll, node_id_path_drop_copy, - WM_drag_free_imported_drag_ID); + WM_drag_free_imported_drag_ID, + NULL); WM_dropbox_add(lb, "NODE_OT_add_mask", node_mask_drop_poll, node_id_drop_copy, - WM_drag_free_imported_drag_ID); + WM_drag_free_imported_drag_ID, + NULL); } /* ************* end drop *********** */ diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c index 86aab86db10..36b2966dc43 100644 --- a/source/blender/editors/space_outliner/outliner_dragdrop.c +++ b/source/blender/editors/space_outliner/outliner_dragdrop.c @@ -31,6 +31,7 @@ #include "DNA_space_types.h" #include "BLI_listbase.h" +#include "BLI_string.h" #include "BLT_translation.h" @@ -316,10 +317,7 @@ static bool allow_parenting_without_modifier_key(SpaceOutliner *space_outliner) } } -static bool parent_drop_poll(bContext *C, - wmDrag *drag, - const wmEvent *event, - const char **UNUSED(r_tooltip)) +static bool parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) { SpaceOutliner *space_outliner = CTX_wm_space_outliner(C); @@ -455,10 +453,7 @@ void OUTLINER_OT_parent_drop(wmOperatorType *ot) /* ******************** Parent Clear Operator *********************** */ -static bool parent_clear_poll(bContext *C, - wmDrag *drag, - const wmEvent *event, - const char **UNUSED(r_tooltip)) +static bool parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *event) { SpaceOutliner *space_outliner = CTX_wm_space_outliner(C); @@ -541,10 +536,7 @@ void OUTLINER_OT_parent_clear(wmOperatorType *ot) /* ******************** Scene Drop Operator *********************** */ -static bool scene_drop_poll(bContext *C, - wmDrag *drag, - const wmEvent *event, - const char **UNUSED(r_tooltip)) +static bool scene_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) { /* Ensure item under cursor is valid drop target */ Object *ob = (Object *)WM_drag_get_local_ID(drag, ID_OB); @@ -609,10 +601,7 @@ void OUTLINER_OT_scene_drop(wmOperatorType *ot) /* ******************** Material Drop Operator *********************** */ -static bool material_drop_poll(bContext *C, - wmDrag *drag, - const wmEvent *event, - const char **UNUSED(r_tooltip)) +static bool material_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) { /* Ensure item under cursor is valid drop target */ Material *ma = (Material *)WM_drag_get_local_ID(drag, ID_MA); @@ -833,10 +822,7 @@ static bool datastack_drop_are_types_valid(StackDropData *drop_data) return true; } -static bool datastack_drop_poll(bContext *C, - wmDrag *drag, - const wmEvent *event, - const char **r_tooltip) +static bool datastack_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) { if (drag->type != WM_DRAG_DATASTACK) { return false; @@ -873,28 +859,6 @@ static bool datastack_drop_poll(bContext *C, break; } - switch (drop_data->drop_action) { - case DATA_STACK_DROP_REORDER: - *r_tooltip = TIP_("Reorder"); - break; - case DATA_STACK_DROP_COPY: - if (drop_data->pchan_parent) { - *r_tooltip = TIP_("Copy to bone"); - } - else { - *r_tooltip = TIP_("Copy to object"); - } - break; - case DATA_STACK_DROP_LINK: - if (drop_data->pchan_parent) { - *r_tooltip = TIP_("Link all to bone"); - } - else { - *r_tooltip = TIP_("Link all to object"); - } - break; - } - if (changed) { ED_region_tag_redraw_no_rebuild(region); } @@ -902,6 +866,35 @@ static bool datastack_drop_poll(bContext *C, return true; } +static char *datastack_drop_tooltip(bContext *UNUSED(C), + wmDrag *drag, + const wmEvent *UNUSED(event)) +{ + StackDropData *drop_data = drag->poin; + switch (drop_data->drop_action) { + case DATA_STACK_DROP_REORDER: + return BLI_strdup(TIP_("Reorder")); + break; + case DATA_STACK_DROP_COPY: + if (drop_data->pchan_parent) { + return BLI_strdup(TIP_("Copy to bone")); + } + else { + return BLI_strdup(TIP_("Copy to object")); + } + break; + case DATA_STACK_DROP_LINK: + if (drop_data->pchan_parent) { + return BLI_strdup(TIP_("Link all to bone")); + } + else { + return BLI_strdup(TIP_("Link all to object")); + } + break; + } + return NULL; +} + static void datastack_drop_link(bContext *C, StackDropData *drop_data) { Main *bmain = CTX_data_main(C); @@ -1155,10 +1148,7 @@ static bool collection_drop_init(bContext *C, return true; } -static bool collection_drop_poll(bContext *C, - wmDrag *drag, - const wmEvent *event, - const char **r_tooltip) +static bool collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) { SpaceOutliner *space_outliner = CTX_wm_space_outliner(C); ARegion *region = CTX_wm_region(C); @@ -1172,45 +1162,20 @@ static bool collection_drop_poll(bContext *C, if (!data.from || event->ctrl) { tselem->flag |= TSE_DRAG_INTO; changed = true; - *r_tooltip = TIP_("Link inside Collection"); } else { switch (data.insert_type) { case TE_INSERT_BEFORE: tselem->flag |= TSE_DRAG_BEFORE; changed = true; - if (te->prev && outliner_is_collection_tree_element(te->prev)) { - *r_tooltip = TIP_("Move between collections"); - } - else { - *r_tooltip = TIP_("Move before collection"); - } break; case TE_INSERT_AFTER: tselem->flag |= TSE_DRAG_AFTER; changed = true; - if (te->next && outliner_is_collection_tree_element(te->next)) { - *r_tooltip = TIP_("Move between collections"); - } - else { - *r_tooltip = TIP_("Move after collection"); - } break; case TE_INSERT_INTO: { tselem->flag |= TSE_DRAG_INTO; changed = true; - - /* Check the type of the drag IDs to avoid the incorrect "Shift to parent" - * for collections. Checking the type of the first ID works fine here since - * all drag IDs are the same type. */ - wmDragID *drag_id = (wmDragID *)drag->ids.first; - const bool is_object = (GS(drag_id->id->name) == ID_OB); - if (is_object) { - *r_tooltip = TIP_("Move inside collection (Ctrl to link, Shift to parent)"); - } - else { - *r_tooltip = TIP_("Move inside collection (Ctrl to link)"); - } break; } } @@ -1226,6 +1191,49 @@ static bool collection_drop_poll(bContext *C, return false; } +static char *collection_drop_tooltip(bContext *C, wmDrag *drag, const wmEvent *event) +{ + CollectionDrop data; + if (!event->shift && collection_drop_init(C, drag, event, &data)) { + TreeElement *te = data.te; + if (!data.from || event->ctrl) { + return BLI_strdup(TIP_("Link inside Collection")); + } + switch (data.insert_type) { + case TE_INSERT_BEFORE: + if (te->prev && outliner_is_collection_tree_element(te->prev)) { + return BLI_strdup(TIP_("Move between collections")); + } + else { + return BLI_strdup(TIP_("Move before collection")); + } + break; + case TE_INSERT_AFTER: + if (te->next && outliner_is_collection_tree_element(te->next)) { + return BLI_strdup(TIP_("Move between collections")); + } + else { + return BLI_strdup(TIP_("Move after collection")); + } + break; + case TE_INSERT_INTO: { + + /* Check the type of the drag IDs to avoid the incorrect "Shift to parent" + * for collections. Checking the type of the first ID works fine here since + * all drag IDs are the same type. */ + wmDragID *drag_id = (wmDragID *)drag->ids.first; + const bool is_object = (GS(drag_id->id->name) == ID_OB); + if (is_object) { + return BLI_strdup(TIP_("Move inside collection (Ctrl to link, Shift to parent)")); + } + return BLI_strdup(TIP_("Move inside collection (Ctrl to link)")); + break; + } + } + } + return NULL; +} + static int collection_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { Main *bmain = CTX_data_main(C); @@ -1499,10 +1507,16 @@ void outliner_dropboxes(void) { ListBase *lb = WM_dropboxmap_find("Outliner", SPACE_OUTLINER, RGN_TYPE_WINDOW); - WM_dropbox_add(lb, "OUTLINER_OT_parent_drop", parent_drop_poll, NULL, NULL); - WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", parent_clear_poll, NULL, NULL); - WM_dropbox_add(lb, "OUTLINER_OT_scene_drop", scene_drop_poll, NULL, NULL); - WM_dropbox_add(lb, "OUTLINER_OT_material_drop", material_drop_poll, NULL, NULL); - WM_dropbox_add(lb, "OUTLINER_OT_datastack_drop", datastack_drop_poll, NULL, NULL); - WM_dropbox_add(lb, "OUTLINER_OT_collection_drop", collection_drop_poll, NULL, NULL); + WM_dropbox_add(lb, "OUTLINER_OT_parent_drop", parent_drop_poll, NULL, NULL, NULL); + WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", parent_clear_poll, NULL, NULL, NULL); + WM_dropbox_add(lb, "OUTLINER_OT_scene_drop", scene_drop_poll, NULL, NULL, NULL); + WM_dropbox_add(lb, "OUTLINER_OT_material_drop", material_drop_poll, NULL, NULL, NULL); + WM_dropbox_add( + lb, "OUTLINER_OT_datastack_drop", datastack_drop_poll, NULL, NULL, datastack_drop_tooltip); + WM_dropbox_add(lb, + "OUTLINER_OT_collection_drop", + collection_drop_poll, + NULL, + NULL, + collection_drop_tooltip); } diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 6de95f0995a..00f3bf6ac72 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -364,10 +364,7 @@ static void sequencer_listener(const wmSpaceTypeListenerParams *params) /* ************* dropboxes ************* */ -static bool image_drop_poll(bContext *C, - wmDrag *drag, - const wmEvent *event, - const char **UNUSED(r_tooltip)) +static bool image_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) { ARegion *region = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); @@ -384,10 +381,7 @@ static bool image_drop_poll(bContext *C, return 0; } -static bool movie_drop_poll(bContext *C, - wmDrag *drag, - const wmEvent *event, - const char **UNUSED(r_tooltip)) +static bool movie_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) { ARegion *region = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); @@ -403,10 +397,7 @@ static bool movie_drop_poll(bContext *C, return 0; } -static bool sound_drop_poll(bContext *C, - wmDrag *drag, - const wmEvent *event, - const char **UNUSED(r_tooltip)) +static bool sound_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) { ARegion *region = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); @@ -448,9 +439,12 @@ static void sequencer_dropboxes(void) { ListBase *lb = WM_dropboxmap_find("Sequencer", SPACE_SEQ, RGN_TYPE_WINDOW); - WM_dropbox_add(lb, "SEQUENCER_OT_image_strip_add", image_drop_poll, sequencer_drop_copy, NULL); - WM_dropbox_add(lb, "SEQUENCER_OT_movie_strip_add", movie_drop_poll, sequencer_drop_copy, NULL); - WM_dropbox_add(lb, "SEQUENCER_OT_sound_strip_add", sound_drop_poll, sequencer_drop_copy, NULL); + WM_dropbox_add( + lb, "SEQUENCER_OT_image_strip_add", image_drop_poll, sequencer_drop_copy, NULL, NULL); + WM_dropbox_add( + lb, "SEQUENCER_OT_movie_strip_add", movie_drop_poll, sequencer_drop_copy, NULL, NULL); + WM_dropbox_add( + lb, "SEQUENCER_OT_sound_strip_add", sound_drop_poll, sequencer_drop_copy, NULL, NULL); } /* ************* end drop *********** */ diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index af783051661..89e92231657 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -312,10 +312,7 @@ static void text_cursor(wmWindow *win, ScrArea *area, ARegion *region) /* ************* dropboxes ************* */ -static bool text_drop_poll(bContext *UNUSED(C), - wmDrag *drag, - const wmEvent *UNUSED(event), - const char **UNUSED(r_tooltip)) +static bool text_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) { if (drag->type == WM_DRAG_PATH) { /* rule might not work? */ @@ -332,10 +329,7 @@ static void text_drop_copy(wmDrag *drag, wmDropBox *drop) RNA_string_set(drop->ptr, "filepath", drag->path); } -static bool text_drop_paste_poll(bContext *UNUSED(C), - wmDrag *drag, - const wmEvent *UNUSED(event), - const char **UNUSED(r_tooltip)) +static bool text_drop_paste_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) { return (drag->type == WM_DRAG_ID); } @@ -356,8 +350,8 @@ static void text_dropboxes(void) { ListBase *lb = WM_dropboxmap_find("Text", SPACE_TEXT, RGN_TYPE_WINDOW); - WM_dropbox_add(lb, "TEXT_OT_open", text_drop_poll, text_drop_copy, NULL); - WM_dropbox_add(lb, "TEXT_OT_insert", text_drop_paste_poll, text_drop_paste, NULL); + WM_dropbox_add(lb, "TEXT_OT_open", text_drop_poll, text_drop_copy, NULL, NULL); + WM_dropbox_add(lb, "TEXT_OT_insert", text_drop_paste_poll, text_drop_paste, NULL, NULL); } /* ************* end drop *********** */ diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 54f10e259f9..a2564469c16 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -513,49 +513,38 @@ static bool view3d_drop_id_in_main_region_poll(bContext *C, return WM_drag_is_ID_type(drag, id_type); } -static bool view3d_ob_drop_poll(bContext *C, - wmDrag *drag, - const wmEvent *event, - const char **UNUSED(r_tooltip)) +static bool view3d_ob_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) { return view3d_drop_id_in_main_region_poll(C, drag, event, ID_OB); } -static bool view3d_collection_drop_poll(bContext *C, - wmDrag *drag, - const wmEvent *event, - const char **UNUSED(r_tooltip)) +static bool view3d_collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) { return view3d_drop_id_in_main_region_poll(C, drag, event, ID_GR); } -static bool view3d_mat_drop_poll(bContext *C, - wmDrag *drag, - const wmEvent *event, - const char **UNUSED(r_tooltip)) +static bool view3d_mat_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) { return view3d_drop_id_in_main_region_poll(C, drag, event, ID_MA); } -static bool view3d_object_data_drop_poll(bContext *C, - wmDrag *drag, - const wmEvent *event, - const char **r_tooltip) +static bool view3d_object_data_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) { ID_Type id_type = view3d_drop_id_in_main_region_poll_get_id_type(C, drag, event); - if (id_type) { - if (OB_DATA_SUPPORT_ID(id_type)) { - *r_tooltip = TIP_("Create object instance from object-data"); - return true; - } + if (id_type && OB_DATA_SUPPORT_ID(id_type)) { + return true; } return false; } -static bool view3d_ima_drop_poll(bContext *C, - wmDrag *drag, - const wmEvent *event, - const char **UNUSED(r_tooltip)) +static char *view3d_object_data_drop_tooltip(bContext *UNUSED(C), + wmDrag *UNUSED(drag), + const wmEvent *UNUSED(event)) +{ + return BLI_strdup(TIP_("Create object instance from object-data")); +} + +static bool view3d_ima_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) { if (ED_region_overlap_isect_any_xy(CTX_wm_area(C), &event->x)) { return false; @@ -580,12 +569,9 @@ static bool view3d_ima_bg_is_camera_view(bContext *C) return false; } -static bool view3d_ima_bg_drop_poll(bContext *C, - wmDrag *drag, - const wmEvent *event, - const char **r_tooltip) +static bool view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) { - if (!view3d_ima_drop_poll(C, drag, event, r_tooltip)) { + if (!view3d_ima_drop_poll(C, drag, event)) { return false; } @@ -596,12 +582,9 @@ static bool view3d_ima_bg_drop_poll(bContext *C, return view3d_ima_bg_is_camera_view(C); } -static bool view3d_ima_empty_drop_poll(bContext *C, - wmDrag *drag, - const wmEvent *event, - const char **r_tooltip) +static bool view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) { - if (!view3d_ima_drop_poll(C, drag, event, r_tooltip)) { + if (!view3d_ima_drop_poll(C, drag, event)) { return false; } @@ -620,8 +603,7 @@ static bool view3d_ima_empty_drop_poll(bContext *C, static bool view3d_volume_drop_poll(bContext *UNUSED(C), wmDrag *drag, - const wmEvent *UNUSED(event), - const char **UNUSED(r_tooltip)) + const wmEvent *UNUSED(event)) { return (drag->type == WM_DRAG_PATH) && (drag->icon == ICON_FILE_VOLUME); } @@ -700,37 +682,44 @@ static void view3d_dropboxes(void) "OBJECT_OT_add_named", view3d_ob_drop_poll, view3d_ob_drop_copy, - WM_drag_free_imported_drag_ID); + WM_drag_free_imported_drag_ID, + NULL); WM_dropbox_add(lb, "OBJECT_OT_drop_named_material", view3d_mat_drop_poll, view3d_id_drop_copy, - WM_drag_free_imported_drag_ID); + WM_drag_free_imported_drag_ID, + NULL); WM_dropbox_add(lb, "VIEW3D_OT_background_image_add", view3d_ima_bg_drop_poll, view3d_id_path_drop_copy, - WM_drag_free_imported_drag_ID); + WM_drag_free_imported_drag_ID, + NULL); WM_dropbox_add(lb, "OBJECT_OT_drop_named_image", view3d_ima_empty_drop_poll, view3d_id_path_drop_copy, - WM_drag_free_imported_drag_ID); + WM_drag_free_imported_drag_ID, + NULL); WM_dropbox_add(lb, "OBJECT_OT_volume_import", view3d_volume_drop_poll, view3d_id_path_drop_copy, - WM_drag_free_imported_drag_ID); + WM_drag_free_imported_drag_ID, + NULL); WM_dropbox_add(lb, "OBJECT_OT_collection_instance_add", view3d_collection_drop_poll, view3d_collection_drop_copy, - WM_drag_free_imported_drag_ID); + WM_drag_free_imported_drag_ID, + NULL); WM_dropbox_add(lb, "OBJECT_OT_data_instance_add", view3d_object_data_drop_poll, view3d_id_drop_copy_with_type, - WM_drag_free_imported_drag_ID); + WM_drag_free_imported_drag_ID, + view3d_object_data_drop_tooltip); } static void view3d_widgets(void) diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index c0d408be2e0..136c639caea 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -34,6 +34,7 @@ #include "BLI_sys_types.h" #include "DNA_windowmanager_types.h" #include "WM_keymap.h" +#include "WM_types.h" #ifdef __cplusplus extern "C" { @@ -705,13 +706,13 @@ void WM_event_drag_image(struct wmDrag *, struct ImBuf *, float scale, int sx, i void WM_drag_free(struct wmDrag *drag); void WM_drag_data_free(int dragtype, void *poin); void WM_drag_free_list(struct ListBase *lb); - struct wmDropBox *WM_dropbox_add( ListBase *lb, const char *idname, - bool (*poll)(struct bContext *, struct wmDrag *, const struct wmEvent *event, const char **), + bool (*poll)(struct bContext *, struct wmDrag *, const struct wmEvent *event), void (*copy)(struct wmDrag *, struct wmDropBox *), - void (*cancel)(struct Main *, struct wmDrag *, struct wmDropBox *)); + void (*cancel)(struct Main *, struct wmDrag *, struct wmDropBox *), + WMDropboxTooltipFunc tooltip); ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid); /* ID drag and drop */ diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 4ead0b2699c..4d6cb941347 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -114,6 +114,7 @@ struct bContext; struct wmEvent; struct wmOperator; struct wmWindowManager; +struct wmDrag; #include "BLI_compiler_attrs.h" #include "DNA_listBase.h" @@ -934,6 +935,10 @@ typedef struct wmDragAsset { int import_type; /* eFileAssetImportType */ } wmDragAsset; +typedef char *(*WMDropboxTooltipFunc)(struct bContext *, + struct wmDrag *, + const struct wmEvent *event); + typedef struct wmDrag { struct wmDrag *next, *prev; @@ -949,8 +954,8 @@ typedef struct wmDrag { float scale; int sx, sy; - /** If set, draws operator name. */ - char opname[200]; + /** If filled, draws operator tooltip/operator name. */ + char tooltip[200]; unsigned int flags; /** List of wmDragIDs, all are guaranteed to have the same ID type. */ @@ -964,8 +969,8 @@ typedef struct wmDrag { typedef struct wmDropBox { struct wmDropBox *next, *prev; - /** Test if the dropbox is active, then can print optype name. */ - bool (*poll)(struct bContext *, struct wmDrag *, const wmEvent *, const char **); + /** Test if the dropbox is active. */ + bool (*poll)(struct bContext *, struct wmDrag *, const wmEvent *); /** Before exec, this copies drag info to #wmDrop properties. */ void (*copy)(struct wmDrag *, struct wmDropBox *); @@ -976,6 +981,9 @@ typedef struct wmDropBox { */ void (*cancel)(struct Main *, struct wmDrag *, struct wmDropBox *); + /** Custom tooltip shown during dragging. */ + WMDropboxTooltipFunc tooltip; + /** * If poll succeeds, operator is called. * Not saved in file, so can be pointer. diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c index db72dd2a819..c58d3c53e03 100644 --- a/source/blender/windowmanager/intern/wm_dragdrop.c +++ b/source/blender/windowmanager/intern/wm_dragdrop.c @@ -96,14 +96,16 @@ ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid) wmDropBox *WM_dropbox_add(ListBase *lb, const char *idname, - bool (*poll)(bContext *, wmDrag *, const wmEvent *, const char **), + bool (*poll)(bContext *, wmDrag *, const wmEvent *), void (*copy)(wmDrag *, wmDropBox *), - void (*cancel)(struct Main *, wmDrag *, wmDropBox *)) + void (*cancel)(struct Main *, wmDrag *, wmDropBox *), + WMDropboxTooltipFunc tooltip) { wmDropBox *drop = MEM_callocN(sizeof(wmDropBox), "wmDropBox"); drop->poll = poll; drop->copy = copy; drop->cancel = cancel; + drop->tooltip = tooltip; drop->ot = WM_operatortype_find(idname, 0); drop->opcontext = WM_OP_INVOKE_DEFAULT; @@ -218,22 +220,36 @@ void WM_drag_free_list(struct ListBase *lb) } } -static const char *dropbox_active(bContext *C, - ListBase *handlers, - wmDrag *drag, - const wmEvent *event) +static char *dropbox_tooltip(bContext *C, + wmDrag *drag, + const wmEvent *event, + const wmDropBox *drop) +{ + char *tooltip = NULL; + if (drop->tooltip) { + tooltip = drop->tooltip(C, drag, event); + } + if (!tooltip) { + tooltip = BLI_strdup(WM_operatortype_name(drop->ot, drop->ptr)); + } + /* XXX Doing translation here might not be ideal, but later we have no more + * access to ot (and hence op context)... */ + return tooltip; +} + +static wmDropBox *dropbox_active(bContext *C, + ListBase *handlers, + wmDrag *drag, + const wmEvent *event) { LISTBASE_FOREACH (wmEventHandler *, handler_base, handlers) { if (handler_base->type == WM_HANDLER_TYPE_DROPBOX) { wmEventHandler_Dropbox *handler = (wmEventHandler_Dropbox *)handler_base; if (handler->dropboxes) { LISTBASE_FOREACH (wmDropBox *, drop, handler->dropboxes) { - const char *tooltip = NULL; - if (drop->poll(C, drag, event, &tooltip) && + if (drop->poll(C, drag, event) && WM_operator_poll_context(C, drop->ot, drop->opcontext)) { - /* XXX Doing translation here might not be ideal, but later we have no more - * access to ot (and hence op context)... */ - return (tooltip) ? tooltip : WM_operatortype_name(drop->ot, drop->ptr); + return drop; } } } @@ -242,29 +258,22 @@ static const char *dropbox_active(bContext *C, return NULL; } -/* return active operator name when mouse is in box */ -static const char *wm_dropbox_active(bContext *C, wmDrag *drag, const wmEvent *event) +/* return active operator tooltip/name when mouse is in box */ +static char *wm_dropbox_active(bContext *C, wmDrag *drag, const wmEvent *event) { wmWindow *win = CTX_wm_window(C); - ScrArea *area = CTX_wm_area(C); - ARegion *region = CTX_wm_region(C); - const char *name; - - name = dropbox_active(C, &win->handlers, drag, event); - if (name) { - return name; + wmDropBox *drop = dropbox_active(C, &win->handlers, drag, event); + if (!drop) { + ScrArea *area = CTX_wm_area(C); + drop = dropbox_active(C, &area->handlers, drag, event); } - - name = dropbox_active(C, &area->handlers, drag, event); - if (name) { - return name; + if (!drop) { + ARegion *region = CTX_wm_region(C); + drop = dropbox_active(C, ®ion->handlers, drag, event); } - - name = dropbox_active(C, ®ion->handlers, drag, event); - if (name) { - return name; + if (drop) { + return dropbox_tooltip(C, drag, event, drop); } - return NULL; } @@ -279,17 +288,18 @@ static void wm_drop_operator_options(bContext *C, wmDrag *drag, const wmEvent *e return; } - drag->opname[0] = 0; + drag->tooltip[0] = 0; /* check buttons (XXX todo rna and value) */ if (UI_but_active_drop_name(C)) { - BLI_strncpy(drag->opname, IFACE_("Paste name"), sizeof(drag->opname)); + BLI_strncpy(drag->tooltip, IFACE_("Paste name"), sizeof(drag->tooltip)); } else { - const char *opname = wm_dropbox_active(C, drag, event); + char *tooltip = wm_dropbox_active(C, drag, event); - if (opname) { - BLI_strncpy(drag->opname, opname, sizeof(drag->opname)); + if (tooltip) { + BLI_strncpy(drag->tooltip, tooltip, sizeof(drag->tooltip)); + MEM_freeN(tooltip); // WM_cursor_modal_set(win, WM_CURSOR_COPY); } // else @@ -584,7 +594,7 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect) } /* operator name with roundbox */ - if (drag->opname[0]) { + if (drag->tooltip[0]) { if (drag->imb) { x = cursorx - drag->sx / 2; @@ -611,7 +621,7 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect) drag_rect_minmax(rect, x, y, x + w, y + iconsize); } else { - wm_drop_operator_draw(drag->opname, x, y); + wm_drop_operator_draw(drag->tooltip, x, y); } } } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 5e29a22304c..5cc361fc1bd 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -2851,8 +2851,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers if (event->custom == EVT_DATA_DRAGDROP) { ListBase *lb = (ListBase *)event->customdata; LISTBASE_FOREACH (wmDrag *, drag, lb) { - const char *tooltip = NULL; - if (drop->poll(C, drag, event, &tooltip)) { + if (drop->poll(C, drag, event)) { /* Optionally copy drag information to operator properties. Don't call it if the * operator fails anyway, it might do more than just set properties (e.g. * typically import an asset). */ From 11cfa6c718b7851a30f203c92e53c4dc6451ae1a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 2 Aug 2021 23:58:55 +1000 Subject: [PATCH 13/24] Fix T90332: Auto-smooth crashes in edit-mode Regression in 39b2a7bb7e815e051348bf5c5ec777d091324164 that meant non-manifold edges were not being tagged when they should have been. --- .../blender/bmesh/intern/bmesh_mesh_normals.c | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/source/blender/bmesh/intern/bmesh_mesh_normals.c b/source/blender/bmesh/intern/bmesh_mesh_normals.c index 6dfaa0ca688..e62deb2dde5 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_normals.c +++ b/source/blender/bmesh/intern/bmesh_mesh_normals.c @@ -50,6 +50,8 @@ static void bm_edge_tag_from_smooth(const float (*fnos)[3], BMEdge *e, const float split_angle_cos); +static void bm_edge_tag_clear(BMEdge *e); + /* -------------------------------------------------------------------- */ /** \name Update Vertex & Face Normals * \{ */ @@ -820,9 +822,10 @@ BLI_INLINE bool bm_edge_is_smooth_no_angle_test(const BMEdge *e, const BMLoop *l_a, const BMLoop *l_b) { + BLI_assert(l_a->radial_next == l_b); return ( /* The face is manifold. */ - (l_a->radial_next == l_b) && + (l_b->radial_next == l_a) && /* Faces have winding that faces the same way. */ (l_a->v != l_b->v) && /* The edge is smooth. */ @@ -863,6 +866,13 @@ static void bm_edge_tag_from_smooth(const float (*fnos)[3], BMEdge *e, const flo } } +static void bm_edge_tag_clear(BMEdge *e) +{ + /* No need for atomics here as this is a single byte. */ + char *hflag_p = &e->head.hflag; + *hflag_p = *hflag_p & ~BM_ELEM_TAG; +} + /** * A version of #bm_edge_tag_from_smooth that sets sharp edges * when they would be considered smooth but exceed the split angle . @@ -944,9 +954,13 @@ static void bm_mesh_loops_calc_normals_for_vert_with_clnors(BMesh *bm, continue; } + /* Always set as #bm_mesh_loops_calc_normals_for_loop checks the tag. */ if (do_edge_tag) { bm_edge_tag_from_smooth(fnos, e_curr_iter, split_angle_cos); } + else { + bm_edge_tag_clear(e_curr_iter); + } do { /* Radial loops. */ if (l_curr->v != v) { @@ -1052,9 +1066,13 @@ static void bm_mesh_loops_calc_normals_for_vert_without_clnors( continue; } + /* Always set as #bm_mesh_loops_calc_normals_for_loop checks the tag. */ if (do_edge_tag) { bm_edge_tag_from_smooth(fnos, e_curr_iter, split_angle_cos); } + else { + bm_edge_tag_clear(e_curr_iter); + } do { /* Radial loops. */ if (l_curr->v != v) { From 0e4f7b4a4b328d1d62c9c5e6a57e58c89a0e9aa2 Mon Sep 17 00:00:00 2001 From: James Monteath Date: Mon, 2 Aug 2021 16:57:29 +0200 Subject: [PATCH 14/24] Delete pipeline_config.json file. The yaml file is now used. Update README.md. --- build_files/config/README.md | 11 ++-- build_files/config/pipeline_config.json | 87 ------------------------- 2 files changed, 5 insertions(+), 93 deletions(-) delete mode 100644 build_files/config/pipeline_config.json diff --git a/build_files/config/README.md b/build_files/config/README.md index 6ce601104af..efa3d4524ec 100644 --- a/build_files/config/README.md +++ b/build_files/config/README.md @@ -1,11 +1,10 @@ Pipeline Config =============== -This configuration file is used by buildbot new build pipeline for the `update-code` step. +The `yaml` configuration file is used by buildbot build pipeline `update-code` step. -It will also be used by the `../utils/make_update.py` script in the near future. +The file allows to set branches or specific commits for both git submodules and svn artifacts. Can also define various build package versions for use by build workers. Especially useful in experimental and release branches. -NOTES: -* Keep both `yaml` and `json` files in sync until deployment of build pipeline updates. -* The `json` file be removed once all branches are running with the `yaml` file. -* Expected buildbot pipeline update is *Friday, July 30th* or *Monday August, 2nd*. +NOTE: +* The configuration file is ```NOT``` used by the `../utils/make_update.py` script. +* That will implemented in the future. diff --git a/build_files/config/pipeline_config.json b/build_files/config/pipeline_config.json deleted file mode 100644 index d914cf85eae..00000000000 --- a/build_files/config/pipeline_config.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "update-code": - { - "git" : - { - "submodules": - [ - { "path": "release/scripts/addons", "branch": "master", "commit_id": "HEAD" }, - { "path": "release/scripts/addons_contrib", "branch": "master", "commit_id": "HEAD" }, - { "path": "release/datafiles/locale", "branch": "master", "commit_id": "HEAD" }, - { "path": "source/tools", "branch": "master", "commit_id": "HEAD" } - ] - }, - "svn": - { - "tests": { "path": "lib/tests", "branch": "trunk", "commit_id": "HEAD" }, - "libraries": - { - "darwin-x86_64": { "path": "lib/darwin", "branch": "trunk", "commit_id": "HEAD" }, - "darwin-arm64": { "path": "lib/darwin_arm64", "branch": "trunk", "commit_id": "HEAD" }, - "linux-x86_64": { "path": "lib/linux_centos7_x86_64", "branch": "trunk", "commit_id": "HEAD" }, - "windows-amd64": { "path": "lib/win64_vc15", "branch": "trunk", "commit_id": "HEAD" } - } - } - }, - "buildbot": - { - "gcc": - { - "version": "9.0" - }, - "sdks": - { - "optix": - { - "version": "7.1.0" - }, - "cuda10": - { - "version": "10.1" - }, - "cuda11": - { - "version": "11.4" - } - }, - "cmake": - { - "default": - { - "version": "any", - "overrides": - { - - } - }, - "darwin-x86_64": - { - "overrides": - { - - } - }, - "darwin-arm64": - { - "overrides": - { - - } - }, - "linux-x86_64": - { - "overrides": - { - - } - }, - "windows-amd64": - { - "overrides": - { - - } - } - } - } -} From d8bf332f86b3644b016950b596bb0814f245e995 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Mon, 2 Aug 2021 16:45:56 +0200 Subject: [PATCH 15/24] Asset Browser: Adjust header pulldowns to be Asset Browser specific So far the Asset Browser just showed the same menus as the File Browser. Not all of their entries made sense for the Asset Browser though. I decided to just give them entirely different classes to avoid confusing if-else checks everywhere. I think the code duplication this adds is a minor issue, it's better to keep things seperated clearly IMO. * View menu: Add "Asset Details" toggle for the sidebar region. * View menu: Remove recursion sub-menu * View menu: Remove "File Path" region toggle, which doesn't apply for the Asset Browser. Differential Revision: https://developer.blender.org/D12057 --- .../startup/bl_ui/space_filebrowser.py | 74 +++++++++++++++++-- source/blender/makesrna/intern/rna_space.c | 20 ++++- 2 files changed, 88 insertions(+), 6 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py index 8ca93d2406c..570d8b42821 100644 --- a/release/scripts/startup/bl_ui/space_filebrowser.py +++ b/release/scripts/startup/bl_ui/space_filebrowser.py @@ -84,12 +84,12 @@ class FILEBROWSER_HT_header(Header): if space_data.active_operator is None: layout.template_header() - FILEBROWSER_MT_editor_menus.draw_collapsible(context, layout) - if SpaceAssetInfo.is_asset_browser(space_data): + ASSETBROWSER_MT_editor_menus.draw_collapsible(context, layout) layout.separator() self.draw_asset_browser_buttons(context) else: + FILEBROWSER_MT_editor_menus.draw_collapsible(context, layout) layout.separator_spacer() if not context.screen.show_statusbar: @@ -477,7 +477,14 @@ class FILEBROWSER_PT_directory_path(Panel): ).region_type = 'TOOL_PROPS' -class FILEBROWSER_MT_editor_menus(Menu): +class FileBrowserMenu: + @classmethod + def poll(cls, context): + space_data = context.space_data + return space_data and space_data.type == 'FILE_BROWSER' and space_data.browse_mode == 'FILES' + + +class FILEBROWSER_MT_editor_menus(FileBrowserMenu, Menu): bl_idname = "FILEBROWSER_MT_editor_menus" bl_label = "" @@ -488,7 +495,7 @@ class FILEBROWSER_MT_editor_menus(Menu): layout.menu("FILEBROWSER_MT_select") -class FILEBROWSER_MT_view(Menu): +class FILEBROWSER_MT_view(FileBrowserMenu, Menu): bl_label = "View" def draw(self, context): @@ -510,7 +517,7 @@ class FILEBROWSER_MT_view(Menu): layout.menu("INFO_MT_area") -class FILEBROWSER_MT_select(Menu): +class FILEBROWSER_MT_select(FileBrowserMenu, Menu): bl_label = "Select" def draw(self, _context): @@ -572,6 +579,60 @@ class FILEBROWSER_MT_context_menu(Menu): layout.prop_menu_enum(params, "sort_method") +class AssetBrowserMenu: + @classmethod + def poll(cls, context): + from bpy_extras.asset_utils import SpaceAssetInfo + return SpaceAssetInfo.is_asset_browser_poll(context) + + +class ASSETBROWSER_MT_editor_menus(AssetBrowserMenu, Menu): + bl_idname = "ASSETBROWSER_MT_editor_menus" + bl_label = "" + + def draw(self, _context): + layout = self.layout + + layout.menu("ASSETBROWSER_MT_view") + layout.menu("ASSETBROWSER_MT_select") + + +class ASSETBROWSER_MT_view(AssetBrowserMenu, Menu): + bl_label = "View" + + def draw(self, context): + layout = self.layout + st = context.space_data + params = st.params + + layout.prop(st, "show_region_toolbar", text="Source List") + layout.prop(st, "show_region_tool_props", text="Asset Details") + layout.operator("file.view_selected") + + layout.separator() + + layout.prop_menu_enum(params, "display_size") + + layout.separator() + + layout.menu("INFO_MT_area") + + +class ASSETBROWSER_MT_select(AssetBrowserMenu, Menu): + bl_label = "Select" + + def draw(self, _context): + layout = self.layout + + layout.operator("file.select_all", text="All").action = 'SELECT' + layout.operator("file.select_all", text="None").action = 'DESELECT' + layout.operator("file.select_all", text="Inverse").action = 'INVERT' + + layout.separator() + + layout.operator("file.select_box") + + class ASSETBROWSER_PT_navigation_bar(asset_utils.AssetBrowserPanel, Panel): bl_label = "Asset Navigation" bl_region_type = 'TOOLS' @@ -694,6 +755,9 @@ classes = ( FILEBROWSER_MT_view, FILEBROWSER_MT_select, FILEBROWSER_MT_context_menu, + ASSETBROWSER_MT_editor_menus, + ASSETBROWSER_MT_view, + ASSETBROWSER_MT_select, ASSETBROWSER_PT_navigation_bar, ASSETBROWSER_PT_metadata, ASSETBROWSER_PT_metadata_preview, diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 1d4318602c2..796e62c8b2a 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -778,6 +778,19 @@ static void rna_Space_show_region_toolbar_update(bContext *C, PointerRNA *ptr) rna_Space_bool_from_region_flag_update_by_type(C, ptr, RGN_TYPE_TOOLS, RGN_FLAG_HIDDEN); } +static bool rna_Space_show_region_tool_props_get(PointerRNA *ptr) +{ + return !rna_Space_bool_from_region_flag_get_by_type(ptr, RGN_TYPE_TOOL_PROPS, RGN_FLAG_HIDDEN); +} +static void rna_Space_show_region_tool_props_set(PointerRNA *ptr, bool value) +{ + rna_Space_bool_from_region_flag_set_by_type(ptr, RGN_TYPE_TOOL_PROPS, RGN_FLAG_HIDDEN, !value); +} +static void rna_Space_show_region_tool_props_update(bContext *C, PointerRNA *ptr) +{ + rna_Space_bool_from_region_flag_update_by_type(C, ptr, RGN_TYPE_TOOL_PROPS, RGN_FLAG_HIDDEN); +} + /* Channels Region. */ static bool rna_Space_show_region_channels_get(PointerRNA *ptr) { @@ -3196,6 +3209,10 @@ static void rna_def_space_generic_show_region_toggles(StructRNA *srna, int regio region_type_mask &= ~(1 << RGN_TYPE_TOOLS); DEF_SHOW_REGION_PROPERTY(show_region_toolbar, "Toolbar", ""); } + if (region_type_mask & (1 << RGN_TYPE_TOOL_PROPS)) { + region_type_mask &= ~(1 << RGN_TYPE_TOOL_PROPS); + DEF_SHOW_REGION_PROPERTY(show_region_tool_props, "Toolbar", ""); + } if (region_type_mask & (1 << RGN_TYPE_CHANNELS)) { region_type_mask &= ~(1 << RGN_TYPE_CHANNELS); DEF_SHOW_REGION_PROPERTY(show_region_channels, "Channels", ""); @@ -6546,7 +6563,8 @@ static void rna_def_space_filebrowser(BlenderRNA *brna) RNA_def_struct_sdna(srna, "SpaceFile"); RNA_def_struct_ui_text(srna, "Space File Browser", "File browser space data"); - rna_def_space_generic_show_region_toggles(srna, (1 << RGN_TYPE_TOOLS) | (1 << RGN_TYPE_UI)); + rna_def_space_generic_show_region_toggles( + srna, (1 << RGN_TYPE_TOOLS) | (1 << RGN_TYPE_UI) | (1 << RGN_TYPE_TOOL_PROPS)); prop = RNA_def_property(srna, "browse_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, rna_enum_space_file_browse_mode_items); From ceb049133c6fe7e66e67227c5f8fde311e69aa14 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Mon, 2 Aug 2021 16:50:04 +0200 Subject: [PATCH 16/24] Asset Browser: Don't show inapplicable filter and display settings So far the Asset Browser just showed the same popups and settings as the File Browser. Not all of them made sense for the Asset Browser though. * Don't show inapplicable recursion toggle. * Don't show sorting options, which don't work with assets anyway. * Don't show the Filter popover, there are currently no applicable items in there. Just like in D12057, I decided to add separate classes for the Asset Browser case. Differential Revision: https://developer.blender.org/D12059 --- .../startup/bl_ui/space_filebrowser.py | 59 ++++++++++++------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py index 570d8b42821..81a71ea0de2 100644 --- a/release/scripts/startup/bl_ui/space_filebrowser.py +++ b/release/scripts/startup/bl_ui/space_filebrowser.py @@ -52,18 +52,10 @@ class FILEBROWSER_HT_header(Header): layout.prop_with_popover( params, "display_type", - panel="FILEBROWSER_PT_display", + panel="ASSETBROWSER_PT_display", text="", icon_only=True, ) - layout.prop_with_popover( - params, - "display_type", - panel="FILEBROWSER_PT_filter", - text="", - icon='FILTER', - icon_only=True, - ) layout.prop(params, "filter_search", text="", icon='VIEWZOOM') @@ -96,16 +88,24 @@ class FILEBROWSER_HT_header(Header): layout.template_running_jobs() -class FILEBROWSER_PT_display(Panel): +class FileBrowserPanel: bl_space_type = 'FILE_BROWSER' - bl_region_type = 'HEADER' - bl_label = "Display Settings" # Shows as tooltip in popover - bl_ui_units_x = 10 @classmethod def poll(cls, context): + space_data = context.space_data + # can be None when save/reload with a file selector open - return context.space_data.params is not None + if space_data.params is None: + return False + + return space_data and space_data.type == 'FILE_BROWSER' and space_data.browse_mode == 'FILES' + + +class FILEBROWSER_PT_display(FileBrowserPanel, Panel): + bl_region_type = 'HEADER' + bl_label = "Display Settings" # Shows as tooltip in popover + bl_ui_units_x = 10 def draw(self, context): layout = self.layout @@ -129,17 +129,11 @@ class FILEBROWSER_PT_display(Panel): layout.prop(params, "use_sort_invert") -class FILEBROWSER_PT_filter(Panel): - bl_space_type = 'FILE_BROWSER' +class FILEBROWSER_PT_filter(FileBrowserPanel, Panel): bl_region_type = 'HEADER' bl_label = "Filter Settings" # Shows as tooltip in popover bl_ui_units_x = 8 - @classmethod - def poll(cls, context): - # can be None when save/reload with a file selector open - return context.space_data.params is not None - def draw(self, context): layout = self.layout @@ -579,6 +573,28 @@ class FILEBROWSER_MT_context_menu(Menu): layout.prop_menu_enum(params, "sort_method") +class ASSETBROWSER_PT_display(asset_utils.AssetBrowserPanel, Panel): + bl_region_type = 'HEADER' + bl_label = "Display Settings" # Shows as tooltip in popover + bl_ui_units_x = 10 + + def draw(self, context): + layout = self.layout + + space = context.space_data + params = space.params + + layout.use_property_split = True + layout.use_property_decorate = False # No animation. + + if params.display_type == 'THUMBNAIL': + layout.prop(params, "display_size", text="Size") + else: + col = layout.column(heading="Columns", align=True) + col.prop(params, "show_details_size", text="Size") + col.prop(params, "show_details_datetime", text="Date") + + class AssetBrowserMenu: @classmethod def poll(cls, context): @@ -755,6 +771,7 @@ classes = ( FILEBROWSER_MT_view, FILEBROWSER_MT_select, FILEBROWSER_MT_context_menu, + ASSETBROWSER_PT_display, ASSETBROWSER_MT_editor_menus, ASSETBROWSER_MT_view, ASSETBROWSER_MT_select, From 3ff5d8f719f592c2ea17533532708e883a8baa96 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Mon, 2 Aug 2021 16:59:10 +0200 Subject: [PATCH 17/24] Asset Browser: Proper context menu for assets Add a context menu dedicated to asset operations to the Asset Browser. There are two separate context menus to keep things separated well and avoid confusing if-else logic (similar to D12057 & D12059). Their polls make sure they are displayed for the right contexts only. Also (to be committed as followup cleanup): Remove now unused special handling for assets in file delete operator. Differential Revision: https://developer.blender.org/D12062 --- .../keyconfig/keymap_data/blender_default.py | 1 + .../keymap_data/industry_compatible_data.py | 1 + .../startup/bl_ui/space_filebrowser.py | 35 +++++++++++++++---- source/blender/editors/space_file/file_ops.c | 18 +++------- 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index 3527e993173..a37577e898b 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -2000,6 +2000,7 @@ def km_file_browser(params): ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("increment", -100)]}), *_template_items_context_menu("FILEBROWSER_MT_context_menu", params.context_menu_event), + *_template_items_context_menu("ASSETBROWSER_MT_context_menu", params.context_menu_event), ]) return keymap diff --git a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py index 714126903d8..9d34b110afe 100644 --- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py +++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py @@ -1249,6 +1249,7 @@ def km_file_browser(params): ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("increment", -100)]}), *_template_items_context_menu("FILEBROWSER_MT_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), + *_template_items_context_menu("ASSETBROWSER_MT_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), ]) return keymap diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py index 81a71ea0de2..44631e368a3 100644 --- a/release/scripts/startup/bl_ui/space_filebrowser.py +++ b/release/scripts/startup/bl_ui/space_filebrowser.py @@ -296,7 +296,7 @@ class FILEBROWSER_MT_bookmarks_context_menu(Menu): text="Move to Bottom").direction = 'BOTTOM' -class FILEBROWSER_PT_bookmarks_favorites(Panel): +class FILEBROWSER_PT_bookmarks_favorites(FileBrowserPanel, Panel): bl_space_type = 'FILE_BROWSER' bl_region_type = 'TOOLS' bl_category = "Bookmarks" @@ -526,7 +526,7 @@ class FILEBROWSER_MT_select(FileBrowserMenu, Menu): layout.operator("file.select_box") -class FILEBROWSER_MT_context_menu(Menu): +class FILEBROWSER_MT_context_menu(FileBrowserMenu, Menu): bl_label = "Files Context Menu" def draw(self, context): @@ -553,10 +553,6 @@ class FILEBROWSER_MT_context_menu(Menu): sub.operator_context = 'EXEC_DEFAULT' sub.operator("file.delete", text="Delete") - active_asset = asset_utils.SpaceAssetInfo.get_active_asset(context) - if active_asset: - layout.operator("asset.open_containing_blend_file") - layout.separator() sub = layout.row() @@ -755,6 +751,32 @@ class ASSETBROWSER_UL_metadata_tags(UIList): row.prop(tag, "name", text="", emboss=False, icon_value=icon) +class ASSETBROWSER_MT_context_menu(AssetBrowserMenu, Menu): + bl_label = "Assets Context Menu" + + def draw(self, context): + layout = self.layout + st = context.space_data + params = st.params + + layout.operator("file.refresh", text="Refresh") + + layout.separator() + + sub = layout.row() + sub.operator_context = 'EXEC_DEFAULT' + sub.operator("asset.clear", text="Clear Asset") + + layout.separator() + + layout.operator("asset.open_containing_blend_file") + + layout.separator() + + if params.display_type == 'THUMBNAIL': + layout.prop_menu_enum(params, "display_size") + + classes = ( FILEBROWSER_HT_header, FILEBROWSER_PT_display, @@ -781,6 +803,7 @@ classes = ( ASSETBROWSER_PT_metadata_details, ASSETBROWSER_PT_metadata_tags, ASSETBROWSER_UL_metadata_tags, + ASSETBROWSER_MT_context_menu, ) if __name__ == "__main__": # only for live edit. diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 616e7fe51db..944eb9988fa 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -2830,20 +2830,10 @@ static bool file_delete_single(const FileSelectParams *params, FileDirEntry *file, const char **r_error_message) { - if (file->typeflag & FILE_TYPE_ASSET) { - ID *id = filelist_file_get_id(file); - if (!id) { - *r_error_message = "File is not a local data-block asset."; - return false; - } - ED_asset_clear_id(id); - } - else { - char str[FILE_MAX]; - BLI_join_dirfile(str, sizeof(str), params->dir, file->relpath); - if (BLI_delete_soft(str, r_error_message) != 0 || BLI_exists(str)) { - return false; - } + char str[FILE_MAX]; + BLI_join_dirfile(str, sizeof(str), params->dir, file->relpath); + if (BLI_delete_soft(str, r_error_message) != 0 || BLI_exists(str)) { + return false; } return true; From 1062649b5e686a128c27552f40a912d1ab28e55d Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Thu, 22 Jul 2021 23:09:20 +0200 Subject: [PATCH 18/24] Fix T87041: Driver Editor not updated in realtime Caused by {rBbbb2e0614fc3} Since above commit only the playhead is updated as an overlay in animation playback (was moved out of drawing of the main region for perfomance reasons). The driver value "debug" visualization is very useful to have during playback though but was left in main region drawing as part of `draw_fcurve` (thus does not update in realtime anymore). Moving `graph_draw_driver_debug` into the overlay is not feasible because it requires animation filtering which has significant overhead which needs to be avoided in the overlay which is redrawn on every UI interaction. Now tag the whole main region for updates in the Driver Editor during playback instead (which will make the Drivers Editor as slow during playback as before rBbbb2e0614fc3 -- but with realtime updates of the debug visualization). Maniphest Tasks: T87041 Differential Revision: https://developer.blender.org/D12003 --- source/blender/editors/screen/screen_ops.c | 29 +++++++++++++++++----- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 9534be3509b..f172e22ea56 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -4488,10 +4488,8 @@ static bool match_region_with_redraws(const ScrArea *area, return false; } -static void screen_animation_region_tag_redraw(ScrArea *area, - ARegion *region, - const Scene *scene, - eScreen_Redraws_Flag redraws) +static void screen_animation_region_tag_redraw( + bContext *C, ScrArea *area, ARegion *region, const Scene *scene, eScreen_Redraws_Flag redraws) { /* Do follow time here if editor type supports it */ if ((redraws & TIME_FOLLOW) && @@ -4515,10 +4513,29 @@ static void screen_animation_region_tag_redraw(ScrArea *area, * We do need to redraw when this area is in full screen as no other areas * will be tagged for redrawing. */ if (region->regiontype == RGN_TYPE_WINDOW && !area->full) { - if (ELEM(area->spacetype, SPACE_GRAPH, SPACE_NLA, SPACE_ACTION)) { + if (ELEM(area->spacetype, SPACE_NLA, SPACE_ACTION)) { return; } + /* Drivers Editor needs a full redraw on playback for graph_draw_driver_debug(). + * This will make it slower than regular graph editor during playback, but drawing this in + * graph_main_region_draw_overlay() is not feasible because it requires animation filtering + * which has significant overhead which needs to be avoided in the overlay which is redrawn on + * every UI interaction. */ + if (area->spacetype == SPACE_GRAPH) { + const SpaceGraph *sipo = area->spacedata.first; + if (sipo->mode != SIPO_MODE_DRIVERS) { + return; + } + bAnimContext ac; + if (ANIM_animdata_get_context(C, &ac) == false) { + return; + } + if (ac.datatype != ANIMCONT_DRIVERS) { + return; + } + } + if (area->spacetype == SPACE_SEQ) { const SpaceSeq *sseq = area->spacedata.first; if (!ED_space_sequencer_has_playback_animation(sseq, scene)) { @@ -4712,7 +4729,7 @@ static int screen_animation_step_invoke(bContext *C, wmOperator *UNUSED(op), con } if (redraw) { - screen_animation_region_tag_redraw(area, region, scene, sad->redraws); + screen_animation_region_tag_redraw(C, area, region, scene, sad->redraws); } } } From eccd8af828ea9dea434905e0ed1c5348f77fbfd5 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 2 Aug 2021 17:15:53 +0200 Subject: [PATCH 19/24] Revert "GHOST/X11: enable EGL" This is causing issues for some users launching Blender, because EGL indirectly requires GLVND, which is not installed by default on e.g. Ubuntu. This reverts commit 0b18a618b88b22663e05eca0f4d976875710e7cc. Fixes T90374 Ref D12034 --- CMakeLists.txt | 31 +++++++------------ build_files/build_environment/install_deps.sh | 13 ++++++++ .../cmake/platform/platform_unix.cmake | 2 ++ 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5072977215d..6c6408bee2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -251,6 +251,16 @@ if(WITH_GHOST_X11) option(WITH_X11_ALPHA "Enable X11 transparent background" ON) endif() +if(UNIX AND NOT APPLE) + option(WITH_SYSTEM_GLEW "Use GLEW OpenGL wrapper library provided by the operating system" OFF) + option(WITH_SYSTEM_GLES "Use OpenGL ES library provided by the operating system" ON) +else() + # not an option for other OS's + set(WITH_SYSTEM_GLEW OFF) + set(WITH_SYSTEM_GLES OFF) +endif() + + if(UNIX AND NOT APPLE) option(WITH_SYSTEM_EIGEN3 "Use the systems Eigen3 library" OFF) endif() @@ -475,32 +485,15 @@ endif() # OpenGL -if(UNIX AND NOT APPLE) - # GLEW can only built with either GLX or EGL support and most binary - # distributions are built with GLX support. So we always compile GLEW - # with EGL support manually, and the options are no longer available. - set(WITH_SYSTEM_GLEW OFF) - set(WITH_SYSTEM_GLES ON) - - # Always use EGL instead of GLX, for X11, Wayland and headless. - set(WITH_GL_EGL ON) -else() - # System GLEW and GLES were never an option on other platforms. - set(WITH_SYSTEM_GLEW OFF) - set(WITH_SYSTEM_GLES OFF) - - # Experimental EGL option. - option(WITH_GL_EGL "Use the EGL OpenGL system library instead of the platform specific OpenGL system library (CGL or WGL)" OFF) - mark_as_advanced(WITH_GL_EGL) -endif() - option(WITH_OPENGL "When off limits visibility of the opengl headers to just bf_gpu and gawain (temporary option for development purposes)" ON) option(WITH_GLEW_ES "Switches to experimental copy of GLEW that has support for OpenGL ES. (temporary option for development purposes)" OFF) +option(WITH_GL_EGL "Use the EGL OpenGL system library instead of the platform specific OpenGL system library (CGL, glX, or WGL)" OFF) option(WITH_GL_PROFILE_ES20 "Support using OpenGL ES 2.0. (through either EGL or the AGL/WGL/XGL 'es20' profile)" OFF) mark_as_advanced( WITH_OPENGL WITH_GLEW_ES + WITH_GL_EGL WITH_GL_PROFILE_ES20 ) diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index fd4f59fcda7..26281887e1f 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -603,6 +603,9 @@ MP3LAME_DEV="" OPENJPEG_USE=false OPENJPEG_DEV="" +# Whether to use system GLEW or not (OpenSubDiv needs recent glew to work). +NO_SYSTEM_GLEW=false + # Switch to english language, else some things (like check_package_DEB()) won't work! LANG_BACK=$LANG LANG="" @@ -3982,9 +3985,13 @@ install_DEB() { version_ge $_glew "1.7.0" if [ $? -eq 1 ]; then WARNING "OpenSubdiv disabled because GLEW-$_glew is not enough" + WARNING "Blender will not use system GLEW library" OSD_SKIP=true + NO_SYSTEM_GLEW=true else WARNING "OpenSubdiv will compile with GLEW-$_glew but with limited capability" + WARNING "Blender will not use system GLEW library" + NO_SYSTEM_GLEW=true fi fi @@ -5955,6 +5962,12 @@ print_info() { fi fi + if [ "$NO_SYSTEM_GLEW" = true ]; then + _1="-D WITH_SYSTEM_GLEW=OFF" + PRINT " $_1" + _buildargs="$_buildargs $_1" + fi + if [ "$FFMPEG_SKIP" = false ]; then _1="-D WITH_CODEC_FFMPEG=ON" _2="-D FFMPEG_LIBRARIES='avformat;avcodec;avutil;avdevice;swscale;swresample;lzma;rt;`print_info_ffmpeglink`'" diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake index ffdbbc3f8c5..7f62399ac4f 100644 --- a/build_files/cmake/platform/platform_unix.cmake +++ b/build_files/cmake/platform/platform_unix.cmake @@ -581,6 +581,8 @@ if(WITH_GHOST_WAYLAND) pkg_check_modules(wayland-cursor REQUIRED wayland-cursor) pkg_check_modules(dbus REQUIRED dbus-1) + set(WITH_GL_EGL ON) + list(APPEND PLATFORM_LINKLIBS ${wayland-client_LINK_LIBRARIES} ${wayland-egl_LINK_LIBRARIES} From 77187718e4fb51ad8b1e486d0c09fcb0998afcd6 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Fri, 30 Jul 2021 08:34:24 +0200 Subject: [PATCH 20/24] Fix T78469: Output Metadata: Strip Name no longer accessible Caused by rB7fc60bff14a6. This has actually been reported and closed, but that was clearly a misunderstanding (above commit changed a checkbox to be an enum, but a second checkbox was simply removed) Maniphest Tasks: T78469 Differential Revision: https://developer.blender.org/D12084 --- release/scripts/startup/bl_ui/properties_output.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/release/scripts/startup/bl_ui/properties_output.py b/release/scripts/startup/bl_ui/properties_output.py index 75c1f69f84f..0c1a26ceec1 100644 --- a/release/scripts/startup/bl_ui/properties_output.py +++ b/release/scripts/startup/bl_ui/properties_output.py @@ -205,6 +205,9 @@ class RENDER_PT_stamp(RenderOutputButtonsPanel, Panel): col.prop(rd, "use_stamp_marker", text="Marker") col.prop(rd, "use_stamp_filename", text="Filename") + if rd.use_sequencer: + col.prop(rd, "use_stamp_sequencer_strip", text="Strip Name") + class RENDER_PT_stamp_note(RenderOutputButtonsPanel, Panel): bl_label = "Note" From 67d56eb71ef1b8da62d296290a87e7129f4c5ac6 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 2 Aug 2021 12:26:28 -0400 Subject: [PATCH 21/24] Cleanup: Remove unused/unecessary OpenVDB C API This commit uses OpenVDB more directly for the voxel remesher, without the extra indirection of copying to a Blender API. This makes the code simpler, shorter, and easier to understand (though I didn't observe any performance improvement). This also removes the rest of the unused and undocumented OpenVDB C API, which was written when Blender's code didn't really use C++, and doesn't serve a purpose anymore. Those features will be implemented as nodes in the future anyway (see D12100). Differential Revision: https://developer.blender.org/D12097 --- intern/openvdb/CMakeLists.txt | 8 - intern/openvdb/intern/openvdb_level_set.cc | 173 ------------------ intern/openvdb/intern/openvdb_level_set.h | 60 ------ intern/openvdb/intern/openvdb_transform.cc | 43 ----- intern/openvdb/intern/openvdb_transform.h | 37 ---- intern/openvdb/openvdb_capi.cc | 144 +-------------- intern/openvdb/openvdb_capi.h | 116 ------------ intern/openvdb/openvdb_util.cc | 36 ---- intern/openvdb/openvdb_util.h | 51 ------ .../blenkernel/BKE_mesh_remesh_voxel.h | 4 - .../blenkernel/intern/mesh_remesh_voxel.cc | 122 ++++++------ 11 files changed, 56 insertions(+), 738 deletions(-) delete mode 100644 intern/openvdb/intern/openvdb_level_set.cc delete mode 100644 intern/openvdb/intern/openvdb_level_set.h delete mode 100644 intern/openvdb/intern/openvdb_transform.cc delete mode 100644 intern/openvdb/intern/openvdb_transform.h delete mode 100644 intern/openvdb/openvdb_util.cc delete mode 100644 intern/openvdb/openvdb_util.h diff --git a/intern/openvdb/CMakeLists.txt b/intern/openvdb/CMakeLists.txt index d695e5533c0..9d37c6cd24c 100644 --- a/intern/openvdb/CMakeLists.txt +++ b/intern/openvdb/CMakeLists.txt @@ -20,7 +20,6 @@ set(INC . - intern ../guardedalloc ) @@ -42,14 +41,7 @@ if(WITH_OPENVDB) ) list(APPEND SRC - intern/openvdb_level_set.cc - intern/openvdb_transform.cc openvdb_capi.cc - openvdb_util.cc - - intern/openvdb_level_set.h - intern/openvdb_transform.h - openvdb_util.h ) list(APPEND LIB diff --git a/intern/openvdb/intern/openvdb_level_set.cc b/intern/openvdb/intern/openvdb_level_set.cc deleted file mode 100644 index 5b01c3b0cb7..00000000000 --- a/intern/openvdb/intern/openvdb_level_set.cc +++ /dev/null @@ -1,173 +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. - * - * The Original Code is Copyright (C) 2015 Blender Foundation. - * All rights reserved. - */ - -#include "openvdb_level_set.h" -#include "MEM_guardedalloc.h" -#include "openvdb/tools/Composite.h" -#include "openvdb_capi.h" -#include "openvdb_util.h" - -OpenVDBLevelSet::OpenVDBLevelSet() -{ - openvdb::initialize(); -} - -OpenVDBLevelSet::~OpenVDBLevelSet() -{ -} - -void OpenVDBLevelSet::mesh_to_level_set(const float *vertices, - const int *faces, - const int totvertices, - const int totfaces, - const openvdb::math::Transform::Ptr &xform) -{ - std::vector points(totvertices); - std::vector triangles(totfaces); - std::vector quads; - - for (int i = 0; i < totvertices; i++) { - points[i] = openvdb::Vec3s(vertices[i * 3], vertices[i * 3 + 1], vertices[i * 3 + 2]); - } - - for (int i = 0; i < totfaces; i++) { - triangles[i] = openvdb::Vec3I(faces[i * 3], faces[i * 3 + 1], faces[i * 3 + 2]); - } - - this->grid = openvdb::tools::meshToLevelSet( - *xform, points, triangles, quads, 1); -} - -void OpenVDBLevelSet::volume_to_mesh(OpenVDBVolumeToMeshData *mesh, - const double isovalue, - const double adaptivity, - const bool relax_disoriented_triangles) -{ - std::vector out_points; - std::vector out_quads; - std::vector out_tris; - openvdb::tools::volumeToMesh(*this->grid, - out_points, - out_tris, - out_quads, - isovalue, - adaptivity, - relax_disoriented_triangles); - mesh->vertices = (float *)MEM_malloc_arrayN(out_points.size(), sizeof(float[3]), __func__); - mesh->quads = (int *)MEM_malloc_arrayN(out_quads.size(), sizeof(int[4]), __func__); - mesh->triangles = NULL; - if (out_tris.size() > 0) { - mesh->triangles = (int *)MEM_malloc_arrayN(out_tris.size(), sizeof(int[3]), __func__); - } - - mesh->totvertices = out_points.size(); - mesh->tottriangles = out_tris.size(); - mesh->totquads = out_quads.size(); - - for (size_t i = 0; i < out_points.size(); i++) { - mesh->vertices[i * 3] = out_points[i].x(); - mesh->vertices[i * 3 + 1] = out_points[i].y(); - mesh->vertices[i * 3 + 2] = out_points[i].z(); - } - - for (size_t i = 0; i < out_quads.size(); i++) { - mesh->quads[i * 4] = out_quads[i].x(); - mesh->quads[i * 4 + 1] = out_quads[i].y(); - mesh->quads[i * 4 + 2] = out_quads[i].z(); - mesh->quads[i * 4 + 3] = out_quads[i].w(); - } - - for (size_t i = 0; i < out_tris.size(); i++) { - mesh->triangles[i * 3] = out_tris[i].x(); - mesh->triangles[i * 3 + 1] = out_tris[i].y(); - mesh->triangles[i * 3 + 2] = out_tris[i].z(); - } -} - -void OpenVDBLevelSet::filter(OpenVDBLevelSet_FilterType filter_type, - int width, - float distance, - OpenVDBLevelSet_FilterBias filter_bias) -{ - - if (!this->grid) { - return; - } - - if (this->grid->getGridClass() != openvdb::GRID_LEVEL_SET) { - return; - } - - openvdb::tools::LevelSetFilter filter(*this->grid); - filter.setSpatialScheme((openvdb::math::BiasedGradientScheme)filter_bias); - switch (filter_type) { - case OPENVDB_LEVELSET_FILTER_GAUSSIAN: - filter.gaussian(width); - break; - case OPENVDB_LEVELSET_FILTER_MEDIAN: - filter.median(width); - break; - case OPENVDB_LEVELSET_FILTER_MEAN: - filter.mean(width); - break; - case OPENVDB_LEVELSET_FILTER_MEAN_CURVATURE: - filter.meanCurvature(); - break; - case OPENVDB_LEVELSET_FILTER_LAPLACIAN: - filter.laplacian(); - break; - case OPENVDB_LEVELSET_FILTER_DILATE: - filter.offset(distance); - break; - case OPENVDB_LEVELSET_FILTER_ERODE: - filter.offset(distance); - break; - case OPENVDB_LEVELSET_FILTER_NONE: - break; - } -} -openvdb::FloatGrid::Ptr OpenVDBLevelSet::CSG_operation_apply( - const openvdb::FloatGrid::Ptr &gridA, - const openvdb::FloatGrid::Ptr &gridB, - OpenVDBLevelSet_CSGOperation operation) -{ - switch (operation) { - case OPENVDB_LEVELSET_CSG_UNION: - openvdb::tools::csgUnion(*gridA, *gridB); - break; - case OPENVDB_LEVELSET_CSG_DIFFERENCE: - openvdb::tools::csgDifference(*gridA, *gridB); - break; - case OPENVDB_LEVELSET_CSG_INTERSECTION: - openvdb::tools::csgIntersection(*gridA, *gridB); - break; - } - - return gridA; -} - -const openvdb::FloatGrid::Ptr &OpenVDBLevelSet::get_grid() -{ - return this->grid; -} - -void OpenVDBLevelSet::set_grid(const openvdb::FloatGrid::Ptr &grid) -{ - this->grid = grid; -} diff --git a/intern/openvdb/intern/openvdb_level_set.h b/intern/openvdb/intern/openvdb_level_set.h deleted file mode 100644 index 2c8f140c012..00000000000 --- a/intern/openvdb/intern/openvdb_level_set.h +++ /dev/null @@ -1,60 +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. - * - * The Original Code is Copyright (C) 2015 Blender Foundation. - * All rights reserved. - */ - -#ifndef __OPENVDB_LEVEL_SET_H__ -#define __OPENVDB_LEVEL_SET_H__ - -#include "openvdb_capi.h" -#include -#include -#include -#include -#include -#include - -struct OpenVDBLevelSet { - private: - openvdb::FloatGrid::Ptr grid; - - public: - OpenVDBLevelSet(); - ~OpenVDBLevelSet(); - const openvdb::FloatGrid::Ptr &get_grid(); - void set_grid(const openvdb::FloatGrid::Ptr &grid); - - void mesh_to_level_set(const float *vertices, - const int *faces, - const int totvertices, - const int totfaces, - const openvdb::math::Transform::Ptr &transform); - - void volume_to_mesh(struct OpenVDBVolumeToMeshData *mesh, - const double isovalue, - const double adaptivity, - const bool relax_disoriented_triangles); - void filter(OpenVDBLevelSet_FilterType filter_type, - int width, - float distance, - OpenVDBLevelSet_FilterBias filter_bias); - openvdb::FloatGrid::Ptr CSG_operation_apply(const openvdb::FloatGrid::Ptr &gridA, - const openvdb::FloatGrid::Ptr &gridB, - OpenVDBLevelSet_CSGOperation operation); -}; - -#endif /* __OPENVDB_LEVEL_SET_H__ */ diff --git a/intern/openvdb/intern/openvdb_transform.cc b/intern/openvdb/intern/openvdb_transform.cc deleted file mode 100644 index 4bfcf43f81a..00000000000 --- a/intern/openvdb/intern/openvdb_transform.cc +++ /dev/null @@ -1,43 +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. - * - * The Original Code is Copyright (C) 2015 Blender Foundation. - * All rights reserved. - */ - -#include "openvdb_transform.h" - -OpenVDBTransform::OpenVDBTransform() -{ -} - -OpenVDBTransform::~OpenVDBTransform() -{ -} - -void OpenVDBTransform::create_linear_transform(double voxel_size) -{ - this->transform = openvdb::math::Transform::createLinearTransform(voxel_size); -} - -const openvdb::math::Transform::Ptr &OpenVDBTransform::get_transform() -{ - return this->transform; -} - -void OpenVDBTransform::set_transform(const openvdb::math::Transform::Ptr &transform) -{ - this->transform = transform; -} diff --git a/intern/openvdb/intern/openvdb_transform.h b/intern/openvdb/intern/openvdb_transform.h deleted file mode 100644 index e2528cd0192..00000000000 --- a/intern/openvdb/intern/openvdb_transform.h +++ /dev/null @@ -1,37 +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. - * - * The Original Code is Copyright (C) 2015 Blender Foundation. - * All rights reserved. - */ - -#ifndef OPENVDB_TRANSFORM_H -#define OPENVDB_TRANSFORM_H - -#include - -struct OpenVDBTransform { - private: - openvdb::math::Transform::Ptr transform; - - public: - OpenVDBTransform(); - ~OpenVDBTransform(); - void create_linear_transform(double voxel_size); - const openvdb::math::Transform::Ptr &get_transform(); - void set_transform(const openvdb::math::Transform::Ptr &transform); -}; - -#endif // OPENVDB_TRANSFORM_H diff --git a/intern/openvdb/openvdb_capi.cc b/intern/openvdb/openvdb_capi.cc index 674b394fa46..9c676e33ecc 100644 --- a/intern/openvdb/openvdb_capi.cc +++ b/intern/openvdb/openvdb_capi.cc @@ -18,151 +18,9 @@ */ #include "openvdb_capi.h" -#include "openvdb_level_set.h" -#include "openvdb_transform.h" -#include "openvdb_util.h" +#include int OpenVDB_getVersionHex() { return openvdb::OPENVDB_LIBRARY_VERSION; } - -OpenVDBLevelSet *OpenVDBLevelSet_create(bool initGrid, OpenVDBTransform *xform) -{ - OpenVDBLevelSet *level_set = new OpenVDBLevelSet(); - if (initGrid) { - openvdb::FloatGrid::Ptr grid = openvdb::FloatGrid::create(); - grid->setGridClass(openvdb::GRID_LEVEL_SET); - if (xform) { - grid->setTransform(xform->get_transform()); - } - level_set->set_grid(grid); - } - return level_set; -} - -OpenVDBTransform *OpenVDBTransform_create() -{ - return new OpenVDBTransform(); -} - -void OpenVDBTransform_free(OpenVDBTransform *transform) -{ - delete transform; -} - -void OpenVDBTransform_create_linear_transform(OpenVDBTransform *transform, double voxel_size) -{ - transform->create_linear_transform(voxel_size); -} - -void OpenVDBLevelSet_free(OpenVDBLevelSet *level_set) -{ - delete level_set; -} - -void OpenVDBLevelSet_mesh_to_level_set(struct OpenVDBLevelSet *level_set, - const float *vertices, - const int *faces, - const int totvertices, - const int totfaces, - OpenVDBTransform *xform) -{ - level_set->mesh_to_level_set(vertices, faces, totvertices, totfaces, xform->get_transform()); -} - -void OpenVDBLevelSet_mesh_to_level_set_transform(struct OpenVDBLevelSet *level_set, - const float *vertices, - const int *faces, - const int totvertices, - const int totfaces, - OpenVDBTransform *transform) -{ - level_set->mesh_to_level_set(vertices, faces, totvertices, totfaces, transform->get_transform()); -} - -void OpenVDBLevelSet_volume_to_mesh(struct OpenVDBLevelSet *level_set, - struct OpenVDBVolumeToMeshData *mesh, - const double isovalue, - const double adaptivity, - const bool relax_disoriented_triangles) -{ - level_set->volume_to_mesh(mesh, isovalue, adaptivity, relax_disoriented_triangles); -} - -void OpenVDBLevelSet_filter(struct OpenVDBLevelSet *level_set, - OpenVDBLevelSet_FilterType filter_type, - int width, - float distance, - OpenVDBLevelSet_FilterBias bias) -{ - level_set->filter(filter_type, width, distance, bias); -} - -void OpenVDBLevelSet_CSG_operation(struct OpenVDBLevelSet *out, - struct OpenVDBLevelSet *gridA, - struct OpenVDBLevelSet *gridB, - OpenVDBLevelSet_CSGOperation operation) -{ - openvdb::FloatGrid::Ptr grid = out->CSG_operation_apply( - gridA->get_grid(), gridB->get_grid(), operation); - out->set_grid(grid); -} - -OpenVDBLevelSet *OpenVDBLevelSet_transform_and_resample(struct OpenVDBLevelSet *level_setA, - struct OpenVDBLevelSet *level_setB, - char sampler, - float isolevel) -{ - openvdb::FloatGrid::Ptr sourceGrid = level_setA->get_grid(); - openvdb::FloatGrid::Ptr targetGrid = level_setB->get_grid()->deepCopy(); - - const openvdb::math::Transform &sourceXform = sourceGrid->transform(), - &targetXform = targetGrid->transform(); - - // Compute a source grid to target grid transform. - // (For this example, we assume that both grids' transforms are linear, - // so that they can be represented as 4 x 4 matrices.) - openvdb::Mat4R xform = sourceXform.baseMap()->getAffineMap()->getMat4() * - targetXform.baseMap()->getAffineMap()->getMat4().inverse(); - - // Create the transformer. - openvdb::tools::GridTransformer transformer(xform); - - switch (sampler) { - case OPENVDB_LEVELSET_GRIDSAMPLER_POINT: - // Resample using nearest-neighbor interpolation. - transformer.transformGrid(*sourceGrid, - *targetGrid); - // Prune the target tree for optimal sparsity. - targetGrid->tree().prune(); - break; - - case OPENVDB_LEVELSET_GRIDSAMPLER_BOX: - // Resample using trilinear interpolation. - transformer.transformGrid(*sourceGrid, - *targetGrid); - // Prune the target tree for optimal sparsity. - targetGrid->tree().prune(); - break; - - case OPENVDB_LEVELSET_GRIDSAMPLER_QUADRATIC: - // Resample using triquadratic interpolation. - transformer.transformGrid(*sourceGrid, - *targetGrid); - // Prune the target tree for optimal sparsity. - targetGrid->tree().prune(); - break; - - case OPENVDB_LEVELSET_GRIDSAMPLER_NONE: - break; - } - - targetGrid = openvdb::tools::levelSetRebuild(*targetGrid, isolevel, 1.0f); - openvdb::tools::pruneLevelSet(targetGrid->tree()); - - OpenVDBLevelSet *level_set = OpenVDBLevelSet_create(false, NULL); - level_set->set_grid(targetGrid); - - return level_set; -} diff --git a/intern/openvdb/openvdb_capi.h b/intern/openvdb/openvdb_capi.h index 9333413c2fe..3db1ef9484b 100644 --- a/intern/openvdb/openvdb_capi.h +++ b/intern/openvdb/openvdb_capi.h @@ -24,124 +24,8 @@ extern "C" { #endif -/* Level Set Filters */ -typedef enum OpenVDBLevelSet_FilterType { - OPENVDB_LEVELSET_FILTER_NONE = 0, - OPENVDB_LEVELSET_FILTER_GAUSSIAN = 1, - OPENVDB_LEVELSET_FILTER_MEAN = 2, - OPENVDB_LEVELSET_FILTER_MEDIAN = 3, - OPENVDB_LEVELSET_FILTER_MEAN_CURVATURE = 4, - OPENVDB_LEVELSET_FILTER_LAPLACIAN = 5, - OPENVDB_LEVELSET_FILTER_DILATE = 6, - OPENVDB_LEVELSET_FILTER_ERODE = 7, -} OpenVDBLevelSet_FilterType; - -typedef enum OpenVDBLevelSet_FilterBias { - OPENVDB_LEVELSET_FIRST_BIAS = 0, - OPENVDB_LEVELSET_SECOND_BIAS, - OPENVDB_LEVELSET_THIRD_BIAS, - OPENVDB_LEVELSET_WENO5_BIAS, - OPENVDB_LEVELSET_HJWENO5_BIAS, -} OpenVDBLevelSet_FilterBias; - -/* Level Set CSG Operations */ -typedef enum OpenVDBLevelSet_CSGOperation { - OPENVDB_LEVELSET_CSG_UNION = 0, - OPENVDB_LEVELSET_CSG_DIFFERENCE = 1, - OPENVDB_LEVELSET_CSG_INTERSECTION = 2, -} OpenVDBLevelSet_CSGOperation; - -typedef enum OpenVDBLevelSet_GridSampler { - OPENVDB_LEVELSET_GRIDSAMPLER_NONE = 0, - OPENVDB_LEVELSET_GRIDSAMPLER_POINT = 1, - OPENVDB_LEVELSET_GRIDSAMPLER_BOX = 2, - OPENVDB_LEVELSET_GRIDSAMPLER_QUADRATIC = 3, -} OpenVDBLevelSet_Gridsampler; - -struct OpenVDBTransform; -struct OpenVDBLevelSet; - -struct OpenVDBVolumeToMeshData { - int tottriangles; - int totquads; - int totvertices; - - float *vertices; - int *quads; - int *triangles; -}; - -struct OpenVDBRemeshData { - float *verts; - int *faces; - int totfaces; - int totverts; - - float *out_verts; - int *out_faces; - int *out_tris; - int out_totverts; - int out_totfaces; - int out_tottris; - int filter_type; - enum OpenVDBLevelSet_FilterType filter_bias; - enum OpenVDBLevelSet_FilterBias filter_width; /* Parameter for gaussian, median, mean. */ - - float voxel_size; - float isovalue; - float adaptivity; - int relax_disoriented_triangles; -}; - int OpenVDB_getVersionHex(void); -enum { - VEC_INVARIANT = 0, - VEC_COVARIANT = 1, - VEC_COVARIANT_NORMALIZE = 2, - VEC_CONTRAVARIANT_RELATIVE = 3, - VEC_CONTRAVARIANT_ABSOLUTE = 4, -}; - -struct OpenVDBTransform *OpenVDBTransform_create(void); -void OpenVDBTransform_free(struct OpenVDBTransform *transform); -void OpenVDBTransform_create_linear_transform(struct OpenVDBTransform *transform, - double voxel_size); - -struct OpenVDBLevelSet *OpenVDBLevelSet_create(bool initGrid, struct OpenVDBTransform *xform); -void OpenVDBLevelSet_free(struct OpenVDBLevelSet *level_set); -void OpenVDBLevelSet_mesh_to_level_set(struct OpenVDBLevelSet *level_set, - const float *vertices, - const int *faces, - const int totvertices, - const int totfaces, - struct OpenVDBTransform *xform); -void OpenVDBLevelSet_mesh_to_level_set_transform(struct OpenVDBLevelSet *level_set, - const float *vertices, - const int *faces, - const int totvertices, - const int totfaces, - struct OpenVDBTransform *transform); -void OpenVDBLevelSet_volume_to_mesh(struct OpenVDBLevelSet *level_set, - struct OpenVDBVolumeToMeshData *mesh, - const double isovalue, - const double adaptivity, - const bool relax_disoriented_triangles); -void OpenVDBLevelSet_filter(struct OpenVDBLevelSet *level_set, - OpenVDBLevelSet_FilterType filter_type, - int width, - float distance, - OpenVDBLevelSet_FilterBias bias); -void OpenVDBLevelSet_CSG_operation(struct OpenVDBLevelSet *out, - struct OpenVDBLevelSet *gridA, - struct OpenVDBLevelSet *gridB, - OpenVDBLevelSet_CSGOperation operation); - -struct OpenVDBLevelSet *OpenVDBLevelSet_transform_and_resample(struct OpenVDBLevelSet *level_setA, - struct OpenVDBLevelSet *level_setB, - char sampler, - float isolevel); - #ifdef __cplusplus } #endif diff --git a/intern/openvdb/openvdb_util.cc b/intern/openvdb/openvdb_util.cc deleted file mode 100644 index 899b41ff09b..00000000000 --- a/intern/openvdb/openvdb_util.cc +++ /dev/null @@ -1,36 +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. - * - * The Original Code is Copyright (C) 2015 Blender Foundation. - * All rights reserved. - */ - -#include "openvdb_util.h" - -#include - -ScopeTimer::ScopeTimer(const std::string &message) : m_message(message), m_timer() -{ -} - -ScopeTimer::~ScopeTimer() -{ -#if OPENVDB_LIBRARY_MAJOR_VERSION_NUMBER >= 7 - double delta = m_timer.milliseconds(); -#else - double delta = m_timer.delta(); /* Deprecated in OpenVDB 7. */ -#endif - std::printf("%s: %fms\n", m_message.c_str(), delta); -} diff --git a/intern/openvdb/openvdb_util.h b/intern/openvdb/openvdb_util.h deleted file mode 100644 index 7a19d588068..00000000000 --- a/intern/openvdb/openvdb_util.h +++ /dev/null @@ -1,51 +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. - * - * The Original Code is Copyright (C) 2015 Blender Foundation. - * All rights reserved. - */ - -#ifndef __OPENVDB_UTIL_H__ -#define __OPENVDB_UTIL_H__ - -#include -#include - -#define CATCH_KEYERROR \ - catch (const openvdb::KeyError &e) \ - { \ - std::cerr << e.what() << '\n'; \ - } - -//#define DEBUG_TIME - -/* A utility class which prints the time elapsed during its lifetime, useful for - * e.g. timing the overall execution time of a function */ -class ScopeTimer { - std::string m_message; - openvdb::util::CpuTimer m_timer; - - public: - ScopeTimer(const std::string &message); - ~ScopeTimer(); -}; - -#ifdef DEBUG_TIME -# define Timer(x) ScopeTimer prof(x); -#else -# define Timer(x) -#endif - -#endif /* __OPENVDB_UTIL_H__ */ diff --git a/source/blender/blenkernel/BKE_mesh_remesh_voxel.h b/source/blender/blenkernel/BKE_mesh_remesh_voxel.h index 5887db59ff2..80ced9b5f57 100644 --- a/source/blender/blenkernel/BKE_mesh_remesh_voxel.h +++ b/source/blender/blenkernel/BKE_mesh_remesh_voxel.h @@ -23,10 +23,6 @@ * \ingroup bke */ -#ifdef WITH_OPENVDB -# include "openvdb_capi.h" -#endif - #ifdef __cplusplus extern "C" { #endif diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc index 8364b0ec024..4484dd5bf09 100644 --- a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc +++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc @@ -33,6 +33,7 @@ #include "BLI_array.hh" #include "BLI_float3.hh" #include "BLI_index_range.hh" +#include "BLI_span.hh" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -48,7 +49,9 @@ #include "bmesh_tools.h" #ifdef WITH_OPENVDB -# include "openvdb_capi.h" +# include +# include +# include #endif #ifdef WITH_QUADRIFLOW @@ -58,6 +61,8 @@ using blender::Array; using blender::float3; using blender::IndexRange; +using blender::MutableSpan; +using blender::Span; #ifdef WITH_QUADRIFLOW static Mesh *remesh_quadriflow(const Mesh *input_mesh, @@ -192,92 +197,81 @@ Mesh *BKE_mesh_remesh_quadriflow(const Mesh *mesh, } #ifdef WITH_OPENVDB -static struct OpenVDBLevelSet *remesh_voxel_level_set_create(const Mesh *mesh, - struct OpenVDBTransform *transform) +static openvdb::FloatGrid::Ptr remesh_voxel_level_set_create(const Mesh *mesh, + const float voxel_size) { - const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh); - MVertTri *verttri = (MVertTri *)MEM_callocN( - sizeof(*verttri) * BKE_mesh_runtime_looptri_len(mesh), "remesh_looptri"); - BKE_mesh_runtime_verttri_from_looptri( - verttri, mesh->mloop, looptri, BKE_mesh_runtime_looptri_len(mesh)); + Span mloop{mesh->mloop, mesh->totloop}; + Span looptris{BKE_mesh_runtime_looptri_ensure(mesh), + BKE_mesh_runtime_looptri_len(mesh)}; - const int totfaces = BKE_mesh_runtime_looptri_len(mesh); - const int totverts = mesh->totvert; - Array verts(totverts); - Array faces(totfaces * 3); + std::vector points(mesh->totvert); + std::vector triangles(looptris.size()); - for (const int i : IndexRange(totverts)) { - verts[i] = mesh->mvert[i].co; + for (const int i : IndexRange(mesh->totvert)) { + const float3 co = mesh->mvert[i].co; + points[i] = openvdb::Vec3s(co.x, co.y, co.z); } - for (const int i : IndexRange(totfaces)) { - MVertTri &vt = verttri[i]; - faces[i * 3] = vt.tri[0]; - faces[i * 3 + 1] = vt.tri[1]; - faces[i * 3 + 2] = vt.tri[2]; + for (const int i : IndexRange(looptris.size())) { + const MLoopTri &loop_tri = looptris[i]; + triangles[i] = openvdb::Vec3I( + mloop[loop_tri.tri[0]].v, mloop[loop_tri.tri[1]].v, mloop[loop_tri.tri[2]].v); } - struct OpenVDBLevelSet *level_set = OpenVDBLevelSet_create(false, nullptr); - OpenVDBLevelSet_mesh_to_level_set( - level_set, (const float *)verts.data(), faces.data(), totverts, totfaces, transform); + openvdb::math::Transform::Ptr transform = openvdb::math::Transform::createLinearTransform( + voxel_size); + openvdb::FloatGrid::Ptr grid = openvdb::tools::meshToLevelSet( + *transform, points, triangles, 1.0f); - MEM_freeN(verttri); - - return level_set; + return grid; } -static Mesh *remesh_voxel_volume_to_mesh(struct OpenVDBLevelSet *level_set, - double isovalue, - double adaptivity, - bool relax_disoriented_triangles) +static Mesh *remesh_voxel_volume_to_mesh(const openvdb::FloatGrid::Ptr level_set_grid, + const float isovalue, + const float adaptivity, + const bool relax_disoriented_triangles) { - struct OpenVDBVolumeToMeshData output_mesh; - OpenVDBLevelSet_volume_to_mesh( - level_set, &output_mesh, isovalue, adaptivity, relax_disoriented_triangles); + std::vector vertices; + std::vector quads; + std::vector tris; + openvdb::tools::volumeToMesh( + *level_set_grid, vertices, tris, quads, isovalue, adaptivity, relax_disoriented_triangles); - Mesh *mesh = BKE_mesh_new_nomain(output_mesh.totvertices, - 0, - 0, - (output_mesh.totquads * 4) + (output_mesh.tottriangles * 3), - output_mesh.totquads + output_mesh.tottriangles); + Mesh *mesh = BKE_mesh_new_nomain( + vertices.size(), 0, 0, quads.size() * 4 + tris.size() * 3, quads.size() + tris.size()); + MutableSpan mverts{mesh->mvert, mesh->totvert}; + MutableSpan mloops{mesh->mloop, mesh->totloop}; + MutableSpan mpolys{mesh->mpoly, mesh->totpoly}; - for (const int i : IndexRange(output_mesh.totvertices)) { - copy_v3_v3(mesh->mvert[i].co, &output_mesh.vertices[i * 3]); + for (const int i : mverts.index_range()) { + copy_v3_v3(mverts[i].co, float3(vertices[i].x(), vertices[i].y(), vertices[i].z())); } - for (const int i : IndexRange(output_mesh.totquads)) { - MPoly &poly = mesh->mpoly[i]; + for (const int i : IndexRange(quads.size())) { + MPoly &poly = mpolys[i]; const int loopstart = i * 4; poly.loopstart = loopstart; poly.totloop = 4; - mesh->mloop[loopstart].v = output_mesh.quads[loopstart]; - mesh->mloop[loopstart + 1].v = output_mesh.quads[loopstart + 1]; - mesh->mloop[loopstart + 2].v = output_mesh.quads[loopstart + 2]; - mesh->mloop[loopstart + 3].v = output_mesh.quads[loopstart + 3]; + mloops[loopstart].v = quads[i][0]; + mloops[loopstart + 1].v = quads[i][3]; + mloops[loopstart + 2].v = quads[i][2]; + mloops[loopstart + 3].v = quads[i][1]; } - const int triangle_poly_start = output_mesh.totquads; - const int triangle_loop_start = output_mesh.totquads * 4; - for (const int i : IndexRange(output_mesh.tottriangles)) { - MPoly &poly = mesh->mpoly[triangle_poly_start + i]; + const int triangle_loop_start = quads.size() * 4; + for (const int i : IndexRange(tris.size())) { + MPoly &poly = mpolys[quads.size() + i]; const int loopstart = triangle_loop_start + i * 3; poly.loopstart = loopstart; poly.totloop = 3; - mesh->mloop[loopstart].v = output_mesh.triangles[i * 3 + 2]; - mesh->mloop[loopstart + 1].v = output_mesh.triangles[i * 3 + 1]; - mesh->mloop[loopstart + 2].v = output_mesh.triangles[i * 3]; + mloops[loopstart].v = tris[i][2]; + mloops[loopstart + 1].v = tris[i][1]; + mloops[loopstart + 2].v = tris[i][0]; } BKE_mesh_calc_edges(mesh, false, false); BKE_mesh_calc_normals(mesh); - MEM_freeN(output_mesh.quads); - MEM_freeN(output_mesh.vertices); - - if (output_mesh.tottriangles > 0) { - MEM_freeN(output_mesh.triangles); - } - return mesh; } #endif @@ -288,14 +282,8 @@ Mesh *BKE_mesh_remesh_voxel(const Mesh *mesh, const float isovalue) { #ifdef WITH_OPENVDB - struct OpenVDBTransform *xform = OpenVDBTransform_create(); - OpenVDBTransform_create_linear_transform(xform, (double)voxel_size); - struct OpenVDBLevelSet *level_set = remesh_voxel_level_set_create(mesh, xform); - Mesh *new_mesh = remesh_voxel_volume_to_mesh( - level_set, (double)isovalue, (double)adaptivity, false); - OpenVDBLevelSet_free(level_set); - OpenVDBTransform_free(xform); - return new_mesh; + openvdb::FloatGrid::Ptr level_set = remesh_voxel_level_set_create(mesh, voxel_size); + return remesh_voxel_volume_to_mesh(level_set, isovalue, adaptivity, false); #else UNUSED_VARS(mesh, voxel_size, adaptivity, isovalue); return nullptr; From a2203a27d9298f7e51948e825e6aea992b3ac5b2 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Mon, 2 Aug 2021 18:43:16 +0200 Subject: [PATCH 22/24] Fix T90356: Frame selected includes active strip Don't include active strip in this operator. This was confusing due to name of operator and inconsistent with other editors. --- source/blender/editors/space_sequencer/sequencer_view.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c index 337ac2e0009..c5385e24d2c 100644 --- a/source/blender/editors/space_sequencer/sequencer_view.c +++ b/source/blender/editors/space_sequencer/sequencer_view.c @@ -275,7 +275,6 @@ static int sequencer_view_selected_exec(bContext *C, wmOperator *op) View2D *v2d = UI_view2d_fromcontext(C); ARegion *region = CTX_wm_region(C); Editing *ed = SEQ_editing_get(scene, false); - Sequence *last_seq = SEQ_select_active_get(scene); Sequence *seq; rctf cur_new = v2d->cur; @@ -293,7 +292,7 @@ static int sequencer_view_selected_exec(bContext *C, wmOperator *op) } for (seq = ed->seqbasep->first; seq; seq = seq->next) { - if ((seq->flag & SELECT) || (seq == last_seq)) { + if ((seq->flag & SELECT)) { xmin = min_ii(xmin, seq->startdisp); xmax = max_ii(xmax, seq->enddisp); From 8b93265c19feeed2b758046359ac102a1f21278a Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 2 Aug 2021 13:47:32 -0400 Subject: [PATCH 23/24] Mesh: Tag normals dirty instead of calculating Because mesh vertex and face normals are just derived data, they can be calculated lazily instead of eagerly. Often normal calculation is a relatively expensive task, and the calculation is often redundant if the mesh is deformed afterwards anyway. Instead, normals should be calculated only when they are needed. This commit moves in that direction by adding a new function to tag a mesh's normals dirty and replacing normal calculation with it in some places. Differential Revision: https://developer.blender.org/D12107 --- source/blender/blenkernel/BKE_mesh.h | 1 + source/blender/blenkernel/intern/mesh_normals.cc | 6 ++++++ source/blender/blenkernel/intern/mesh_remesh_voxel.cc | 2 +- source/blender/blenkernel/intern/volume_to_mesh.cc | 2 +- source/blender/editors/object/object_remesh.cc | 3 ++- source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc | 2 +- .../nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc | 6 ++---- .../blender/nodes/geometry/nodes/node_geo_mesh_subdivide.cc | 2 +- .../nodes/geometry/nodes/node_geo_subdivision_surface.cc | 2 +- 9 files changed, 16 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index e3be9cd8ef8..ef1384c804b 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -280,6 +280,7 @@ void BKE_mesh_recalc_looptri_with_normals(const struct MLoop *mloop, /* *** mesh_normals.cc *** */ +void BKE_mesh_normals_tag_dirty(struct Mesh *mesh); void BKE_mesh_calc_normals_mapping_simple(struct Mesh *me); void BKE_mesh_calc_normals_mapping(struct MVert *mverts, int numVerts, diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index f496d6eada1..8740baa5aef 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -63,6 +63,12 @@ static CLG_LogRef LOG = {"bke.mesh_normals"}; /** \name Mesh Normal Calculation * \{ */ +void BKE_mesh_normals_tag_dirty(Mesh *mesh) +{ + mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL; + mesh->runtime.cd_dirty_poly |= CD_MASK_NORMAL; +} + /** * Call when there are no polygons. */ diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc index 4484dd5bf09..63b0403dcea 100644 --- a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc +++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc @@ -270,7 +270,7 @@ static Mesh *remesh_voxel_volume_to_mesh(const openvdb::FloatGrid::Ptr level_set } BKE_mesh_calc_edges(mesh, false, false); - BKE_mesh_calc_normals(mesh); + BKE_mesh_normals_tag_dirty(mesh); return mesh; } diff --git a/source/blender/blenkernel/intern/volume_to_mesh.cc b/source/blender/blenkernel/intern/volume_to_mesh.cc index 7ab67516242..e9d6eea4614 100644 --- a/source/blender/blenkernel/intern/volume_to_mesh.cc +++ b/source/blender/blenkernel/intern/volume_to_mesh.cc @@ -159,7 +159,7 @@ static Mesh *new_mesh_from_openvdb_data(Span verts, } BKE_mesh_calc_edges(mesh, false, false); - BKE_mesh_calc_normals(mesh); + BKE_mesh_normals_tag_dirty(mesh); return mesh; } diff --git a/source/blender/editors/object/object_remesh.cc b/source/blender/editors/object/object_remesh.cc index 82dbc9aaf38..d56cb3c7548 100644 --- a/source/blender/editors/object/object_remesh.cc +++ b/source/blender/editors/object/object_remesh.cc @@ -166,9 +166,10 @@ static int voxel_remesh_exec(bContext *C, wmOperator *op) Mesh *mesh_fixed_poles = BKE_mesh_remesh_voxel_fix_poles(new_mesh); BKE_id_free(nullptr, new_mesh); new_mesh = mesh_fixed_poles; - BKE_mesh_calc_normals(new_mesh); } + BKE_mesh_calc_normals(new_mesh); + if (mesh->flag & ME_REMESH_REPROJECT_VOLUME || mesh->flag & ME_REMESH_REPROJECT_PAINT_MASK || mesh->flag & ME_REMESH_REPROJECT_SCULPT_FACE_SETS) { BKE_mesh_runtime_clear_geometry(mesh); diff --git a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc index 4286db52115..91d569282c3 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc @@ -150,7 +150,7 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span coords) plConvexHullDelete(hull); - BKE_mesh_calc_normals(result); + BKE_mesh_normals_tag_dirty(result); return result; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc index 925ed0f8da8..d46ea2d2050 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc @@ -299,7 +299,7 @@ Mesh *create_cylinder_or_cone_mesh(const float radius_top, mesh->medge[0].v1 = 0; mesh->medge[0].v2 = 1; mesh->medge[0].flag |= ME_LOOSEEDGE; - BKE_mesh_calc_normals(mesh); + BKE_mesh_normals_tag_dirty(mesh); return mesh; } @@ -534,12 +534,10 @@ Mesh *create_cylinder_or_cone_mesh(const float radius_top, } } - BKE_mesh_calc_normals(mesh); + BKE_mesh_normals_tag_dirty(mesh); calculate_uvs(mesh, top_is_point, bottom_is_point, verts_num, fill_type); - BLI_assert(BKE_mesh_is_valid(mesh)); - return mesh; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_subdivide.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_subdivide.cc index 245d7800621..165da8ec9f2 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_subdivide.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_subdivide.cc @@ -88,7 +88,7 @@ static void geo_node_mesh_subdivide_exec(GeoNodeExecParams params) } Mesh *mesh_out = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh_in); - BKE_mesh_calc_normals(mesh_out); + BKE_mesh_normals_tag_dirty(mesh_out); MeshComponent &mesh_component = geometry_set.get_component_for_write(); mesh_component.replace(mesh_out); diff --git a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc index f0f032ed8f4..a2c10af9c4d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc @@ -93,7 +93,7 @@ static void geo_node_subdivision_surface_exec(GeoNodeExecParams params) } Mesh *mesh_out = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh_in); - BKE_mesh_calc_normals(mesh_out); + BKE_mesh_normals_tag_dirty(mesh_out); MeshComponent &mesh_component = geometry_set.get_component_for_write(); mesh_component.replace(mesh_out); From 4f6f445120bb534a36e2ee5ddd89be6793a4c35d Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 2 Aug 2021 14:21:19 -0400 Subject: [PATCH 24/24] Cleanup: Make spline settings copy function public It will be useful in the spline type conversion node. Theoretically it could become protected again if that conversion moves out of a node, which might be a nice improvement after an initial version. --- source/blender/blenkernel/BKE_spline.hh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/blender/blenkernel/BKE_spline.hh b/source/blender/blenkernel/BKE_spline.hh index 53485ecbd6b..fc145f1ddf1 100644 --- a/source/blender/blenkernel/BKE_spline.hh +++ b/source/blender/blenkernel/BKE_spline.hh @@ -109,6 +109,7 @@ class Spline { SplinePtr copy() const; SplinePtr copy_only_settings() const; SplinePtr copy_without_attributes() const; + static void copy_base_settings(const Spline &src, Spline &dst); Spline::Type type() const; @@ -209,8 +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; - - static void copy_base_settings(const Spline &src, Spline &dst); }; /**