Merge branch 'master' into sculpt-dev

This commit is contained in:
Pablo Dobarro 2021-07-25 18:20:27 +02:00
commit 89897140cf
266 changed files with 4285 additions and 2288 deletions

View File

@ -217,7 +217,7 @@ if(UNIX AND NOT (APPLE OR HAIKU))
option(WITH_GHOST_X11 "Enable building Blender against X11 for windowing" ON)
mark_as_advanced(WITH_GHOST_X11)
option(WITH_GHOST_WAYLAND "Enable building Blender against Wayland for windowing (under development)" OFF)
option(WITH_GHOST_WAYLAND "Enable building Blender against Wayland for windowing" ON)
mark_as_advanced(WITH_GHOST_WAYLAND)
endif()

View File

@ -82,7 +82,7 @@ def create_nb_project_main():
make_exe = cmake_cache_var("CMAKE_MAKE_PROGRAM")
make_exe_basename = os.path.basename(make_exe)
# --------------- NB specific
# --------------- NetBeans specific.
defines = [("%s=%s" % cdef) if cdef[1] else cdef[0] for cdef in defines]
defines += [cdef.replace("#define", "").strip() for cdef in cmake_compiler_defines()]

View File

@ -122,7 +122,7 @@ is a full-featured 3D application. It supports the entirety of the 3D pipeline -
'''modeling, rigging, animation, simulation, rendering, compositing, motion tracking, and video editing.
Use Blender to create 3D images and animations, films and commercials, content for games, '''
r'''architectural and industrial visualizatons, and scientific visualizations.
r'''architectural and industrial visualizations, and scientific visualizations.
https://www.blender.org''')

View File

@ -1047,6 +1047,7 @@ context_type_map = {
"annotation_data": ("GreasePencil", False),
"annotation_data_owner": ("ID", False),
"armature": ("Armature", False),
"asset_library": ("AssetLibraryReference", False),
"bone": ("Bone", False),
"brush": ("Brush", False),
"camera": ("Camera", False),
@ -1113,6 +1114,7 @@ context_type_map = {
"texture_slot": ("MaterialTextureSlot", False),
"texture_user": ("ID", False),
"texture_user_property": ("Property", False),
"ui_list": ("UIList", False),
"vertex_paint_object": ("Object", False),
"view_layer": ("ViewLayer", False),
"visible_bones": ("EditBone", True),

View File

@ -1136,7 +1136,7 @@ class CYCLES_PT_context_material(CyclesButtonsPanel, Panel):
col = row.column(align=True)
col.operator("object.material_slot_add", icon='ADD', text="")
col.operator("object.material_slot_remove", icon='REMOVE', text="")
col.separator()
col.menu("MATERIAL_MT_context_menu", icon='DOWNARROW_HLT', text="")
if is_sortable:
@ -1151,16 +1151,15 @@ class CYCLES_PT_context_material(CyclesButtonsPanel, Panel):
row.operator("object.material_slot_select", text="Select")
row.operator("object.material_slot_deselect", text="Deselect")
split = layout.split(factor=0.65)
row = layout.row()
if ob:
split.template_ID(ob, "active_material", new="material.new")
row = split.row()
row.template_ID(ob, "active_material", new="material.new")
if slot:
row.prop(slot, "link", text="")
else:
row.label()
icon_link = 'MESH_DATA' if slot.link == 'DATA' else 'OBJECT_DATA'
row.prop(slot, "link", text="", icon=icon_link, icon_only=True)
elif mat:
split.template_ID(space, "pin_id")
split.separator()

View File

@ -993,7 +993,7 @@ void OSLCompiler::parameter_array(const char *name, const float f[], int arrayle
void OSLCompiler::parameter_color_array(const char *name, const array<float3> &f)
{
/* NB: cycles float3 type is actually 4 floats! need to use an explicit array */
/* NOTE: cycles float3 type is actually 4 floats! need to use an explicit array. */
array<float[3]> table(f.size());
for (int i = 0; i < f.size(); ++i) {

View File

@ -628,7 +628,7 @@ extern void GHOST_ScreenToClient(
GHOST_WindowHandle windowhandle, int32_t inX, int32_t inY, int32_t *outX, int32_t *outY);
/**
* Converts a point in screen coordinates to client rectangle coordinates
* Converts a point in client rectangle coordinates to screen coordinates.
* \param windowhandle: The handle to the window.
* \param inX: The x-coordinate in the client rectangle.
* \param inY: The y-coordinate in the client rectangle.

View File

@ -133,7 +133,7 @@ class GHOST_IWindow {
virtual void screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const = 0;
/**
* Converts a point in screen coordinates to client rectangle coordinates
* Converts a point in client rectangle coordinates to screen coordinates.
* \param inX: The x-coordinate in the client rectangle.
* \param inY: The y-coordinate in the client rectangle.
* \param outX: The x-coordinate on the screen.

View File

@ -683,6 +683,10 @@ typedef struct GHOST_XrDrawViewInfo {
/** Set if the buffer should be submitted with a SRGB transfer applied. */
char expects_srgb_buffer;
/** The view that this info represents. Not necessarily the "eye index" (e.g. for quad view
* systems, etc). */
char view_idx;
} GHOST_XrDrawViewInfo;
typedef struct GHOST_XrError {

View File

@ -57,9 +57,17 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
/* Special case, try Wayland, fall back to X11. */
try {
m_system = new GHOST_SystemWayland();
if (!std::getenv("BLENDER_WAYLAND")) {
printf("Connected to a Wayland compositor but Wayland is disabled at "\
"runtime.\nSet environment variable 'BLENDER_WAYLAND' (e.g. "\
"BLENDER_WAYLAND= blender) to use Wayland.\n");
throw std::runtime_error(std::string());
}
}
catch (const std::runtime_error &) {
/* fallback to X11. */
delete m_system;
m_system = nullptr;
}
if (!m_system) {
m_system = new GHOST_SystemX11();

View File

@ -114,7 +114,7 @@ class GHOST_NDOFManager {
virtual bool available() = 0;
/**
* Rach platform's device detection should call this
* Each platform's device detection should call this
* use standard USB/HID identifiers.
*/
bool setDevice(unsigned short vendor_id, unsigned short product_id);

View File

@ -360,8 +360,8 @@ class GHOST_SystemWin32 : public GHOST_System {
static GHOST_EventKey *processKeyEvent(GHOST_WindowWin32 *window, RAWINPUT const &raw);
/**
* Process special keys (VK_OEM_*), to see if current key layout
* gives us anything special, like ! on french AZERTY.
* Process special keys `VK_OEM_*`, to see if current key layout
* gives us anything special, like `!` on French AZERTY.
* \param vKey: The virtual key from #hardKey.
* \param scanCode: The ScanCode of pressed key (similar to PS/2 Set 1).
*/

View File

@ -157,7 +157,7 @@ class GHOST_WindowCocoa : public GHOST_Window {
void screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const;
/**
* Converts a point in screen coordinates to client rectangle coordinates
* Converts a point in client rectangle coordinates to screen coordinates.
* \param inX: The x-coordinate in the client rectangle.
* \param inY: The y-coordinate in the client rectangle.
* \param outX: The x-coordinate on the screen.
@ -166,7 +166,7 @@ class GHOST_WindowCocoa : public GHOST_Window {
void clientToScreen(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const;
/**
* Converts a point in screen coordinates to client rectangle coordinates
* Converts a point in client rectangle coordinates to screen coordinates.
* but without the y coordinate conversion needed for ghost compatibility.
* \param inX: The x-coordinate in the client rectangle.
* \param inY: The y-coordinate in the client rectangle.
@ -178,10 +178,10 @@ class GHOST_WindowCocoa : public GHOST_Window {
/**
* Converts a point in screen coordinates to client rectangle coordinates,
* but without the y coordinate conversion needed for ghost compatibility.
* \param inX: The x-coordinate in the client rectangle.
* \param inY: The y-coordinate in the client rectangle.
* \param outX: The x-coordinate on the screen.
* \param outY: The y-coordinate on the screen.
* \param inX: The x-coordinate on the screen.
* \param inY: The y-coordinate on the screen.
* \param outX: The x-coordinate in the client rectangle.
* \param outY: The y-coordinate in the client rectangle.
*/
void screenToClientIntern(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const;

View File

@ -183,7 +183,7 @@ class GHOST_WindowWin32 : public GHOST_Window {
void screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const;
/**
* Converts a point in screen coordinates to client rectangle coordinates
* Converts a point in client rectangle coordinates to screen coordinates.
* \param inX: The x-coordinate in the client rectangle.
* \param inY: The y-coordinate in the client rectangle.
* \param outX: The x-coordinate on the screen.

View File

@ -120,7 +120,7 @@ static void create_reference_spaces(OpenXRSessionData &oxr, const GHOST_XrPose &
XrReferenceSpaceCreateInfo create_info = {XR_TYPE_REFERENCE_SPACE_CREATE_INFO};
create_info.poseInReferenceSpace.orientation.w = 1.0f;
create_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL;
create_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_STAGE;
#if 0
/* TODO
*
@ -144,8 +144,47 @@ static void create_reference_spaces(OpenXRSessionData &oxr, const GHOST_XrPose &
(void)base_pose;
#endif
CHECK_XR(xrCreateReferenceSpace(oxr.session, &create_info, &oxr.reference_space),
"Failed to create reference space.");
XrResult result = xrCreateReferenceSpace(oxr.session, &create_info, &oxr.reference_space);
if (XR_FAILED(result)) {
/* One of the rare cases where we don't want to immediately throw an exception on failure,
* since runtimes are not required to support the stage reference space. Although we need the
* stage reference space for absolute tracking, if the runtime doesn't support it then just
* fallback to the local space. */
if (result == XR_ERROR_REFERENCE_SPACE_UNSUPPORTED) {
printf(
"Warning: XR runtime does not support stage reference space, disabling absolute "
"tracking.\n");
create_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL;
CHECK_XR(xrCreateReferenceSpace(oxr.session, &create_info, &oxr.reference_space),
"Failed to create local reference space.");
}
else {
throw GHOST_XrException("Failed to create stage reference space.", result);
}
}
else {
/* Check if tracking bounds are valid. Tracking bounds may be invalid if the user did not
* define a tracking space via the XR runtime. */
XrExtent2Df extents;
CHECK_XR(xrGetReferenceSpaceBoundsRect(oxr.session, XR_REFERENCE_SPACE_TYPE_STAGE, &extents),
"Failed to get stage reference space bounds.");
if (extents.width == 0.0f || extents.height == 0.0f) {
printf(
"Warning: Invalid stage reference space bounds, disabling absolute tracking. To enable "
"absolute tracking, please define a tracking space via the XR runtime.\n");
/* Fallback to local space. */
if (oxr.reference_space != XR_NULL_HANDLE) {
CHECK_XR(xrDestroySpace(oxr.reference_space), "Failed to destroy stage reference space.");
}
create_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL;
CHECK_XR(xrCreateReferenceSpace(oxr.session, &create_info, &oxr.reference_space),
"Failed to create local reference space.");
}
}
create_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_VIEW;
CHECK_XR(xrCreateReferenceSpace(oxr.session, &create_info, &oxr.view_space),
@ -370,6 +409,7 @@ void GHOST_XrSession::drawView(GHOST_XrSwapchain &swapchain,
XrCompositionLayerProjectionView &r_proj_layer_view,
XrSpaceLocation &view_location,
XrView &view,
uint32_t view_idx,
void *draw_customdata)
{
XrSwapchainImageBaseHeader *swapchain_image = swapchain.acquireDrawableSwapchainImage();
@ -380,6 +420,8 @@ void GHOST_XrSession::drawView(GHOST_XrSwapchain &swapchain,
r_proj_layer_view.fov = view.fov;
swapchain.updateCompositionLayerProjectViewSubImage(r_proj_layer_view.subImage);
assert(view_idx < 256);
draw_view_info.view_idx = (char)view_idx;
draw_view_info.expects_srgb_buffer = swapchain.isBufferSRGB();
draw_view_info.ofsx = r_proj_layer_view.subImage.imageRect.offset.x;
draw_view_info.ofsy = r_proj_layer_view.subImage.imageRect.offset.y;
@ -429,6 +471,7 @@ XrCompositionLayerProjection GHOST_XrSession::drawLayer(
r_proj_layer_views[view_idx],
view_location,
m_oxr->views[view_idx],
view_idx,
draw_customdata);
}

View File

@ -117,6 +117,7 @@ class GHOST_XrSession {
XrCompositionLayerProjectionView &r_proj_layer_view,
XrSpaceLocation &view_location,
XrView &view,
uint32_t view_idx,
void *draw_customdata);
void beginFrameDrawing();
void endFrameDrawing(std::vector<XrCompositionLayerBaseHeader *> &layers);

View File

@ -217,39 +217,39 @@ if(WITH_LIBMV)
if(WITH_GTESTS)
include(GTestTesting)
blender_add_lib(libmv_test_dataset "./libmv/multiview/test_data_sets.cc" "" "" "")
blender_add_lib(libmv_test_dataset "./libmv/multiview/test_data_sets.cc" "${INC}" "${INC_SYS}" "")
BLENDER_SRC_GTEST("libmv_predict_tracks" "./libmv/autotrack/predict_tracks_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_tracks" "./libmv/autotrack/tracks_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_scoped_ptr" "./libmv/base/scoped_ptr_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_vector" "./libmv/base/vector_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_array_nd" "./libmv/image/array_nd_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_convolve" "./libmv/image/convolve_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_image" "./libmv/image/image_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_sample" "./libmv/image/sample_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_tuple" "./libmv/image/tuple_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_euclidean_resection" "./libmv/multiview/euclidean_resection_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_fundamental" "./libmv/multiview/fundamental_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_homography" "./libmv/multiview/homography_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_nviewtriangulation" "./libmv/multiview/nviewtriangulation_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_panography" "./libmv/multiview/panography_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_projection" "./libmv/multiview/projection_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_resection" "./libmv/multiview/resection_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_triangulation" "./libmv/multiview/triangulation_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_dogleg" "./libmv/numeric/dogleg_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_function_derivative" "./libmv/numeric/function_derivative_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_levenberg_marquardt" "./libmv/numeric/levenberg_marquardt_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_numeric" "./libmv/numeric/numeric_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_poly" "./libmv/numeric/poly_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_camera_intrinsics" "./libmv/simple_pipeline/camera_intrinsics_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_detect" "./libmv/simple_pipeline/detect_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_intersect" "./libmv/simple_pipeline/intersect_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_keyframe_selection" "./libmv/simple_pipeline/keyframe_selection_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_modal_solver" "./libmv/simple_pipeline/modal_solver_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_resect" "./libmv/simple_pipeline/resect_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_brute_region_tracker" "./libmv/tracking/brute_region_tracker_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_klt_region_tracker" "./libmv/tracking/klt_region_tracker_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_pyramid_region_tracker" "./libmv/tracking/pyramid_region_tracker_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_predict_tracks" "./libmv/autotrack/predict_tracks_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_tracks" "./libmv/autotrack/tracks_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_scoped_ptr" "./libmv/base/scoped_ptr_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_vector" "./libmv/base/vector_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_array_nd" "./libmv/image/array_nd_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_convolve" "./libmv/image/convolve_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_image" "./libmv/image/image_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_sample" "./libmv/image/sample_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_tuple" "./libmv/image/tuple_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_euclidean_resection" "./libmv/multiview/euclidean_resection_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_fundamental" "./libmv/multiview/fundamental_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_homography" "./libmv/multiview/homography_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_nviewtriangulation" "./libmv/multiview/nviewtriangulation_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_panography" "./libmv/multiview/panography_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_projection" "./libmv/multiview/projection_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_resection" "./libmv/multiview/resection_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_triangulation" "./libmv/multiview/triangulation_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_dogleg" "./libmv/numeric/dogleg_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_function_derivative" "./libmv/numeric/function_derivative_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_levenberg_marquardt" "./libmv/numeric/levenberg_marquardt_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_numeric" "./libmv/numeric/numeric_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_poly" "./libmv/numeric/poly_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_camera_intrinsics" "./libmv/simple_pipeline/camera_intrinsics_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_detect" "./libmv/simple_pipeline/detect_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_intersect" "./libmv/simple_pipeline/intersect_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_keyframe_selection" "./libmv/simple_pipeline/keyframe_selection_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_modal_solver" "./libmv/simple_pipeline/modal_solver_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_resect" "./libmv/simple_pipeline/resect_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_brute_region_tracker" "./libmv/tracking/brute_region_tracker_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_klt_region_tracker" "./libmv/tracking/klt_region_tracker_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
blender_add_test_executable("libmv_pyramid_region_tracker" "./libmv/tracking/pyramid_region_tracker_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
endif()
else()
list(APPEND SRC

View File

@ -62,8 +62,8 @@ template<typename _Tp> struct MEM_Allocator {
return &__x;
}
// NB: __n is permitted to be 0. The C++ standard says nothing
// about what the return value is when __n == 0.
/* NOTE: `__n` is permitted to be 0.
* The C++ standard says nothing about what the return value is when `__n == 0`. */
_Tp *allocate(size_type __n, const void * = 0)
{
_Tp *__ret = NULL;

View File

@ -129,5 +129,5 @@ if(WITH_GTESTS AND WITH_OPENSUBDIV)
add_definitions(${GLOG_DEFINES})
add_definitions(-DBLENDER_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
BLENDER_SRC_GTEST(opensubdiv_mesh_topology_test "internal/topology/mesh_topology_test.cc" "${LIB};bf_intern_opensubdiv")
blender_add_test_executable(opensubdiv_mesh_topology_test "internal/topology/mesh_topology_test.cc" "${INC}" "${INC_SYS}" "${LIB};bf_intern_opensubdiv")
endif()

View File

@ -113,7 +113,7 @@ const UserDef U_default = {
.gp_eraser = 25,
.gp_settings = 0,
/** Initialized by: #BKE_studiolight_default . */
/** Initialized by: #BKE_studiolight_default. */
.light_param = {{0}},
.light_ambient = {0, 0, 0},

View File

@ -71,7 +71,7 @@ def rtl_process_po(args, settings):
po.write(kind="PO", dest=args.dst)
def language_menu(_args, settings):
def language_menu(args, settings):
# 'DEFAULT' and en_US are always valid, fully-translated "languages"!
stats = {"DEFAULT": 1.0, "en_US": 1.0}

View File

@ -77,7 +77,7 @@ class NodeItem:
else:
return bpy.app.translations.contexts.default
# NB: is a staticmethod because called with an explicit self argument
# NOTE: is a staticmethod because called with an explicit self argument
# NodeItemCustom sets this as a variable attribute in __init__
@staticmethod
def draw(self, layout, _context):

View File

@ -60,17 +60,22 @@ class CopyRigidbodySettings(Operator):
def execute(self, context):
obj_act = context.object
view_layer = context.view_layer
# deselect all but mesh objects
# Deselect all non mesh objects and objects that
# already have a rigid body attached.
rb_objects = []
for o in context.selected_objects:
if o.type != 'MESH':
if o.type != 'MESH' or o.rigid_body is not None:
o.select_set(False)
elif o.rigid_body is None:
# Add rigidbody to object!
view_layer.objects.active = o
bpy.ops.rigidbody.object_add()
view_layer.objects.active = obj_act
if o.rigid_body is not None:
rb_objects.append(o)
bpy.ops.rigidbody.objects_add()
# Ensure that the rigid body objects
# we've de-selected are selected again.
for o in rb_objects:
o.select_set(True)
objects = context.selected_objects
if objects:

View File

@ -1156,14 +1156,19 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
flow.prop(strip, "use_only_boost")
elif strip_type == 'SPEED':
layout.prop(strip, "use_default_fade", text="Stretch to Input Strip Length")
if not strip.use_default_fade:
layout.prop(strip, "use_as_speed")
if strip.use_as_speed:
layout.prop(strip, "speed_factor")
else:
layout.prop(strip, "speed_factor", text="Frame Number")
layout.prop(strip, "use_scale_to_length")
col = layout.column(align=True)
col.prop(strip, "speed_control", text="Speed Control")
if strip.speed_control == "MULTIPLY":
col.prop(strip, "speed_factor", text=" ")
elif strip.speed_control == "LENGTH":
col.prop(strip, "speed_length", text=" ")
elif strip.speed_control == "FRAME_NUMBER":
col.prop(strip, "speed_frame_number", text=" ")
row = layout.row(align=True)
row.enabled = strip.speed_control != "STRETCH"
row = layout.row(align=True, heading="Interpolation")
row.prop(strip, "use_frame_interpolate", text="")
elif strip_type == 'TRANSFORM':
col = layout.column()
@ -1233,11 +1238,7 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
layout.prop(strip, "wrap_width", text="Wrap Width")
col = layout.column(align=True)
if strip_type == 'SPEED':
col.prop(strip, "multiply_speed")
col.prop(strip, "use_frame_interpolate")
elif strip_type in {'CROSS', 'GAMMA_CROSS', 'WIPE', 'ALPHA_OVER', 'ALPHA_UNDER', 'OVER_DROP'}:
if strip_type in {'CROSS', 'GAMMA_CROSS', 'WIPE', 'ALPHA_OVER', 'ALPHA_UNDER', 'OVER_DROP'}:
col.prop(strip, "use_default_fade", text="Default Fade")
if not strip.use_default_fade:
col.prop(strip, "effect_fader", text="Effect Fader")

View File

@ -510,6 +510,7 @@ geometry_node_categories = [
NodeItem("GeometryNodeCurveTrim"),
NodeItem("GeometryNodeCurveLength"),
NodeItem("GeometryNodeCurveReverse"),
NodeItem("GeometryNodeCurveSetHandles"),
]),
GeometryNodeCategory("GEO_PRIMITIVES_CURVE", "Curve Primitives", items=[
NodeItem("GeometryNodeCurvePrimitiveLine"),

View File

@ -147,7 +147,7 @@ node_categories = [
MyNodeCategory('OTHERNODES', "Other Nodes", items=[
# the node item can have additional settings,
# which are applied to new nodes
# NB: settings values are stored as string expressions,
# NOTE: settings values are stored as string expressions,
# for this reason they should be converted to strings using repr()
NodeItem("CustomNodeType", label="Node A", settings={
"my_string_prop": repr("Lorem ipsum dolor sit amet"),

View File

@ -39,7 +39,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 12
#define BLENDER_FILE_SUBVERSION 13
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file

View File

@ -501,7 +501,7 @@ enum {
CD_FAKE = 1 << 8,
/* Vertices. */
CD_FAKE_MDEFORMVERT = CD_FAKE | CD_MDEFORMVERT, /* *sigh* due to how vgroups are stored :( . */
CD_FAKE_MDEFORMVERT = CD_FAKE | CD_MDEFORMVERT, /* *sigh* due to how vgroups are stored :(. */
CD_FAKE_SHAPEKEY = CD_FAKE |
CD_SHAPEKEY, /* Not available as real CD layer in non-bmesh context. */

View File

@ -399,6 +399,12 @@ void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr,
const char data_type);
void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr);
void BKE_lnor_spacearr_free(MLoopNorSpaceArray *lnors_spacearr);
void BKE_lnor_spacearr_tls_init(MLoopNorSpaceArray *lnors_spacearr,
MLoopNorSpaceArray *lnors_spacearr_tls);
void BKE_lnor_spacearr_tls_join(MLoopNorSpaceArray *lnors_spacearr,
MLoopNorSpaceArray *lnors_spacearr_tls);
MLoopNorSpace *BKE_lnor_space_create(MLoopNorSpaceArray *lnors_spacearr);
void BKE_lnor_space_define(MLoopNorSpace *lnor_space,
const float lnor[3],

View File

@ -41,6 +41,7 @@ void BKE_mesh_foreach_mapped_vert(struct Mesh *mesh,
MeshForeachFlag flag);
void BKE_mesh_foreach_mapped_edge(
struct Mesh *mesh,
int tot_edges,
void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
void *userData);
void BKE_mesh_foreach_mapped_loop(struct Mesh *mesh,

View File

@ -1465,6 +1465,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
#define GEO_NODE_CURVE_ENDPOINTS 1069
#define GEO_NODE_CURVE_PRIMITIVE_QUADRILATERAL 1070
#define GEO_NODE_CURVE_TRIM 1071
#define GEO_NODE_CURVE_SET_HANDLES 1072
/** \} */

View File

@ -306,6 +306,7 @@ class BezierSpline final : public Spline {
blender::MutableSpan<HandleType> handle_types_right();
blender::Span<blender::float3> handle_positions_right() const;
blender::MutableSpan<blender::float3> handle_positions_right();
void ensure_auto_handles() const;
void translate(const blender::float3 &translation) override;
void transform(const blender::float4x4 &matrix) override;
@ -353,8 +354,6 @@ class BezierSpline final : public Spline {
void correct_end_tangents() const final;
void copy_settings(Spline &dst) const final;
void copy_data(Spline &dst) const final;
void ensure_auto_handles() const;
};
/**
@ -544,6 +543,7 @@ struct CurveEval {
blender::Span<SplinePtr> splines() const;
blender::MutableSpan<SplinePtr> splines();
bool has_spline_with_type(const Spline::Type type) const;
void resize(const int size);
void add_spline(SplinePtr spline);

View File

@ -1947,7 +1947,7 @@ static void nlaevalchan_blendOrcombine(NlaEvalChannelSnapshot *lower_necs,
return;
}
default:
BLI_assert("Mix mode should've been handled");
BLI_assert_msg(0, "Mix mode should've been handled");
}
return;
}
@ -1960,7 +1960,7 @@ static void nlaevalchan_blendOrcombine(NlaEvalChannelSnapshot *lower_necs,
return;
}
default:
BLI_assert("Blend mode should've been handled");
BLI_assert_msg(0, "Blend mode should've been handled");
}
}
@ -2110,7 +2110,7 @@ static void nlaevalchan_blendOrcombine_get_inverted_upper_evalchan(
return;
}
default:
BLI_assert("Mix mode should've been handled");
BLI_assert_msg(0, "Mix mode should've been handled");
}
return;
}
@ -2123,7 +2123,7 @@ static void nlaevalchan_blendOrcombine_get_inverted_upper_evalchan(
return;
}
default:
BLI_assert("Blend mode should've been handled");
BLI_assert_msg(0, "Blend mode should've been handled");
}
}

View File

@ -171,10 +171,14 @@ class BKE_armature_find_selected_bones_test : public testing::Test {
strcpy(bone2.name, "bone2");
strcpy(bone3.name, "bone3");
arm.bonebase = {NULL, NULL};
BLI_addtail(&arm.bonebase, &bone1);
BLI_addtail(&arm.bonebase, &bone2);
BLI_addtail(&arm.bonebase, &bone3);
arm.bonebase = {nullptr, nullptr};
bone1.childbase = {nullptr, nullptr};
bone2.childbase = {nullptr, nullptr};
bone3.childbase = {nullptr, nullptr};
BLI_addtail(&arm.bonebase, &bone1); // bone1 is root bone
BLI_addtail(&arm.bonebase, &bone2); // bone2 is root bone
BLI_addtail(&bone2.childbase, &bone3); // bone3 has bone2 as parent
// Make sure the armature & its bones are visible, to make them selectable.
arm.layer = bone1.layer = bone2.layer = bone3.layer = 1;

View File

@ -39,6 +39,7 @@
#include "BKE_attribute.h"
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_hair.h"
#include "BKE_pointcloud.h"
#include "BKE_report.h"
@ -63,14 +64,28 @@ static void get_domains(ID *id, DomainInfo info[ATTR_DOMAIN_NUM])
}
case ID_ME: {
Mesh *mesh = (Mesh *)id;
info[ATTR_DOMAIN_POINT].customdata = &mesh->vdata;
info[ATTR_DOMAIN_POINT].length = mesh->totvert;
info[ATTR_DOMAIN_EDGE].customdata = &mesh->edata;
info[ATTR_DOMAIN_EDGE].length = mesh->totedge;
info[ATTR_DOMAIN_CORNER].customdata = &mesh->ldata;
info[ATTR_DOMAIN_CORNER].length = mesh->totloop;
info[ATTR_DOMAIN_FACE].customdata = &mesh->pdata;
info[ATTR_DOMAIN_FACE].length = mesh->totpoly;
BMEditMesh *em = mesh->edit_mesh;
if (em != NULL) {
BMesh *bm = em->bm;
info[ATTR_DOMAIN_POINT].customdata = &bm->vdata;
info[ATTR_DOMAIN_POINT].length = bm->totvert;
info[ATTR_DOMAIN_EDGE].customdata = &bm->edata;
info[ATTR_DOMAIN_EDGE].length = bm->totedge;
info[ATTR_DOMAIN_CORNER].customdata = &bm->ldata;
info[ATTR_DOMAIN_CORNER].length = bm->totloop;
info[ATTR_DOMAIN_FACE].customdata = &bm->pdata;
info[ATTR_DOMAIN_FACE].length = bm->totface;
}
else {
info[ATTR_DOMAIN_POINT].customdata = &mesh->vdata;
info[ATTR_DOMAIN_POINT].length = mesh->totvert;
info[ATTR_DOMAIN_EDGE].customdata = &mesh->edata;
info[ATTR_DOMAIN_EDGE].length = mesh->totedge;
info[ATTR_DOMAIN_CORNER].customdata = &mesh->ldata;
info[ATTR_DOMAIN_CORNER].length = mesh->totloop;
info[ATTR_DOMAIN_FACE].customdata = &mesh->pdata;
info[ATTR_DOMAIN_FACE].length = mesh->totpoly;
}
break;
}
case ID_HA: {
@ -146,7 +161,24 @@ CustomDataLayer *BKE_id_attribute_new(
return NULL;
}
CustomData_add_layer_named(customdata, type, CD_DEFAULT, NULL, info[domain].length, name);
switch (GS(id->name)) {
case ID_ME: {
Mesh *me = (Mesh *)id;
BMEditMesh *em = me->edit_mesh;
if (em != NULL) {
BM_data_layer_add_named(em->bm, customdata, type, name);
}
else {
CustomData_add_layer_named(customdata, type, CD_DEFAULT, NULL, info[domain].length, name);
}
break;
}
default: {
CustomData_add_layer_named(customdata, type, CD_DEFAULT, NULL, info[domain].length, name);
break;
}
}
const int index = CustomData_get_named_layer_index(customdata, type, name);
return (index == -1) ? NULL : &(customdata->layers[index]);
}
@ -168,8 +200,26 @@ bool BKE_id_attribute_remove(ID *id, CustomDataLayer *layer, ReportList *reports
return false;
}
const int length = BKE_id_attribute_data_length(id, layer);
CustomData_free_layer(customdata, layer->type, length, index);
switch (GS(id->name)) {
case ID_ME: {
Mesh *me = (Mesh *)id;
BMEditMesh *em = me->edit_mesh;
if (em != NULL) {
BM_data_layer_free(em->bm, customdata, layer->type);
}
else {
const int length = BKE_id_attribute_data_length(id, layer);
CustomData_free_layer(customdata, layer->type, length, index);
}
break;
}
default: {
const int length = BKE_id_attribute_data_length(id, layer);
CustomData_free_layer(customdata, layer->type, length, index);
break;
}
}
return true;
}
@ -316,7 +366,7 @@ CustomData *BKE_id_attributes_iterator_next_domain(ID *id, CustomDataLayer *laye
for (AttributeDomain domain = 0; domain < ATTR_DOMAIN_NUM; domain++) {
CustomData *customdata = info[domain].customdata;
if (customdata && customdata->layers) {
if (customdata && customdata->layers && customdata->totlayer) {
if (customdata->layers == layers) {
use_next = true;
}

View File

@ -1072,7 +1072,7 @@ static BoidState *get_boid_state(BoidSettings *boids, ParticleData *pa)
return state;
}
#if 0 /* TODO */
#if 0 /* TODO */
static int boid_condition_is_true(BoidCondition *cond)
{
return 0;

View File

@ -48,6 +48,22 @@ blender::MutableSpan<SplinePtr> CurveEval::splines()
return splines_;
}
/**
* \return True if the curve contains a spline with the given type.
*
* \note If you are looping over all of the splines in the same scope anyway,
* it's better to avoid calling this function, in case there are many splines.
*/
bool CurveEval::has_spline_with_type(const Spline::Type type) const
{
for (const SplinePtr &spline : this->splines()) {
if (spline->type() == type) {
return true;
}
}
return false;
}
void CurveEval::resize(const int size)
{
splines_.resize(size);

View File

@ -306,7 +306,7 @@ const float (*BKE_editmesh_vert_coords_when_deformed(struct Depsgraph *depsgraph
}
else if ((em->mesh_eval_final != NULL) &&
(em->mesh_eval_final->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH)) {
/* If this is an edit-mesh type, leave NULL as we can use the vertex coords. . */
/* If this is an edit-mesh type, leave NULL as we can use the vertex coords. */
}
else {
/* Constructive modifiers have been used, we need to allocate coordinates. */

View File

@ -918,7 +918,7 @@ void BKE_fcurve_active_keyframe_set(FCurve *fcu, const BezTriple *active_bezt)
}
/* The active keyframe should always be selected. */
BLI_assert(BEZT_ISSEL_ANY(active_bezt) || !"active keyframe must be selected");
BLI_assert_msg(BEZT_ISSEL_ANY(active_bezt), "active keyframe must be selected");
fcu->active_keyframe_index = (int)offset;
}

View File

@ -854,17 +854,9 @@ class PositionAttributeProvider final : public BuiltinPointAttributeProvider<flo
return {};
}
bool curve_has_bezier_spline = false;
for (SplinePtr &spline : curve->splines()) {
if (spline->type() == Spline::Type::Bezier) {
curve_has_bezier_spline = true;
break;
}
}
/* Use the regular position virtual array when there aren't any Bezier splines
* to avoid the overhead of checking the spline type for every point. */
if (!curve_has_bezier_spline) {
if (!curve->has_spline_with_type(Spline::Type::Bezier)) {
return BuiltinPointAttributeProvider<float3>::try_get_for_write(component);
}

View File

@ -667,7 +667,7 @@ void BKE_previewimg_blend_read(BlendDataReader *reader, PreviewImage *prv)
BKE_previewimg_finish(prv, i);
}
else {
/* Only for old files that didn't write the flag . */
/* Only for old files that didn't write the flag. */
prv->flag[i] |= PRV_UNFINISHED;
}
}

View File

@ -1237,7 +1237,7 @@ void BKE_layer_collection_isolate_global(Scene *scene,
bool hide_it = extend && (lc->runtime_flag & LAYER_COLLECTION_VISIBLE_VIEW_LAYER);
if (!extend) {
/* Hide all collections . */
/* Hide all collections. */
LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_master->layer_collections) {
layer_collection_flag_set_recursive(lc_iter, LAYER_COLLECTION_HIDE);
}

View File

@ -95,9 +95,14 @@ void BKE_mesh_foreach_mapped_vert(Mesh *mesh,
}
}
/* Copied from cdDM_foreachMappedEdge */
/**
* Copied from #cdDM_foreachMappedEdge.
* \param tot_edges: Number of original edges. Used to avoid calling the callback with invalid
* edge indices.
*/
void BKE_mesh_foreach_mapped_edge(
Mesh *mesh,
const int tot_edges,
void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
void *userData)
{
@ -138,7 +143,7 @@ void BKE_mesh_foreach_mapped_edge(
func(userData, orig, mv[med->v1].co, mv[med->v2].co);
}
}
else {
else if (mesh->totedge == tot_edges) {
for (int i = 0; i < mesh->totedge; i++, med++) {
func(userData, i, mv[med->v1].co, mv[med->v2].co);
}

View File

@ -530,6 +530,36 @@ void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr,
lnors_spacearr->data_type = data_type;
}
/**
* Utility for multi-threaded calculation that ensures
* `lnors_spacearr_tls` doesn't share memory with `lnors_spacearr`
* that would cause it not to be thread safe.
*
* \note This works as long as threads never operate on the same loops at once.
*/
void BKE_lnor_spacearr_tls_init(MLoopNorSpaceArray *lnors_spacearr,
MLoopNorSpaceArray *lnors_spacearr_tls)
{
*lnors_spacearr_tls = *lnors_spacearr;
lnors_spacearr_tls->mem = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
}
/**
* Utility for multi-threaded calculation
* that merges `lnors_spacearr_tls` into `lnors_spacearr`.
*/
void BKE_lnor_spacearr_tls_join(MLoopNorSpaceArray *lnors_spacearr,
MLoopNorSpaceArray *lnors_spacearr_tls)
{
BLI_assert(lnors_spacearr->data_type == lnors_spacearr_tls->data_type);
BLI_assert(lnors_spacearr->mem != lnors_spacearr_tls->mem);
lnors_spacearr->num_spaces += lnors_spacearr_tls->num_spaces;
BLI_memarena_merge(lnors_spacearr->mem, lnors_spacearr_tls->mem);
BLI_memarena_free(lnors_spacearr_tls->mem);
lnors_spacearr_tls->mem = nullptr;
BKE_lnor_spacearr_clear(lnors_spacearr_tls);
}
void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr)
{
lnors_spacearr->num_spaces = 0;

View File

@ -1212,10 +1212,12 @@ static void update_typeinfo(Main *bmain,
FOREACH_NODETREE_END;
}
/* Try to initialize all typeinfo in a node tree.
* NB: In general undefined typeinfo is a perfectly valid case,
/**
* Try to initialize all type-info in a node tree.
*
* \note In general undefined type-info is a perfectly valid case,
* the type may just be registered later.
* In that case the update_typeinfo function will set typeinfo on registration
* In that case the update_typeinfo function will set type-info on registration
* and do necessary updates.
*/
void ntreeSetTypes(const struct bContext *C, bNodeTree *ntree)
@ -5117,6 +5119,7 @@ static void registerGeometryNodes()
register_node_type_geo_curve_primitive_star();
register_node_type_geo_curve_resample();
register_node_type_geo_curve_reverse();
register_node_type_geo_curve_set_handles();
register_node_type_geo_curve_subdivide();
register_node_type_geo_curve_to_mesh();
register_node_type_geo_curve_to_points();

View File

@ -880,7 +880,7 @@ static int palettecolor_compare_luminance(const void *a1, const void *a2)
void BKE_palette_sort_hsv(tPaletteColorHSV *color_array, const int totcol)
{
/* Sort by Hue , Saturation and Value. */
/* Sort by Hue, Saturation and Value. */
qsort(color_array, totcol, sizeof(tPaletteColorHSV), palettecolor_compare_hsv);
}

View File

@ -423,7 +423,7 @@ static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *
/* get some info from CCGSubSurf */
totface = ccgSubSurf_getNumFaces(uvss);
/* edgeSize = ccgSubSurf_getEdgeSize(uvss); */ /*UNUSED*/
// edgeSize = ccgSubSurf_getEdgeSize(uvss); /* UNUSED */
gridSize = ccgSubSurf_getGridSize(uvss);
gridFaces = gridSize - 1;

View File

@ -1303,7 +1303,7 @@ const char *BKE_unit_identifier_get(const void *usys_pt, int index)
{
const bUnitDef *unit = ((const bUnitCollection *)usys_pt)->units + index;
if (unit->identifier == NULL) {
BLI_assert(false && "identifier for this unit is not specified yet");
BLI_assert_msg(0, "identifier for this unit is not specified yet");
}
return unit->identifier;
}

View File

@ -58,7 +58,7 @@ static void workspace_init_data(ID *id)
{
WorkSpace *workspace = (WorkSpace *)id;
BKE_asset_library_reference_init_default(&workspace->active_asset_library);
BKE_asset_library_reference_init_default(&workspace->asset_library);
}
static void workspace_free_data(ID *id)

View File

@ -1747,9 +1747,10 @@ void BKE_ffmpeg_preset_set(RenderData *rd, int preset)
rd->ffcodecdata.type = FFMPEG_MPEG2;
rd->ffcodecdata.video_bitrate = 6000;
/* Don't set resolution, see T21351.
* rd->xsch = 720;
* rd->ysch = isntsc ? 480 : 576; */
# if 0 /* Don't set resolution, see T21351. */
rd->xsch = 720;
rd->ysch = isntsc ? 480 : 576;
# endif
rd->ffcodecdata.gop_size = isntsc ? 18 : 15;
rd->ffcodecdata.rc_max_rate = 9000;

View File

@ -51,8 +51,14 @@ struct float4x4 {
{
BLI_ASSERT_UNIT_V3(forward);
BLI_ASSERT_UNIT_V3(up);
/* Negate the cross product so that the resulting matrix has determinant 1 (instead of -1).
* Without the negation, the result would be a so called improper rotation. That means it
* contains a reflection. Such an improper rotation matrix could not be converted to another
* representation of a rotation such as euler angles. */
const float3 cross = -float3::cross(forward, up);
float4x4 matrix;
const float3 cross = float3::cross(forward, up);
matrix.values[0][0] = forward.x;
matrix.values[1][0] = cross.x;
matrix.values[2][0] = up.x;

View File

@ -22,7 +22,7 @@
* \brief BVH-tree implementation.
*
* k-DOP BVH (Discrete Oriented Polytope, Bounding Volume Hierarchy).
* A k-DOP is represented as k/2 pairs of min , max values for k/2 directions (intervals, "slabs").
* A k-DOP is represented as k/2 pairs of min, max values for k/2 directions (intervals, "slabs").
*
* See: http://www.gris.uni-tuebingen.de/people/staff/jmezger/papers/bvh.pdf
*

View File

@ -2208,7 +2208,10 @@ static int power_of_10_greater_equal_to(int x)
* order around each face in turn. And then the next face starts at
* cdt->face_edge_offset beyond the start for the previous face.
*/
template<typename T> void add_face_constraints(CDT_state<T> *cdt_state, const CDT_input<T> &input)
template<typename T>
void add_face_constraints(CDT_state<T> *cdt_state,
const CDT_input<T> &input,
CDT_output_type output_type)
{
int nv = input.vert.size();
int nf = input.face.size();
@ -2265,8 +2268,16 @@ template<typename T> void add_face_constraints(CDT_state<T> *cdt_state, const CD
}
int fedge_end = fedge_start + flen - 1;
if (face_symedge0 != nullptr) {
/* We need to propagate face ids to all faces that represent #f, if #need_ids.
* Even if `need_ids == false`, we need to propagate at least the fact that
* the face ids set would be non-empty if the output type is one of the ones
* making valid BMesh faces. */
int id = cdt_state->need_ids ? f : 0;
add_face_ids(cdt_state, face_symedge0, id, fedge_start, fedge_end);
if (cdt_state->need_ids || (output_type == CDT_CONSTRAINTS_VALID_BMESH ||
output_type == CDT_CONSTRAINTS_VALID_BMESH_WITH_HOLES)) {
add_face_ids(cdt_state, face_symedge0, f, fedge_start, fedge_end);
}
}
fstart += flen;
}
@ -2779,7 +2790,7 @@ CDT_result<T> delaunay_calc(const CDT_input<T> &input, CDT_output_type output_ty
add_input_verts(&cdt_state, input);
initial_triangulation(&cdt_state.cdt);
add_edge_constraints(&cdt_state, input);
add_face_constraints(&cdt_state, input);
add_face_constraints(&cdt_state, input, output_type);
return get_cdt_output(&cdt_state, input, output_type);
}

View File

@ -625,7 +625,7 @@ void BLI_ewa_filter(const int width,
* Use a different radius based on interpolation switch,
* just enough to anti-alias when interpolation is off,
* and slightly larger to make result a bit smoother than bilinear interpolation when
* interpolation is on (minimum values: const float rmin = intpol ? 1.0f : 0.5f;) */
* interpolation is on (minimum values: `const float rmin = intpol ? 1.0f : 0.5f;`) */
const float rmin = (intpol ? 1.5625f : 0.765625f) / ff2;
BLI_ewa_imp2radangle(A, B, C, F, &a, &b, &th, &ecc);
if ((b2 = b * b) < rmin) {

View File

@ -276,7 +276,7 @@ void mul_m4_m4m4_uniq(float R[4][4], const float A[4][4], const float B[4][4])
{
BLI_assert(!ELEM(R, A, B));
/* matrix product: R[j][k] = A[j][i] . B[i][k] */
/* Matrix product: `R[j][k] = A[j][i] . B[i][k]`. */
#ifdef BLI_HAVE_SSE2
__m128 A0 = _mm_loadu_ps(A[0]);
__m128 A1 = _mm_loadu_ps(A[1]);
@ -321,7 +321,7 @@ void mul_m4_m4m4_db_uniq(double R[4][4], const double A[4][4], const double B[4]
{
BLI_assert(!ELEM(R, A, B));
/* matrix product: R[j][k] = A[j][i] . B[i][k] */
/* Matrix product: `R[j][k] = A[j][i] . B[i][k]`. */
R[0][0] = B[0][0] * A[0][0] + B[0][1] * A[1][0] + B[0][2] * A[2][0] + B[0][3] * A[3][0];
R[0][1] = B[0][0] * A[0][1] + B[0][1] * A[1][1] + B[0][2] * A[2][1] + B[0][3] * A[3][1];
@ -349,7 +349,7 @@ void mul_m4db_m4db_m4fl_uniq(double R[4][4], const double A[4][4], const float B
/* Remove second check since types don't match. */
BLI_assert(!ELEM(R, A /*, B */));
/* matrix product: R[j][k] = A[j][i] . B[i][k] */
/* Matrix product: `R[j][k] = A[j][i] . B[i][k]`. */
R[0][0] = B[0][0] * A[0][0] + B[0][1] * A[1][0] + B[0][2] * A[2][0] + B[0][3] * A[3][0];
R[0][1] = B[0][0] * A[0][1] + B[0][1] * A[1][1] + B[0][2] * A[2][1] + B[0][3] * A[3][1];

View File

@ -182,8 +182,8 @@ void BLI_string_flip_side_name(char *r_name,
/* We first check the case with a .### extension, let's find the last period */
if (isdigit(r_name[len - 1])) {
index = strrchr(r_name, '.'); /* last occurrence. */
if (index && isdigit(index[1])) { /* doesn't handle case bone.1abc2 correct..., whatever! */
index = strrchr(r_name, '.'); /* Last occurrence. */
if (index && isdigit(index[1])) { /* Doesn't handle case `bone.1abc2` correct..., whatever! */
if (strip_number == false) {
BLI_strncpy(number, index, name_len);
}
@ -194,7 +194,7 @@ void BLI_string_flip_side_name(char *r_name,
BLI_strncpy(prefix, r_name, name_len);
/* first case; separator . - _ with extensions r R l L. */
/* First case; separator (`.` or `_`) with extensions in `r R l L`. */
if ((len > 1) && is_char_sep(r_name[len - 2])) {
is_set = true;
switch (r_name[len - 1]) {

View File

@ -532,7 +532,7 @@ bool BLI_task_pool_current_canceled(TaskPool *pool)
case TASK_POOL_BACKGROUND_SERIAL:
return background_task_pool_canceled(pool);
}
BLI_assert("BLI_task_pool_canceled: Control flow should not come here!");
BLI_assert_msg(0, "BLI_task_pool_canceled: Control flow should not come here!");
return false;
}

View File

@ -1874,7 +1874,7 @@ void text_test(
vec2<T> start_co = b_vert[arc_origin_vert];
vec2<T> end_co = b_vert[arc_terminal_vert];
vec2<T> center_co = 0.5 * (start_co + end_co);
BLI_assert(start_co[0] == end_co[2]);
BLI_assert(start_co[0] == end_co[0]);
double radius = abs(math_to_double<T>(end_co[1] - center_co[1]));
double angle_delta = M_PI / (num_arc_points + 1);
int start_vert = b_before_arcs_in.vert.size() + arc * num_arc_points;
@ -1948,6 +1948,12 @@ void text_test(
if (num_lines > 1) {
label += " lines=" + std::to_string(num_lines);
}
if (!need_ids) {
label += " no_ids";
}
if (otype != CDT_INSIDE_WITH_HOLES) {
label += " otype=" + std::to_string(otype);
}
graph_draw<T>(label, out.vert, out.edge, out.face);
}
}
@ -1957,6 +1963,51 @@ TEST(delaunay_d, TextB10)
text_test<double>(10, 1, 1, CDT_INSIDE_WITH_HOLES, true);
}
TEST(delaunay_d, TextB10_noids)
{
text_test<double>(10, 1, 1, CDT_INSIDE_WITH_HOLES, false);
}
TEST(delaunay_d, TextB10_inside)
{
text_test<double>(10, 1, 1, CDT_INSIDE, true);
}
TEST(delaunay_d, TextB10_inside_noids)
{
text_test<double>(10, 1, 1, CDT_INSIDE, false);
}
TEST(delaunay_d, TextB10_constraints)
{
text_test<double>(10, 1, 1, CDT_CONSTRAINTS, true);
}
TEST(delaunay_d, TextB10_constraints_noids)
{
text_test<double>(10, 1, 1, CDT_CONSTRAINTS, false);
}
TEST(delaunay_d, TextB10_constraints_valid_bmesh)
{
text_test<double>(10, 1, 1, CDT_CONSTRAINTS_VALID_BMESH, true);
}
TEST(delaunay_d, TextB10_constraints_valid_bmesh_noids)
{
text_test<double>(10, 1, 1, CDT_CONSTRAINTS_VALID_BMESH, false);
}
TEST(delaunay_d, TextB10_constraints_valid_bmesh_with_holes)
{
text_test<double>(10, 1, 1, CDT_CONSTRAINTS_VALID_BMESH_WITH_HOLES, true);
}
TEST(delaunay_d, TextB10_constraints_valid_bmesh_with_holes_noids)
{
text_test<double>(10, 1, 1, CDT_CONSTRAINTS_VALID_BMESH_WITH_HOLES, false);
}
TEST(delaunay_d, TextB200)
{
text_test<double>(200, 1, 1, CDT_INSIDE_WITH_HOLES, true);

View File

@ -866,11 +866,11 @@ static void fill_sphere_data(int nrings,
};
Array<int> eid = {0, 0, 0, 0}; /* Don't care about edge ids. */
/*
* (x, y , z) is given from inclination theta and azimuth phi,
* where 0 <= theta <= pi; 0 <= phi <= 2pi.
* x = radius * sin(theta) cos(phi)
* y = radius * sin(theta) sin(phi)
* z = radius * cos(theta)
* (x, y, z) is given from inclination theta and azimuth phi,
* where: `0 <= theta <= pi; 0 <= phi <= 2pi`.
* `x = radius * sin(theta) cos(phi)`
* `y = radius * sin(theta) sin(phi)`
* `z = radius * cos(theta)`
*/
for (int s = 0; s < nsegs; ++s) {
double phi = s * delta_phi;

View File

@ -2444,7 +2444,7 @@ static void direct_link_id_common(
BlendDataReader *reader, Library *current_library, ID *id, ID *id_old, const int tag)
{
if (!BLO_read_data_is_undo(reader)) {
/* When actually reading a file , we do want to reset/re-generate session uuids.
/* When actually reading a file, we do want to reset/re-generate session uuids.
* In undo case, we want to re-use existing ones. */
id->session_uuid = MAIN_ID_SESSION_UUID_UNSET;
}

View File

@ -2149,7 +2149,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
/* NB: scene->nodetree is a local ID block, has been direct_link'ed */
/* NOTE: `scene->nodetree` is a local ID block, has been direct_link'ed. */
if (scene->nodetree) {
scene->nodetree->active_viewer_key = active_viewer_key;
}

View File

@ -29,6 +29,7 @@
#include "DNA_armature_types.h"
#include "DNA_brush_types.h"
#include "DNA_collection_types.h"
#include "DNA_curve_types.h"
#include "DNA_genfile.h"
#include "DNA_listBase.h"
#include "DNA_material_types.h"
@ -41,6 +42,7 @@
#include "BKE_asset.h"
#include "BKE_collection.h"
#include "BKE_deform.h"
#include "BKE_fcurve.h"
#include "BKE_fcurve_driver.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
@ -49,11 +51,10 @@
#include "BLO_readfile.h"
#include "MEM_guardedalloc.h"
#include "readfile.h"
#include "versioning_common.h"
#include "SEQ_sequencer.h"
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
#include "versioning_common.h"
@ -113,6 +114,74 @@ static void move_vertex_group_names_to_object_data(Main *bmain)
}
}
static void do_versions_sequencer_speed_effect_recursive(Scene *scene, const ListBase *seqbase)
{
/* Old SpeedControlVars->flags. */
#define SEQ_SPEED_INTEGRATE (1 << 0)
#define SEQ_SPEED_COMPRESS_IPO_Y (1 << 2)
LISTBASE_FOREACH (Sequence *, seq, seqbase) {
if (seq->type == SEQ_TYPE_SPEED) {
SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
const char *substr = NULL;
float globalSpeed = v->globalSpeed;
if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) {
if (globalSpeed == 1.0f) {
v->speed_control_type = SEQ_SPEED_STRETCH;
}
else {
v->speed_control_type = SEQ_SPEED_MULTIPLY;
v->speed_fader = globalSpeed *
((float)seq->seq1->len /
max_ff((float)(seq->seq1->enddisp - seq->seq1->start), 1.0f));
}
}
else if (v->flags & SEQ_SPEED_INTEGRATE) {
v->speed_control_type = SEQ_SPEED_MULTIPLY;
v->speed_fader = seq->speed_fader * globalSpeed;
}
else if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
globalSpeed *= 100.0f;
v->speed_control_type = SEQ_SPEED_LENGTH;
v->speed_fader_length = seq->speed_fader * globalSpeed;
substr = "speed_length";
}
else {
v->speed_control_type = SEQ_SPEED_FRAME_NUMBER;
v->speed_fader_frame_number = (int)(seq->speed_fader * globalSpeed);
substr = "speed_frame_number";
}
v->flags &= ~(SEQ_SPEED_INTEGRATE | SEQ_SPEED_COMPRESS_IPO_Y);
if (substr || globalSpeed != 1.0f) {
FCurve *fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0, NULL);
if (fcu) {
if (globalSpeed != 1.0f) {
for (int i = 0; i < fcu->totvert; i++) {
BezTriple *bezt = &fcu->bezt[i];
bezt->vec[0][1] *= globalSpeed;
bezt->vec[1][1] *= globalSpeed;
bezt->vec[2][1] *= globalSpeed;
}
}
if (substr) {
char *new_path = BLI_str_replaceN(fcu->rna_path, "speed_factor", substr);
MEM_freeN(fcu->rna_path);
fcu->rna_path = new_path;
}
}
}
}
else if (seq->type == SEQ_TYPE_META) {
do_versions_sequencer_speed_effect_recursive(scene, &seq->seqbase);
}
}
#undef SEQ_SPEED_INTEGRATE
#undef SEQ_SPEED_COMPRESS_IPO_Y
}
void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
{
if (MAIN_VERSION_ATLEAST(bmain, 300, 0) && !MAIN_VERSION_ATLEAST(bmain, 300, 1)) {
@ -161,6 +230,14 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
move_vertex_group_names_to_object_data(bmain);
}
if (!MAIN_VERSION_ATLEAST(bmain, 300, 13)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
if (scene->ed != NULL) {
do_versions_sequencer_speed_effect_recursive(scene, &scene->ed->seqbase);
}
}
}
/**
* Versioning code until next subversion bump goes here.
*
@ -531,15 +608,6 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
FOREACH_NODETREE_END;
{
if (!DNA_struct_elem_find(
fd->filesdna, "WorkSpace", "AssetLibraryReference", "active_asset_library")) {
LISTBASE_FOREACH (WorkSpace *, workspace, &bmain->workspaces) {
BKE_asset_library_reference_init_default(&workspace->active_asset_library);
}
}
}
}
if (!MAIN_VERSION_ATLEAST(bmain, 300, 10)) {
@ -552,18 +620,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
/**
* Versioning code until next subversion bump goes here.
*
* \note Be sure to check when bumping the version:
* - "versioning_userdef.c", #blo_do_versions_userdef
* - "versioning_userdef.c", #do_versions_theme
*
* \note Keep this message at the bottom of the function.
*/
{
/* Keep this block, even when empty. */
if (!MAIN_VERSION_ATLEAST(bmain, 300, 13)) {
/* Convert Surface Deform to sparse-capable bind structure. */
if (!DNA_struct_elem_find(
fd->filesdna, "SurfaceDeformModifierData", "int", "num_mesh_verts")) {
@ -582,5 +639,42 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
}
if (!DNA_struct_elem_find(
fd->filesdna, "WorkSpace", "AssetLibraryReference", "asset_library")) {
LISTBASE_FOREACH (WorkSpace *, workspace, &bmain->workspaces) {
BKE_asset_library_reference_init_default(&workspace->asset_library);
}
}
if (!DNA_struct_elem_find(
fd->filesdna, "FileAssetSelectParams", "AssetLibraryReference", "asset_library")) {
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
if (space->spacetype == SPACE_FILE) {
SpaceFile *sfile = (SpaceFile *)space;
if (sfile->browse_mode != FILE_BROWSE_MODE_ASSETS) {
continue;
}
BKE_asset_library_reference_init_default(&sfile->asset_params->asset_library);
}
}
}
}
}
}
/**
* Versioning code until next subversion bump goes here.
*
* \note Be sure to check when bumping the version:
* - "versioning_userdef.c", #blo_do_versions_userdef
* - "versioning_userdef.c", #do_versions_theme
*
* \note Keep this message at the bottom of the function.
*/
{
/* Keep this block, even when empty. */
}
}

View File

@ -883,6 +883,10 @@ void blo_do_versions_userdef(UserDef *userdef)
userdef->sequencer_proxy_setup = USER_SEQ_PROXY_SETUP_AUTOMATIC;
}
if (!USER_VERSION_ATLEAST(293, 13)) {
BKE_addon_ensure(&userdef->addons, "pose_library");
}
/**
* Versioning code until next subversion bump goes here.
*
@ -894,7 +898,6 @@ void blo_do_versions_userdef(UserDef *userdef)
*/
{
/* Keep this block, even when empty. */
BKE_addon_ensure(&userdef->addons, "pose_library");
}
LISTBASE_FOREACH (bTheme *, btheme, &userdef->themes) {

View File

@ -185,7 +185,7 @@ typedef struct BMLoop {
struct BMFace *f;
/**
* Other loops connected to this edge,.
* Other loops connected to this edge.
*
* This is typically use for accessing an edges faces,
* however this is done by stepping over it's loops.

File diff suppressed because it is too large Load Diff

View File

@ -272,7 +272,7 @@ int BM_mesh_calc_edge_groups_as_arrays(BMesh *bm,
int (**r_groups)[3]) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL(1, 2, 3, 4, 5);
/* not really any good place to put this */
/* Not really any good place to put this. */
float bmesh_subd_falloff_calc(const int falloff, float val) ATTR_WARN_UNUSED_RESULT;
#include "bmesh_query_inline.h"

View File

@ -1336,7 +1336,7 @@ static void bm_vert_fasthash_destroy(UUIDFashMatch *fm)
* Take a face-region and return a list of matching face-regions.
*
* \param faces_region: A single, contiguous face-region.
* \return A list of matching null-terminated face-region arrays.
* \return A list of matching null-terminated face-region arrays.
*/
int BM_mesh_region_match(BMesh *bm,
BMFace **faces_region,

View File

@ -66,6 +66,7 @@ constexpr int COM_DATA_TYPE_VALUE_CHANNELS = COM_data_type_num_channels(DataType
constexpr int COM_DATA_TYPE_VECTOR_CHANNELS = COM_data_type_num_channels(DataType::Vector);
constexpr int COM_DATA_TYPE_COLOR_CHANNELS = COM_data_type_num_channels(DataType::Color);
constexpr float COM_COLOR_TRANSPARENT[4] = {0.0f, 0.0f, 0.0f, 0.0f};
constexpr float COM_VECTOR_ZERO[3] = {0.0f, 0.0f, 0.0f};
constexpr float COM_VALUE_ZERO[1] = {0.0f};
constexpr float COM_VALUE_ONE[1] = {1.0f};

View File

@ -18,8 +18,8 @@
#pragma once
#include "BLI_assert.h"
#include "BLI_rect.h"
#include <iterator>
namespace blender::compositor {
@ -111,26 +111,35 @@ template<typename T> class BufferArea : rcti {
private:
template<typename TIterator> constexpr TIterator begin_iterator() const
{
T *end_ptr = get_end_ptr();
if (elem_stride_ == 0) {
/* Iterate a single element. */
return TIterator(buffer_, 1, 1, 1);
return TIterator(buffer_, end_ptr, 1, 1, 1);
}
T *begin_ptr = buffer_ + (intptr_t)this->ymin * buffer_width_ * elem_stride_ +
(intptr_t)this->xmin * elem_stride_;
return TIterator(begin_ptr, buffer_width_, BLI_rcti_size_x(this), elem_stride_);
return TIterator(begin_ptr, end_ptr, buffer_width_, BLI_rcti_size_x(this), elem_stride_);
}
template<typename TIterator> constexpr TIterator end_iterator() const
{
T *end_ptr = get_end_ptr();
if (elem_stride_ == 0) {
/* Iterate a single element. */
return TIterator(buffer_ + 1, 1, 1, 1);
return TIterator(end_ptr, end_ptr, 1, 1, 1);
}
T *end_ptr = buffer_ + (intptr_t)(this->ymax - 1) * buffer_width_ * elem_stride_ +
(intptr_t)this->xmax * elem_stride_;
return TIterator(end_ptr, buffer_width_, BLI_rcti_size_x(this), elem_stride_);
return TIterator(end_ptr, end_ptr, buffer_width_, BLI_rcti_size_x(this), elem_stride_);
}
T *get_end_ptr() const
{
if (elem_stride_ == 0) {
return buffer_ + 1;
}
return buffer_ + (intptr_t)(this->ymax - 1) * buffer_width_ * elem_stride_ +
(intptr_t)this->xmax * elem_stride_;
}
};
@ -149,23 +158,31 @@ template<typename T> class BufferAreaIterator {
int rows_gap_;
T *current_;
const T *row_end_;
const T *end_;
public:
constexpr BufferAreaIterator() = default;
constexpr BufferAreaIterator(T *current, int buffer_width, int area_width, int elem_stride = 1)
constexpr BufferAreaIterator(
T *current, const T *end, int buffer_width, int area_width, int elem_stride = 1)
: elem_stride_(elem_stride),
row_stride_(buffer_width * elem_stride),
rows_gap_(row_stride_ - area_width * elem_stride),
current_(current),
row_end_(current + area_width * elem_stride)
row_end_(current + area_width * elem_stride),
end_(end)
{
}
constexpr BufferAreaIterator &operator++()
{
current_ += elem_stride_;
BLI_assert(current_ <= row_end_);
if (current_ == row_end_) {
BLI_assert(current_ <= end_);
if (current_ == end_) {
return *this;
}
current_ += rows_gap_;
row_end_ += row_stride_;
}

View File

@ -31,10 +31,10 @@ namespace blender::compositor {
template<typename T> class BuffersIteratorBuilder {
public:
class Iterator {
int x_start_;
int x_end_;
const T *out_end_;
const T *out_row_end_;
int out_elem_stride_;
int out_row_stride_;
/* Stride between an output row end and the next row start. */
int out_rows_gap_;
@ -48,9 +48,9 @@ template<typename T> class BuffersIteratorBuilder {
friend class BuffersIteratorBuilder;
public:
/**
* Current output element.
*/
int x;
int y;
/** Current output element. */
T *out;
public:
@ -85,9 +85,11 @@ template<typename T> class BuffersIteratorBuilder {
for (In &in : ins_) {
in.in += in.elem_stride;
}
if (out == out_row_end_) {
x++;
if (x == x_end_) {
x = x_start_;
y++;
out += out_rows_gap_;
out_row_end_ += out_row_stride_;
for (In &in : ins_) {
in.in += in.rows_gap;
}
@ -110,43 +112,72 @@ template<typename T> class BuffersIteratorBuilder {
/**
* Create a buffers iterator builder to iterate given output buffer area.
* \param output: Output buffer.
* \param buffer_width: Number of elements in an output buffer row.
* \param area: Rectangle area to be iterated in all buffers.
* \param buffer_area: Whole output buffer area (may have offset position).
* \param iterated_area: Area to be iterated in all buffers.
* \param elem_stride: Output buffer element stride.
*/
BuffersIteratorBuilder(T *output, int buffer_width, const rcti &area, int elem_stride = 1)
: area_(area), is_built_(false)
BuffersIteratorBuilder(T *output,
const rcti &buffer_area,
const rcti &iterated_area,
int elem_stride = 1)
: area_(iterated_area), is_built_(false)
{
BLI_assert(BLI_rcti_inside_rcti(&buffer_area, &iterated_area));
iterator_.x = iterated_area.xmin;
iterator_.y = iterated_area.ymin;
iterator_.x_start_ = iterated_area.xmin;
iterator_.x_end_ = iterated_area.xmax;
iterator_.out_elem_stride_ = elem_stride;
iterator_.out_row_stride_ = buffer_width * elem_stride;
iterator_.out_rows_gap_ = iterator_.out_row_stride_ - BLI_rcti_size_x(&area) * elem_stride;
iterator_.out = output + (intptr_t)area.ymin * iterator_.out_row_stride_ +
(intptr_t)area.xmin * elem_stride;
iterator_.out_row_end_ = iterator_.out + (intptr_t)BLI_rcti_size_x(&area) * elem_stride;
iterator_.out_end_ = iterator_.out_row_end_ +
(intptr_t)iterator_.out_row_stride_ * (BLI_rcti_size_y(&area) - 1);
const int buffer_width = BLI_rcti_size_x(&buffer_area);
intptr_t out_row_stride = buffer_width * elem_stride;
iterator_.out_rows_gap_ = out_row_stride - BLI_rcti_size_x(&iterated_area) * elem_stride;
const int out_start_x = iterated_area.xmin - buffer_area.xmin;
const int out_start_y = iterated_area.ymin - buffer_area.ymin;
iterator_.out = output + (intptr_t)out_start_y * out_row_stride +
(intptr_t)out_start_x * elem_stride;
const T *out_row_end_ = iterator_.out +
(intptr_t)BLI_rcti_size_x(&iterated_area) * elem_stride;
iterator_.out_end_ = out_row_end_ +
(intptr_t)out_row_stride * (BLI_rcti_size_y(&iterated_area) - 1);
}
/**
* Create a buffers iterator builder to iterate given output buffer with no offsets.
*/
BuffersIteratorBuilder(T *output, int buffer_width, int buffer_height, int elem_stride = 1)
: BuffersIteratorBuilder(
output, buffer_width, {0, buffer_width, 0, buffer_height}, elem_stride)
: BuffersIteratorBuilder(output,
{0, buffer_width, 0, buffer_height},
{0, buffer_width, 0, buffer_height},
elem_stride)
{
}
/**
* Add an input buffer to be iterated. Its coordinates must be correlated with the output.
* Add an input buffer to be iterated. It must contain iterated area.
*/
void add_input(const T *input, const rcti &buffer_area, int elem_stride = 1)
{
BLI_assert(!is_built_);
BLI_assert(BLI_rcti_inside_rcti(&buffer_area, &area_));
typename Iterator::In in;
in.elem_stride = elem_stride;
const int buffer_width = BLI_rcti_size_x(&buffer_area);
in.rows_gap = buffer_width * elem_stride - BLI_rcti_size_x(&area_) * elem_stride;
const int in_start_x = area_.xmin - buffer_area.xmin;
const int in_start_y = area_.ymin - buffer_area.ymin;
in.in = input + in_start_y * buffer_width * elem_stride + in_start_x * elem_stride;
iterator_.ins_.append(std::move(in));
}
/**
* Add an input buffer to be iterated with no offsets. It must contain iterated area.
*/
void add_input(const T *input, int buffer_width, int elem_stride = 1)
{
BLI_assert(!is_built_);
typename Iterator::In in;
in.elem_stride = elem_stride;
in.rows_gap = buffer_width * elem_stride - BLI_rcti_size_x(&area_) * elem_stride;
in.in = input + area_.ymin * buffer_width * elem_stride + area_.xmin * elem_stride;
iterator_.ins_.append(std::move(in));
rcti buffer_area;
BLI_rcti_init(&buffer_area, 0, buffer_width, 0, area_.ymax);
add_input(input, buffer_area, elem_stride);
}
/**

View File

@ -20,6 +20,7 @@
#include "COM_Debug.h"
#include "COM_ExecutionGroup.h"
#include "COM_ReadBufferOperation.h"
#include "COM_ViewerOperation.h"
#include "COM_WorkScheduler.h"
#include "BLT_translation.h"
@ -100,11 +101,15 @@ void FullFrameExecutionModel::render_operation(NodeOperation *op)
const bool has_outputs = op->getNumberOfOutputSockets() > 0;
MemoryBuffer *op_buf = has_outputs ? create_operation_buffer(op) : nullptr;
Span<rcti> areas = active_buffers_.get_areas_to_render(op);
op->render(op_buf, areas, input_bufs);
if (op->getWidth() > 0 && op->getHeight() > 0) {
Span<rcti> areas = active_buffers_.get_areas_to_render(op);
op->render(op_buf, areas, input_bufs);
DebugInfo::operation_rendered(op, op_buf);
}
/* Even if operation has no resolution set the empty buffer. It will be clipped with a
* TranslateOperation from convert resolutions if linked to an operation with resolution. */
active_buffers_.set_rendered_buffer(op, std::unique_ptr<MemoryBuffer>(op_buf));
DebugInfo::operation_rendered(op, op_buf);
operation_finished(op);
}
@ -118,10 +123,16 @@ void FullFrameExecutionModel::render_operations()
WorkScheduler::start(this->context_);
for (eCompositorPriority priority : priorities_) {
for (NodeOperation *op : operations_) {
if (op->isOutputOperation(is_rendering) && op->getRenderPriority() == priority) {
const bool has_size = op->getWidth() > 0 && op->getHeight() > 0;
const bool is_priority_output = op->isOutputOperation(is_rendering) &&
op->getRenderPriority() == priority;
if (is_priority_output && has_size) {
render_output_dependencies(op);
render_operation(op);
}
else if (is_priority_output && !has_size && op->isActiveViewerOutput()) {
static_cast<ViewerOperation *>(op)->clear_display_buffer();
}
}
}
WorkScheduler::stop();

View File

@ -136,9 +136,9 @@ BuffersIterator<float> MemoryBuffer::iterate_with(Span<MemoryBuffer *> inputs)
BuffersIterator<float> MemoryBuffer::iterate_with(Span<MemoryBuffer *> inputs, const rcti &area)
{
BuffersIteratorBuilder<float> builder(m_buffer, getWidth(), area, elem_stride);
BuffersIteratorBuilder<float> builder(m_buffer, m_rect, area, elem_stride);
for (MemoryBuffer *input : inputs) {
builder.add_input(input->getBuffer(), input->getWidth(), input->elem_stride);
builder.add_input(input->getBuffer(), input->get_rect(), input->elem_stride);
}
return builder.build();
}

View File

@ -143,7 +143,7 @@ void RenderLayersNode::missingSocketLink(NodeConverter &converter, NodeOutput *o
break;
}
default: {
BLI_assert("!Unexpected data type");
BLI_assert_msg(0, "Unexpected data type");
return;
}
}

View File

@ -988,11 +988,11 @@ static void do_createEdgeLocationBuffer(unsigned int t,
*
* Example: 9 by 9 pixel block
*
* . = pixel non-white in both outer and inner mask
* o = pixel white in outer, but not inner mask, adjacent to "." pixel
* g = pixel white in outer, but not inner mask, not adjacent to "." pixel
* i = pixel white in inner mask, adjacent to "g" or "." pixel
* F = pixel white in inner mask, only adjacent to other pixels white in the inner mask
* `.` = Pixel non-white in both outer and inner mask.
* `o` = Pixel white in outer, but not inner mask, adjacent to "." pixel.
* `g` = Pixel white in outer, but not inner mask, not adjacent to "." pixel.
* `i` = Pixel white in inner mask, adjacent to "g" or "." pixel.
* `F` = Pixel white in inner mask, only adjacent to other pixels white in the inner mask.
*
*
* ......... <----- pixel #80
@ -1108,9 +1108,9 @@ static void do_fillGradientBuffer(unsigned int rw,
* outside edge.
*
* In an image where:
* . = blank (black) pixels, not covered by inner mask or outer mask
* + = desired gradient pixels, covered only by outer mask
* * = white full mask pixels, covered by at least inner mask
* `.` = Blank (black) pixels, not covered by inner mask or outer mask.
* `+` = Desired gradient pixels, covered only by outer mask.
* `*` = White full mask pixels, covered by at least inner mask.
*
* ...............................
* ...............+++++++++++.....

View File

@ -148,8 +148,8 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src,
}
/* See "Recursive Gabor Filtering" by Young/VanVliet
* all factors here in double.prec.
* Required, because for single.prec it seems to blow up if sigma > ~200 */
* all factors here in double-precision.
* Required, because for single-precision floating point seems to blow up if `sigma > ~200`. */
if (sigma >= 3.556f) {
q = 0.9804f * (sigma - 3.556f) + 2.5091f;
}
@ -158,7 +158,7 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src,
}
q2 = q * q;
sc = (1.1668 + q) * (3.203729649 + (2.21566 + q) * q);
/* No gabor filtering here, so no complex multiplies, just the regular coefs.
/* No gabor filtering here, so no complex multiplies, just the regular coefficients.
* all negated here, so as not to have to recalc Triggs/Sdika matrix. */
cf[1] = q * (5.788961737 + (6.76492 + 3.0 * q) * q) / sc;
cf[2] = -q2 * (3.38246 + 3.0 * q) / sc;
@ -168,7 +168,7 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src,
/* Triggs/Sdika border corrections,
* it seems to work, not entirely sure if it is actually totally correct,
* Besides J.M.Geusebroek's anigauss.c (see http://www.science.uva.nl/~mark),
* Besides J.M.Geusebroek's `anigauss.c` (see http://www.science.uva.nl/~mark),
* found one other implementation by Cristoph Lampert,
* but neither seem to be quite the same, result seems to be ok so far anyway.
* Extra scale factor here to not have to do it in filter,

View File

@ -116,6 +116,18 @@ void MovieClipBaseOperation::executePixelSampled(float output[4],
}
}
void MovieClipBaseOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> UNUSED(inputs))
{
if (m_movieClipBuffer) {
output->copy_from(m_movieClipBuffer, area);
}
else {
output->fill(area, COM_COLOR_TRANSPARENT);
}
}
MovieClipOperation::MovieClipOperation() : MovieClipBaseOperation()
{
this->addOutputSocket(DataType::Color);
@ -136,4 +148,16 @@ void MovieClipAlphaOperation::executePixelSampled(float output[4],
output[0] = result[3];
}
void MovieClipAlphaOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> UNUSED(inputs))
{
if (m_movieClipBuffer) {
output->copy_from(m_movieClipBuffer, area, 3, COM_DATA_TYPE_VALUE_CHANNELS, 0);
}
else {
output->fill(area, COM_VALUE_ZERO);
}
}
} // namespace blender::compositor

View File

@ -19,7 +19,7 @@
#pragma once
#include "BLI_listbase.h"
#include "COM_NodeOperation.h"
#include "COM_MultiThreadedOperation.h"
#include "DNA_movieclip_types.h"
#include "IMB_imbuf_types.h"
@ -28,7 +28,7 @@ namespace blender::compositor {
/**
* Base class for movie clip
*/
class MovieClipBaseOperation : public NodeOperation {
class MovieClipBaseOperation : public MultiThreadedOperation {
protected:
MovieClip *m_movieClip;
MovieClipUser *m_movieClipUser;
@ -67,6 +67,10 @@ class MovieClipBaseOperation : public NodeOperation {
this->m_framenumber = framenumber;
}
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
void update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs) override;
};
class MovieClipOperation : public MovieClipBaseOperation {
@ -78,6 +82,10 @@ class MovieClipAlphaOperation : public MovieClipBaseOperation {
public:
MovieClipAlphaOperation();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
void update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs) override;
};
} // namespace blender::compositor

View File

@ -157,14 +157,8 @@ void TextureBaseOperation::executePixelSampled(float output[4],
m_sceneColorManage,
false);
if (texres.talpha) {
output[3] = texres.ta;
}
else {
output[3] = texres.tin;
}
if ((retval & TEX_RGB)) {
output[3] = texres.talpha ? texres.ta : texres.tin;
if (retval & TEX_RGB) {
output[0] = texres.tr;
output[1] = texres.tg;
output[2] = texres.tb;
@ -174,4 +168,67 @@ void TextureBaseOperation::executePixelSampled(float output[4],
}
}
void TextureBaseOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs)
{
const int op_width = this->getWidth();
const int op_height = this->getHeight();
const float center_x = op_width / 2;
const float center_y = op_height / 2;
TexResult tex_result = {0};
float vec[3];
const int thread_id = WorkScheduler::current_thread_id();
for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
const float *tex_offset = it.in(0);
const float *tex_size = it.in(1);
float u = (it.x - center_x) / op_width * 2;
float v = (it.y - center_y) / op_height * 2;
/* When no interpolation/filtering happens in multitex() force nearest interpolation.
* We do it here because (a) we can't easily say multitex() that we want nearest
* interpolation and (b) in such configuration multitex() simply floor's the value
* which often produces artifacts.
*/
if (m_texture != nullptr && (m_texture->imaflag & TEX_INTERPOL) == 0) {
u += 0.5f / center_x;
v += 0.5f / center_y;
}
vec[0] = tex_size[0] * (u + tex_offset[0]);
vec[1] = tex_size[1] * (v + tex_offset[1]);
vec[2] = tex_size[2] * tex_offset[2];
const int retval = multitex_ext(this->m_texture,
vec,
nullptr,
nullptr,
0,
&tex_result,
thread_id,
m_pool,
m_sceneColorManage,
false);
it.out[3] = tex_result.talpha ? tex_result.ta : tex_result.tin;
if (retval & TEX_RGB) {
it.out[0] = tex_result.tr;
it.out[1] = tex_result.tg;
it.out[2] = tex_result.tb;
}
else {
it.out[0] = it.out[1] = it.out[2] = it.out[3];
}
}
}
void TextureAlphaOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs)
{
MemoryBuffer texture(DataType::Color, area);
TextureBaseOperation::update_memory_buffer_partial(&texture, area, inputs);
output->copy_from(&texture, area, 3, COM_DATA_TYPE_VALUE_CHANNELS, 0);
}
} // namespace blender::compositor

View File

@ -19,7 +19,7 @@
#pragma once
#include "BLI_listbase.h"
#include "COM_NodeOperation.h"
#include "COM_MultiThreadedOperation.h"
#include "DNA_texture_types.h"
#include "MEM_guardedalloc.h"
@ -33,7 +33,7 @@ namespace blender::compositor {
*
* \todo Rename to operation.
*/
class TextureBaseOperation : public NodeOperation {
class TextureBaseOperation : public MultiThreadedOperation {
private:
Tex *m_texture;
const RenderData *m_rd;
@ -71,6 +71,10 @@ class TextureBaseOperation : public NodeOperation {
{
this->m_sceneColorManage = sceneColorManage;
}
void update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs) override;
};
class TextureOperation : public TextureBaseOperation {
@ -81,6 +85,10 @@ class TextureAlphaOperation : public TextureBaseOperation {
public:
TextureAlphaOperation();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
void update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs) override;
};
} // namespace blender::compositor

View File

@ -246,4 +246,17 @@ void ViewerOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(output),
updateImage(&area);
}
void ViewerOperation::clear_display_buffer()
{
BLI_assert(isActiveViewerOutput());
initImage();
size_t buf_bytes = (size_t)m_ibuf->y * m_ibuf->x * COM_DATA_TYPE_COLOR_CHANNELS * sizeof(float);
if (buf_bytes > 0) {
memset(m_outputBuffer, 0, buf_bytes);
rcti display_area;
BLI_rcti_init(&display_area, 0, m_ibuf->x, 0, m_ibuf->y);
updateImage(&display_area);
}
}
} // namespace blender::compositor

View File

@ -131,6 +131,8 @@ class ViewerOperation : public MultiThreadedOperation {
const rcti &area,
Span<MemoryBuffer *> inputs) override;
void clear_display_buffer();
private:
void updateImage(const rcti *rect);
void initImage();

View File

@ -103,7 +103,7 @@ void evaluate_node(const DepsgraphEvalState *state, OperationNode *operation_nod
::Depsgraph *depsgraph = reinterpret_cast<::Depsgraph *>(state->graph);
/* Sanity checks. */
BLI_assert(!operation_node->is_noop() && "NOOP nodes should not actually be scheduled");
BLI_assert_msg(!operation_node->is_noop(), "NOOP nodes should not actually be scheduled");
/* Perform operation. */
if (state->do_stats) {
const double start_time = PIL_check_seconds_timer();

View File

@ -348,7 +348,7 @@ bool scene_copy_inplace_no_main(const Scene *scene, Scene *new_scene)
/* For the given scene get view layer which corresponds to an original for the
* scene's evaluated one. This depends on how the scene is pulled into the
* dependency graph. */
* dependency graph. */
ViewLayer *get_original_view_layer(const Depsgraph *depsgraph, const IDNode *id_node)
{
if (id_node->linked_state == DEG_ID_LINKED_DIRECTLY) {

View File

@ -192,7 +192,7 @@ void EEVEE_subsurface_add_pass(EEVEE_ViewLayerData *sldata,
gpumat, stl->effects->sss_sample_count, &sss_tex_profile);
if (!sss_profile) {
BLI_assert(0 && "SSS pass requested but no SSS data was found");
BLI_assert_msg(0, "SSS pass requested but no SSS data was found");
return;
}

View File

@ -327,7 +327,7 @@ vec2 safe_normalize_len(vec2 v, out float len)
float stroke_thickness_modulate(float thickness)
{
/* Modify stroke thickness by object and layer factors.-*/
/* Modify stroke thickness by object and layer factors. */
thickness *= thicknessScale;
thickness += thicknessOffset;
thickness = max(1.0, thickness);

View File

@ -340,7 +340,7 @@ void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
if (shgroup && geom) {
if (ob->type == OB_POINTCLOUD) {
/* Draw range to avoid drawcall batching messing up the instance attrib. */
/* Draw range to avoid drawcall batching messing up the instance attribute. */
DRW_shgroup_call_instance_range(shgroup, ob, geom, 0, 0);
}
else {

View File

@ -128,7 +128,7 @@ static void workbench_cache_sculpt_populate(WORKBENCH_PrivateData *wpd,
BLI_INLINE void workbench_object_drawcall(DRWShadingGroup *grp, struct GPUBatch *geom, Object *ob)
{
if (ob->type == OB_POINTCLOUD) {
/* Draw range to avoid drawcall batching messing up the instance attrib. */
/* Draw range to avoid drawcall batching messing up the instance attribute. */
DRW_shgroup_call_instance_range(grp, ob, geom, 0, 0);
}
else {

View File

@ -327,7 +327,7 @@ typedef enum {
/** Culling test */
DRW_STATE_CULL_BACK = (1 << 7),
DRW_STATE_CULL_FRONT = (1 << 8),
/** Stencil test . These options are mutually exclusive and packed into 2 bits. */
/** Stencil test. These options are mutually exclusive and packed into 2 bits. */
DRW_STATE_STENCIL_ALWAYS = (1 << 9),
DRW_STATE_STENCIL_EQUAL = (2 << 9),
DRW_STATE_STENCIL_NEQUAL = (3 << 9),

View File

@ -770,9 +770,9 @@ GPUBatch *DRW_cache_normal_arrow_get(void)
}
/* -------------------------------------------------------------------- */
/** \name Dummy vbos
/** \name Dummy VBO's
*
* We need a dummy vbo containing the vertex count to draw instances ranges.
* We need a dummy VBO containing the vertex count to draw instances ranges.
*
* \{ */

View File

@ -81,11 +81,12 @@ typedef enum eMRDataType {
MR_DATA_POLY_NOR = 1 << 1,
MR_DATA_LOOP_NOR = 1 << 2,
MR_DATA_LOOPTRI = 1 << 3,
MR_DATA_LOOSE_GEOM = 1 << 4,
/** Force loop normals calculation. */
MR_DATA_TAN_LOOP_NOR = 1 << 4,
MR_DATA_MAT_OFFSETS = 1 << 5,
MR_DATA_TAN_LOOP_NOR = 1 << 5,
MR_DATA_POLYS_SORTED = 1 << 6,
} eMRDataType;
ENUM_OPERATORS(eMRDataType, MR_DATA_MAT_OFFSETS)
ENUM_OPERATORS(eMRDataType, MR_DATA_POLYS_SORTED)
#ifdef __cplusplus
extern "C" {
@ -169,10 +170,10 @@ typedef struct MeshBufferExtractionCache {
} loose_geom;
struct {
int *tri;
int *tri_first_index;
int *mat_tri_len;
int visible_tri_len;
} mat_offsets;
} poly_sorted;
} MeshBufferExtractionCache;
#define FOREACH_MESH_BUFFER_CACHE(batch_cache, mbc) \

View File

@ -531,7 +531,8 @@ static void mesh_extract_render_data_node_exec(void *__restrict task_data)
mesh_render_data_update_normals(mr, data_flag);
mesh_render_data_update_looptris(mr, iter_type, data_flag);
mesh_render_data_update_mat_offsets(mr, update_task_data->cache, data_flag);
mesh_render_data_update_loose_geom(mr, update_task_data->cache, iter_type, data_flag);
mesh_render_data_update_polys_sorted(mr, update_task_data->cache, data_flag);
}
static struct TaskNode *mesh_extract_render_data_node_create(struct TaskGraph *task_graph,
@ -685,19 +686,8 @@ static void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
double rdata_start = PIL_check_seconds_timer();
#endif
eMRIterType iter_type = extractors.iter_types();
eMRDataType data_flag = extractors.data_types();
MeshRenderData *mr = mesh_render_data_create(me,
extraction_cache,
is_editmode,
is_paint_mode,
is_mode_active,
obmat,
do_final,
do_uvedit,
ts,
iter_type);
MeshRenderData *mr = mesh_render_data_create(
me, is_editmode, is_paint_mode, is_mode_active, obmat, do_final, do_uvedit, ts);
mr->use_hide = use_hide;
mr->use_subsurf_fdots = use_subsurf_fdots;
mr->use_final_mesh = do_final;
@ -706,6 +696,9 @@ static void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
double rdata_end = PIL_check_seconds_timer();
#endif
eMRIterType iter_type = extractors.iter_types();
eMRDataType data_flag = extractors.data_types();
struct TaskNode *task_node_mesh_render_data = mesh_extract_render_data_node_create(
task_graph, mr, extraction_cache, iter_type, data_flag);

View File

@ -101,10 +101,12 @@ typedef struct MeshRenderData {
float (*loop_normals)[3];
float (*poly_normals)[3];
int *lverts, *ledges;
struct {
int *tri;
int *tri_first_index;
int *mat_tri_len;
int visible_tri_len;
} mat_offsets;
} poly_sorted;
} MeshRenderData;
BLI_INLINE BMFace *bm_original_face_get(const MeshRenderData *mr, int idx)
@ -240,20 +242,22 @@ typedef struct MeshExtract {
/* draw_cache_extract_mesh_render_data.c */
MeshRenderData *mesh_render_data_create(Mesh *me,
MeshBufferExtractionCache *cache,
const bool is_editmode,
const bool is_paint_mode,
const bool is_mode_active,
const float obmat[4][4],
const bool do_final,
const bool do_uvedit,
const ToolSettings *ts,
const eMRIterType iter_type);
const ToolSettings *ts);
void mesh_render_data_free(MeshRenderData *mr);
void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_flag);
void mesh_render_data_update_mat_offsets(MeshRenderData *mr,
MeshBufferExtractionCache *cache,
const eMRDataType data_flag);
void mesh_render_data_update_loose_geom(MeshRenderData *mr,
MeshBufferExtractionCache *cache,
const eMRIterType iter_type,
const eMRDataType data_flag);
void mesh_render_data_update_polys_sorted(MeshRenderData *mr,
MeshBufferExtractionCache *cache,
const eMRDataType data_flag);
void mesh_render_data_update_looptris(MeshRenderData *mr,
const eMRIterType iter_type,
const eMRDataType data_flag);

View File

@ -25,6 +25,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_alloca.h"
#include "BLI_bitmap.h"
#include "BLI_math.h"
#include "BLI_task.h"
@ -165,119 +166,118 @@ static void mesh_render_data_ledges_bm(const MeshRenderData *mr,
}
}
void mesh_render_data_update_loose_geom(MeshRenderData *mr,
MeshBufferExtractionCache *cache,
const eMRIterType iter_type,
const eMRDataType data_flag)
{
if ((iter_type & (MR_ITER_LEDGE | MR_ITER_LVERT)) || (data_flag & MR_DATA_LOOSE_GEOM)) {
mesh_render_data_loose_geom_ensure(mr, cache);
mesh_render_data_loose_geom_load(mr, cache);
}
}
/** \} */
/* ---------------------------------------------------------------------- */
/** \name Material Offsets
/** \name Polygons sorted per material
*
* Material offsets contains the offset of a material after sorting tris based on their material.
* Contains polygon indices sorted based on their material.
*
* \{ */
static void mesh_render_data_mat_offset_load(MeshRenderData *mr,
const MeshBufferExtractionCache *cache);
static void mesh_render_data_mat_offset_ensure(MeshRenderData *mr,
MeshBufferExtractionCache *cache);
static void mesh_render_data_mat_offset_build(MeshRenderData *mr,
MeshBufferExtractionCache *cache);
static void mesh_render_data_mat_offset_build_bm(MeshRenderData *mr,
static void mesh_render_data_polys_sorted_load(MeshRenderData *mr,
const MeshBufferExtractionCache *cache);
static void mesh_render_data_polys_sorted_ensure(MeshRenderData *mr,
MeshBufferExtractionCache *cache);
static void mesh_render_data_mat_offset_build_mesh(MeshRenderData *mr,
MeshBufferExtractionCache *cache);
static void mesh_render_data_mat_offset_apply_offset(MeshRenderData *mr,
MeshBufferExtractionCache *cache);
static void mesh_render_data_polys_sorted_build(MeshRenderData *mr,
MeshBufferExtractionCache *cache);
static int *mesh_render_data_mat_tri_len_build(MeshRenderData *mr);
void mesh_render_data_update_mat_offsets(MeshRenderData *mr,
MeshBufferExtractionCache *cache,
const eMRDataType data_flag)
void mesh_render_data_update_polys_sorted(MeshRenderData *mr,
MeshBufferExtractionCache *cache,
const eMRDataType data_flag)
{
if (data_flag & MR_DATA_MAT_OFFSETS) {
mesh_render_data_mat_offset_ensure(mr, cache);
mesh_render_data_mat_offset_load(mr, cache);
if (data_flag & MR_DATA_POLYS_SORTED) {
mesh_render_data_polys_sorted_ensure(mr, cache);
mesh_render_data_polys_sorted_load(mr, cache);
}
}
static void mesh_render_data_mat_offset_load(MeshRenderData *mr,
const MeshBufferExtractionCache *cache)
static void mesh_render_data_polys_sorted_load(MeshRenderData *mr,
const MeshBufferExtractionCache *cache)
{
mr->mat_offsets.tri = cache->mat_offsets.tri;
mr->mat_offsets.visible_tri_len = cache->mat_offsets.visible_tri_len;
mr->poly_sorted.tri_first_index = cache->poly_sorted.tri_first_index;
mr->poly_sorted.mat_tri_len = cache->poly_sorted.mat_tri_len;
mr->poly_sorted.visible_tri_len = cache->poly_sorted.visible_tri_len;
}
static void mesh_render_data_mat_offset_ensure(MeshRenderData *mr,
MeshBufferExtractionCache *cache)
static void mesh_render_data_polys_sorted_ensure(MeshRenderData *mr,
MeshBufferExtractionCache *cache)
{
if (cache->mat_offsets.tri) {
if (cache->poly_sorted.tri_first_index) {
return;
}
mesh_render_data_mat_offset_build(mr, cache);
mesh_render_data_polys_sorted_build(mr, cache);
}
static void mesh_render_data_mat_offset_build(MeshRenderData *mr, MeshBufferExtractionCache *cache)
static void mesh_render_data_polys_sorted_build(MeshRenderData *mr,
MeshBufferExtractionCache *cache)
{
size_t mat_tri_idx_size = sizeof(int) * mr->mat_len;
cache->mat_offsets.tri = MEM_callocN(mat_tri_idx_size, __func__);
int *tri_first_index = MEM_mallocN(sizeof(*tri_first_index) * mr->poly_len, __func__);
int *mat_tri_len = mesh_render_data_mat_tri_len_build(mr);
/* Count how many triangles for each material. */
/* Apply offset. */
int visible_tri_len = 0;
int *mat_tri_offs = BLI_array_alloca(mat_tri_offs, mr->mat_len);
{
for (int i = 0; i < mr->mat_len; i++) {
mat_tri_offs[i] = visible_tri_len;
visible_tri_len += mat_tri_len[i];
}
}
/* Sort per material. */
int mat_last = mr->mat_len - 1;
if (mr->extract_type == MR_EXTRACT_BMESH) {
mesh_render_data_mat_offset_build_bm(mr, cache);
BMIter iter;
BMFace *f;
int i;
BM_ITER_MESH_INDEX (f, &iter, mr->bm, BM_FACES_OF_MESH, i) {
if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
const int mat = min_ii(f->mat_nr, mat_last);
tri_first_index[i] = mat_tri_offs[mat];
mat_tri_offs[mat] += f->len - 2;
}
else {
tri_first_index[i] = -1;
}
}
}
else {
mesh_render_data_mat_offset_build_mesh(mr, cache);
const MPoly *mp = &mr->mpoly[0];
for (int i = 0; i < mr->poly_len; i++, mp++) {
if (!(mr->use_hide && (mp->flag & ME_HIDE))) {
const int mat = min_ii(mp->mat_nr, mat_last);
tri_first_index[i] = mat_tri_offs[mat];
mat_tri_offs[mat] += mp->totloop - 2;
}
else {
tri_first_index[i] = -1;
}
}
}
mesh_render_data_mat_offset_apply_offset(mr, cache);
cache->poly_sorted.tri_first_index = tri_first_index;
cache->poly_sorted.mat_tri_len = mat_tri_len;
cache->poly_sorted.visible_tri_len = visible_tri_len;
}
typedef struct MatOffsetUserData {
MeshRenderData *mr;
/** This struct is extended during allocation to hold mat_tri_len for each material. */
int mat_tri_len[0];
} MatOffsetUserData;
static void mesh_render_data_mat_offset_reduce(const void *__restrict UNUSED(userdata),
void *__restrict chunk_join,
void *__restrict chunk)
static void mesh_render_data_mat_tri_len_bm_range_fn(void *__restrict userdata,
const int iter,
const TaskParallelTLS *__restrict tls)
{
MatOffsetUserData *dst = chunk_join;
MatOffsetUserData *src = chunk;
int *dst_mat_len = dst->mat_tri_len;
int *src_mat_len = src->mat_tri_len;
for (int i = 0; i < dst->mr->mat_len; i++) {
dst_mat_len[i] += src_mat_len[i];
}
}
static void mesh_render_data_mat_offset_build_threaded(MeshRenderData *mr,
MeshBufferExtractionCache *cache,
int face_len,
TaskParallelRangeFunc range_func)
{
/* Extending the #MatOffsetUserData with an int per material slot. */
size_t userdata_size = sizeof(MatOffsetUserData) +
(mr->mat_len) * sizeof(*cache->mat_offsets.tri);
MatOffsetUserData *userdata = MEM_callocN(userdata_size, __func__);
userdata->mr = mr;
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.userdata_chunk = userdata;
settings.userdata_chunk_size = userdata_size;
settings.min_iter_per_thread = MIN_RANGE_LEN;
settings.func_reduce = mesh_render_data_mat_offset_reduce;
BLI_task_parallel_range(0, face_len, NULL, range_func, &settings);
memcpy(cache->mat_offsets.tri,
&userdata->mat_tri_len,
(mr->mat_len) * sizeof(*cache->mat_offsets.tri));
MEM_freeN(userdata);
}
static void mesh_render_data_mat_offset_bm_range(void *__restrict UNUSED(userdata),
const int iter,
const TaskParallelTLS *__restrict tls)
{
MatOffsetUserData *mat_offset_userdata = tls->userdata_chunk;
MeshRenderData *mr = mat_offset_userdata->mr;
int *mat_tri_len = mat_offset_userdata->mat_tri_len;
MeshRenderData *mr = userdata;
int *mat_tri_len = tls->userdata_chunk;
BMesh *bm = mr->bm;
BMFace *efa = BM_face_at_index(bm, iter);
@ -287,21 +287,12 @@ static void mesh_render_data_mat_offset_bm_range(void *__restrict UNUSED(userdat
}
}
static void mesh_render_data_mat_offset_build_bm(MeshRenderData *mr,
MeshBufferExtractionCache *cache)
static void mesh_render_data_mat_tri_len_mesh_range_fn(void *__restrict userdata,
const int iter,
const TaskParallelTLS *__restrict tls)
{
BMesh *bm = mr->bm;
mesh_render_data_mat_offset_build_threaded(
mr, cache, bm->totface, mesh_render_data_mat_offset_bm_range);
}
static void mesh_render_data_mat_offset_mesh_range(void *__restrict UNUSED(userdata),
const int iter,
const TaskParallelTLS *__restrict tls)
{
MatOffsetUserData *mat_offset_userdata = tls->userdata_chunk;
const MeshRenderData *mr = mat_offset_userdata->mr;
int *mat_tri_len = mat_offset_userdata->mat_tri_len;
MeshRenderData *mr = userdata;
int *mat_tri_len = tls->userdata_chunk;
const MPoly *mp = &mr->mpoly[iter];
if (!(mr->use_hide && (mp->flag & ME_HIDE))) {
@ -310,25 +301,49 @@ static void mesh_render_data_mat_offset_mesh_range(void *__restrict UNUSED(userd
}
}
static void mesh_render_data_mat_offset_build_mesh(MeshRenderData *mr,
MeshBufferExtractionCache *cache)
static void mesh_render_data_mat_tri_len_reduce_fn(const void *__restrict userdata,
void *__restrict chunk_join,
void *__restrict chunk)
{
mesh_render_data_mat_offset_build_threaded(
mr, cache, mr->poly_len, mesh_render_data_mat_offset_mesh_range);
const MeshRenderData *mr = userdata;
int *dst_mat_len = chunk_join;
int *src_mat_len = chunk;
for (int i = 0; i < mr->mat_len; i++) {
dst_mat_len[i] += src_mat_len[i];
}
}
static void mesh_render_data_mat_offset_apply_offset(MeshRenderData *mr,
MeshBufferExtractionCache *cache)
static int *mesh_render_data_mat_tri_len_build_threaded(MeshRenderData *mr,
int face_len,
TaskParallelRangeFunc range_func)
{
int *mat_tri_len = cache->mat_offsets.tri;
int ofs = mat_tri_len[0];
mat_tri_len[0] = 0;
for (int i = 1; i < mr->mat_len; i++) {
int tmp = mat_tri_len[i];
mat_tri_len[i] = ofs;
ofs += tmp;
/* Extending the #MatOffsetUserData with an int per material slot. */
size_t mat_tri_len_size = sizeof(int) * mr->mat_len;
int *mat_tri_len = MEM_callocN(mat_tri_len_size, __func__);
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.userdata_chunk = mat_tri_len;
settings.userdata_chunk_size = mat_tri_len_size;
settings.min_iter_per_thread = MIN_RANGE_LEN;
settings.func_reduce = mesh_render_data_mat_tri_len_reduce_fn;
BLI_task_parallel_range(0, face_len, mr, range_func, &settings);
return mat_tri_len;
}
/* Count how many triangles for each material. */
static int *mesh_render_data_mat_tri_len_build(MeshRenderData *mr)
{
if (mr->extract_type == MR_EXTRACT_BMESH) {
BMesh *bm = mr->bm;
return mesh_render_data_mat_tri_len_build_threaded(
mr, bm->totface, mesh_render_data_mat_tri_len_bm_range_fn);
}
else {
return mesh_render_data_mat_tri_len_build_threaded(
mr, mr->poly_len, mesh_render_data_mat_tri_len_mesh_range_fn);
}
cache->mat_offsets.visible_tri_len = ofs;
}
/** \} */
@ -447,15 +462,13 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_
* otherwise don't use modifiers as they are not from this object.
*/
MeshRenderData *mesh_render_data_create(Mesh *me,
MeshBufferExtractionCache *cache,
const bool is_editmode,
const bool is_paint_mode,
const bool is_mode_active,
const float obmat[4][4],
const bool do_final,
const bool do_uvedit,
const ToolSettings *ts,
const eMRIterType iter_type)
const ToolSettings *ts)
{
MeshRenderData *mr = MEM_callocN(sizeof(*mr), __func__);
mr->toolsettings = ts;
@ -565,11 +578,6 @@ MeshRenderData *mesh_render_data_create(Mesh *me,
mr->tri_len = poly_to_tri_count(mr->poly_len, mr->loop_len);
}
if (iter_type & (MR_ITER_LEDGE | MR_ITER_LVERT)) {
mesh_render_data_loose_geom_ensure(mr, cache);
mesh_render_data_loose_geom_load(mr, cache);
}
return mr;
}

View File

@ -663,7 +663,7 @@ static void curve_create_curves_lines(CurveRenderData *rdata, GPUIndexBuf *ibo_c
for (const int i_spline : splines.index_range()) {
const int eval_size = splines[i_spline]->evaluated_points_size();
if (splines[i_spline]->is_cyclic()) {
if (splines[i_spline]->is_cyclic() && splines[i_spline]->evaluated_edges_size() > 1) {
GPU_indexbuf_add_generic_vert(&elb, offsets[i_spline] + eval_size - 1);
}
for (const int i_point : IndexRange(eval_size)) {

View File

@ -856,7 +856,9 @@ static void mesh_buffer_extraction_cache_clear(MeshBufferExtractionCache *extrac
extraction_cache->loose_geom.edge_len = 0;
extraction_cache->loose_geom.vert_len = 0;
MEM_SAFE_FREE(extraction_cache->mat_offsets.tri);
MEM_SAFE_FREE(extraction_cache->poly_sorted.tri_first_index);
MEM_SAFE_FREE(extraction_cache->poly_sorted.mat_tri_len);
extraction_cache->poly_sorted.visible_tri_len = 0;
}
static void mesh_batch_cache_clear(Mesh *me)

View File

@ -80,7 +80,7 @@ typedef struct DRWTempInstancingHandle {
GPUBatch *batch;
/** Batch containing instancing attributes. */
GPUBatch *instancer;
/** Callbuffer to be used instead of instancer . */
/** Callbuffer to be used instead of instancer. */
GPUVertBuf *buf;
/** Original non-instanced batch pointer. */
GPUBatch *geom;

View File

@ -147,7 +147,7 @@ static bool drw_draw_show_annotation(void)
* the draw manager is only used to draw the background. */
return false;
default:
BLI_assert("");
BLI_assert(0);
return false;
}
}
@ -2253,7 +2253,7 @@ static void draw_select_framebuffer_depth_only_setup(const int size[2])
/* Must run after all instance datas have been added. */
void DRW_render_instance_buffer_finish(void)
{
BLI_assert(!DST.buffer_finish_called && "DRW_render_instance_buffer_finish called twice!");
BLI_assert_msg(!DST.buffer_finish_called, "DRW_render_instance_buffer_finish called twice!");
DST.buffer_finish_called = true;
DRW_instance_buffer_finish(DST.idatalist);
drw_resource_buffer_finish(DST.vmempool);

View File

@ -74,7 +74,7 @@ static void draw_call_sort(DRWCommand *array, DRWCommand *array_tmp, int array_l
return;
}
}
/* Cumulate batch indices */
/* Accumulate batch indices */
for (int i = 1; i < ARRAY_SIZE(idx); i++) {
idx[i] += idx[i - 1];
}
@ -453,7 +453,7 @@ void DRW_shgroup_vertex_buffer(DRWShadingGroup *shgroup,
{
int location = GPU_shader_get_ssbo(shgroup->shader, name);
if (location == -1) {
BLI_assert(false && "Unable to locate binding of shader storage buffer objects.");
BLI_assert_msg(0, "Unable to locate binding of shader storage buffer objects.");
return;
}
drw_shgroup_uniform_create_ex(

View File

@ -266,7 +266,7 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
}
const short edge_tex_sep = (short)((edge_tex_count - 1) * 5.0f * U.dpi_fac);
/* make the precision of the display value proportionate to the gridsize */
/* Make the precision of the display value proportionate to the grid-size. */
if (grid <= 0.01f) {
conv_float = "%.6g";

View File

@ -237,7 +237,7 @@ constexpr MeshExtract create_extractor_lines_loose_only()
{
MeshExtract extractor = {nullptr};
extractor.init = extract_lines_loose_only_init;
extractor.data_type = MR_DATA_NONE;
extractor.data_type = MR_DATA_LOOSE_GEOM;
extractor.data_size = 0;
extractor.use_threading = false;
extractor.mesh_buffer_offset = offsetof(MeshBufferCache, ibo.lines_loose);

Some files were not shown because too many files have changed in this diff Show More