Merge branch 'master' into sculpt-dev

This commit is contained in:
Pablo Dobarro 2021-08-02 21:35:31 +02:00
commit b2dc8bd92e
72 changed files with 896 additions and 1430 deletions

View File

@ -251,6 +251,16 @@ if(WITH_GHOST_X11)
option(WITH_X11_ALPHA "Enable X11 transparent background" ON)
endif()
if(UNIX AND NOT APPLE)
option(WITH_SYSTEM_GLEW "Use GLEW OpenGL wrapper library provided by the operating system" OFF)
option(WITH_SYSTEM_GLES "Use OpenGL ES library provided by the operating system" ON)
else()
# not an option for other OS's
set(WITH_SYSTEM_GLEW OFF)
set(WITH_SYSTEM_GLES OFF)
endif()
if(UNIX AND NOT APPLE)
option(WITH_SYSTEM_EIGEN3 "Use the systems Eigen3 library" OFF)
endif()
@ -475,32 +485,15 @@ endif()
# OpenGL
if(UNIX AND NOT APPLE)
# GLEW can only built with either GLX or EGL support and most binary
# distributions are built with GLX support. So we always compile GLEW
# with EGL support manually, and the options are no longer available.
set(WITH_SYSTEM_GLEW OFF)
set(WITH_SYSTEM_GLES ON)
# Always use EGL instead of GLX, for X11, Wayland and headless.
set(WITH_GL_EGL ON)
else()
# System GLEW and GLES were never an option on other platforms.
set(WITH_SYSTEM_GLEW OFF)
set(WITH_SYSTEM_GLES OFF)
# Experimental EGL option.
option(WITH_GL_EGL "Use the EGL OpenGL system library instead of the platform specific OpenGL system library (CGL or WGL)" OFF)
mark_as_advanced(WITH_GL_EGL)
endif()
option(WITH_OPENGL "When off limits visibility of the opengl headers to just bf_gpu and gawain (temporary option for development purposes)" ON)
option(WITH_GLEW_ES "Switches to experimental copy of GLEW that has support for OpenGL ES. (temporary option for development purposes)" OFF)
option(WITH_GL_EGL "Use the EGL OpenGL system library instead of the platform specific OpenGL system library (CGL, glX, or WGL)" OFF)
option(WITH_GL_PROFILE_ES20 "Support using OpenGL ES 2.0. (through either EGL or the AGL/WGL/XGL 'es20' profile)" OFF)
mark_as_advanced(
WITH_OPENGL
WITH_GLEW_ES
WITH_GL_EGL
WITH_GL_PROFILE_ES20
)

View File

@ -603,6 +603,9 @@ MP3LAME_DEV=""
OPENJPEG_USE=false
OPENJPEG_DEV=""
# Whether to use system GLEW or not (OpenSubDiv needs recent glew to work).
NO_SYSTEM_GLEW=false
# Switch to english language, else some things (like check_package_DEB()) won't work!
LANG_BACK=$LANG
LANG=""
@ -3982,9 +3985,13 @@ install_DEB() {
version_ge $_glew "1.7.0"
if [ $? -eq 1 ]; then
WARNING "OpenSubdiv disabled because GLEW-$_glew is not enough"
WARNING "Blender will not use system GLEW library"
OSD_SKIP=true
NO_SYSTEM_GLEW=true
else
WARNING "OpenSubdiv will compile with GLEW-$_glew but with limited capability"
WARNING "Blender will not use system GLEW library"
NO_SYSTEM_GLEW=true
fi
fi
@ -5955,6 +5962,12 @@ print_info() {
fi
fi
if [ "$NO_SYSTEM_GLEW" = true ]; then
_1="-D WITH_SYSTEM_GLEW=OFF"
PRINT " $_1"
_buildargs="$_buildargs $_1"
fi
if [ "$FFMPEG_SKIP" = false ]; then
_1="-D WITH_CODEC_FFMPEG=ON"
_2="-D FFMPEG_LIBRARIES='avformat;avcodec;avutil;avdevice;swscale;swresample;lzma;rt;`print_info_ffmpeglink`'"

View File

@ -581,6 +581,8 @@ if(WITH_GHOST_WAYLAND)
pkg_check_modules(wayland-cursor REQUIRED wayland-cursor)
pkg_check_modules(dbus REQUIRED dbus-1)
set(WITH_GL_EGL ON)
list(APPEND PLATFORM_LINKLIBS
${wayland-client_LINK_LIBRARIES}
${wayland-egl_LINK_LIBRARIES}

View File

@ -1,11 +1,10 @@
Pipeline Config
===============
This configuration file is used by buildbot new build pipeline for the `update-code` step.
The `yaml` configuration file is used by buildbot build pipeline `update-code` step.
It will also be used by the `../utils/make_update.py` script in the near future.
The file allows to set branches or specific commits for both git submodules and svn artifacts. Can also define various build package versions for use by build workers. Especially useful in experimental and release branches.
NOTES:
* Keep both `yaml` and `json` files in sync until deployment of build pipeline updates.
* The `json` file be removed once all branches are running with the `yaml` file.
* Expected buildbot pipeline update is *Friday, July 30th* or *Monday August, 2nd*.
NOTE:
* The configuration file is ```NOT``` used by the `../utils/make_update.py` script.
* That will implemented in the future.

View File

@ -1,87 +0,0 @@
{
"update-code":
{
"git" :
{
"submodules":
[
{ "path": "release/scripts/addons", "branch": "master", "commit_id": "HEAD" },
{ "path": "release/scripts/addons_contrib", "branch": "master", "commit_id": "HEAD" },
{ "path": "release/datafiles/locale", "branch": "master", "commit_id": "HEAD" },
{ "path": "source/tools", "branch": "master", "commit_id": "HEAD" }
]
},
"svn":
{
"tests": { "path": "lib/tests", "branch": "trunk", "commit_id": "HEAD" },
"libraries":
{
"darwin-x86_64": { "path": "lib/darwin", "branch": "trunk", "commit_id": "HEAD" },
"darwin-arm64": { "path": "lib/darwin_arm64", "branch": "trunk", "commit_id": "HEAD" },
"linux-x86_64": { "path": "lib/linux_centos7_x86_64", "branch": "trunk", "commit_id": "HEAD" },
"windows-amd64": { "path": "lib/win64_vc15", "branch": "trunk", "commit_id": "HEAD" }
}
}
},
"buildbot":
{
"gcc":
{
"version": "9.0"
},
"sdks":
{
"optix":
{
"version": "7.1.0"
},
"cuda10":
{
"version": "10.1"
},
"cuda11":
{
"version": "11.4"
}
},
"cmake":
{
"default":
{
"version": "any",
"overrides":
{
}
},
"darwin-x86_64":
{
"overrides":
{
}
},
"darwin-arm64":
{
"overrides":
{
}
},
"linux-x86_64":
{
"overrides":
{
}
},
"windows-amd64":
{
"overrides":
{
}
}
}
}
}

View File

@ -34,6 +34,8 @@ GHOST_ImeWin32::GHOST_ImeWin32()
: is_composing_(false),
ime_status_(false),
input_language_id_(LANG_USER_DEFAULT),
conversion_modes_(IME_CMODE_ALPHANUMERIC),
sentence_mode_(IME_SMODE_NONE),
system_caret_(false),
caret_rect_(-1, -1, 0, 0),
is_first(true),
@ -59,6 +61,63 @@ bool GHOST_ImeWin32::SetInputLanguage()
return ime_status_;
}
WORD GHOST_ImeWin32::GetInputLanguage()
{
return input_language_id_;
}
void GHOST_ImeWin32::UpdateConversionStatus(HWND window_handle)
{
HIMC imm_context = ::ImmGetContext(window_handle);
if (imm_context) {
if (::ImmGetOpenStatus(imm_context)) {
::ImmGetConversionStatus(imm_context, &conversion_modes_, &sentence_mode_);
}
else {
conversion_modes_ = IME_CMODE_ALPHANUMERIC;
sentence_mode_ = IME_SMODE_NONE;
}
::ImmReleaseContext(window_handle, imm_context);
}
else {
conversion_modes_ = IME_CMODE_ALPHANUMERIC;
sentence_mode_ = IME_SMODE_NONE;
}
}
bool GHOST_ImeWin32::IsEnglishMode()
{
return (conversion_modes_ & IME_CMODE_NOCONVERSION) ||
!(conversion_modes_ & (IME_CMODE_NATIVE | IME_CMODE_FULLSHAPE));
}
bool GHOST_ImeWin32::IsImeKeyEvent(char ascii)
{
if (!(IsEnglishMode())) {
/* In Chinese, Japanese, Korean, all alpha keys are processed by IME. */
if ((ascii >= 'A' && ascii <= 'Z') || (ascii >= 'a' && ascii <= 'z')) {
return true;
}
switch (PRIMARYLANGID(GetInputLanguage())) {
/* In Japanese, all symbolic characters are also processed by IME. */
case LANG_JAPANESE: {
if (ascii >= ' ' && ascii <= '~') {
return true;
}
break;
}
/* In Chinese, some symbolic characters are also processed by IME. */
case LANG_CHINESE: {
if (ascii && strchr("!\"$'(),.:;<>?[\\]^_`", ascii)) {
return true;
}
break;
}
}
}
return false;
}
void GHOST_ImeWin32::CreateImeWindow(HWND window_handle)
{
/**

View File

@ -156,6 +156,18 @@ class GHOST_ImeWin32 {
*/
bool SetInputLanguage();
/* Returns the current input language id. */
WORD GetInputLanguage();
/* Saves the current conversion status. */
void UpdateConversionStatus(HWND window_handle);
/* Is the IME currently in conversion mode? */
bool IsEnglishMode();
/* Checks a key whether IME has to do handling. */
bool IsImeKeyEvent(char ascii);
/**
* Create the IME windows, and allocate required resources for them.
* Parameters
@ -371,6 +383,12 @@ class GHOST_ImeWin32 {
*/
LANGID input_language_id_;
/* Current Conversion Mode Values. Retrieved with ImmGetConversionStatus. */
DWORD conversion_modes_;
/* Current Sentence Mode. Retrieved with ImmGetConversionStatus. */
DWORD sentence_mode_;
/**
* Represents whether or not the current input context has created a system
* caret to set the position of its IME candidate window.

View File

@ -1219,6 +1219,12 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA
ascii = utf8_char[0] & 0x80 ? '?' : utf8_char[0];
}
#ifdef WITH_INPUT_IME
if (window->getImeInput()->IsImeKeyEvent(ascii)) {
return NULL;
}
#endif /* WITH_INPUT_IME */
event = new GHOST_EventKey(system->getMilliSeconds(),
keyDown ? GHOST_kEventKeyDown : GHOST_kEventKeyUp,
window,
@ -1419,6 +1425,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
system->handleKeyboardChange();
#ifdef WITH_INPUT_IME
window->getImeInput()->SetInputLanguage();
window->getImeInput()->UpdateConversionStatus(hwnd);
#endif
break;
}
@ -1455,6 +1462,13 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
////////////////////////////////////////////////////////////////////////
// IME events, processed, read more in GHOST_IME.h
////////////////////////////////////////////////////////////////////////
case WM_IME_NOTIFY: {
/* Update conversion status when IME is changed or input mode is changed. */
if (wParam == IMN_SETOPENSTATUS || wParam == IMN_SETCONVERSIONMODE) {
window->getImeInput()->UpdateConversionStatus(hwnd);
}
break;
}
case WM_IME_SETCONTEXT: {
GHOST_ImeWin32 *ime = window->getImeInput();
ime->SetInputLanguage();
@ -1466,8 +1480,6 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
case WM_IME_STARTCOMPOSITION: {
GHOST_ImeWin32 *ime = window->getImeInput();
eventHandled = true;
/* remove input event before start comp event, avoid redundant input */
eventManager->removeTypeEvents(GHOST_kEventKeyDown, window);
ime->CreateImeWindow(hwnd);
ime->ResetComposition(hwnd);
event = processImeEvent(GHOST_kEventImeCompositionStart, window, &ime->eventImeData);

View File

@ -20,7 +20,6 @@
set(INC
.
intern
../guardedalloc
)
@ -42,14 +41,7 @@ if(WITH_OPENVDB)
)
list(APPEND SRC
intern/openvdb_level_set.cc
intern/openvdb_transform.cc
openvdb_capi.cc
openvdb_util.cc
intern/openvdb_level_set.h
intern/openvdb_transform.h
openvdb_util.h
)
list(APPEND LIB

View File

@ -1,173 +0,0 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2015 Blender Foundation.
* All rights reserved.
*/
#include "openvdb_level_set.h"
#include "MEM_guardedalloc.h"
#include "openvdb/tools/Composite.h"
#include "openvdb_capi.h"
#include "openvdb_util.h"
OpenVDBLevelSet::OpenVDBLevelSet()
{
openvdb::initialize();
}
OpenVDBLevelSet::~OpenVDBLevelSet()
{
}
void OpenVDBLevelSet::mesh_to_level_set(const float *vertices,
const int *faces,
const int totvertices,
const int totfaces,
const openvdb::math::Transform::Ptr &xform)
{
std::vector<openvdb::Vec3s> points(totvertices);
std::vector<openvdb::Vec3I> triangles(totfaces);
std::vector<openvdb::Vec4I> quads;
for (int i = 0; i < totvertices; i++) {
points[i] = openvdb::Vec3s(vertices[i * 3], vertices[i * 3 + 1], vertices[i * 3 + 2]);
}
for (int i = 0; i < totfaces; i++) {
triangles[i] = openvdb::Vec3I(faces[i * 3], faces[i * 3 + 1], faces[i * 3 + 2]);
}
this->grid = openvdb::tools::meshToLevelSet<openvdb::FloatGrid>(
*xform, points, triangles, quads, 1);
}
void OpenVDBLevelSet::volume_to_mesh(OpenVDBVolumeToMeshData *mesh,
const double isovalue,
const double adaptivity,
const bool relax_disoriented_triangles)
{
std::vector<openvdb::Vec3s> out_points;
std::vector<openvdb::Vec4I> out_quads;
std::vector<openvdb::Vec3I> out_tris;
openvdb::tools::volumeToMesh<openvdb::FloatGrid>(*this->grid,
out_points,
out_tris,
out_quads,
isovalue,
adaptivity,
relax_disoriented_triangles);
mesh->vertices = (float *)MEM_malloc_arrayN(out_points.size(), sizeof(float[3]), __func__);
mesh->quads = (int *)MEM_malloc_arrayN(out_quads.size(), sizeof(int[4]), __func__);
mesh->triangles = NULL;
if (out_tris.size() > 0) {
mesh->triangles = (int *)MEM_malloc_arrayN(out_tris.size(), sizeof(int[3]), __func__);
}
mesh->totvertices = out_points.size();
mesh->tottriangles = out_tris.size();
mesh->totquads = out_quads.size();
for (size_t i = 0; i < out_points.size(); i++) {
mesh->vertices[i * 3] = out_points[i].x();
mesh->vertices[i * 3 + 1] = out_points[i].y();
mesh->vertices[i * 3 + 2] = out_points[i].z();
}
for (size_t i = 0; i < out_quads.size(); i++) {
mesh->quads[i * 4] = out_quads[i].x();
mesh->quads[i * 4 + 1] = out_quads[i].y();
mesh->quads[i * 4 + 2] = out_quads[i].z();
mesh->quads[i * 4 + 3] = out_quads[i].w();
}
for (size_t i = 0; i < out_tris.size(); i++) {
mesh->triangles[i * 3] = out_tris[i].x();
mesh->triangles[i * 3 + 1] = out_tris[i].y();
mesh->triangles[i * 3 + 2] = out_tris[i].z();
}
}
void OpenVDBLevelSet::filter(OpenVDBLevelSet_FilterType filter_type,
int width,
float distance,
OpenVDBLevelSet_FilterBias filter_bias)
{
if (!this->grid) {
return;
}
if (this->grid->getGridClass() != openvdb::GRID_LEVEL_SET) {
return;
}
openvdb::tools::LevelSetFilter<openvdb::FloatGrid> filter(*this->grid);
filter.setSpatialScheme((openvdb::math::BiasedGradientScheme)filter_bias);
switch (filter_type) {
case OPENVDB_LEVELSET_FILTER_GAUSSIAN:
filter.gaussian(width);
break;
case OPENVDB_LEVELSET_FILTER_MEDIAN:
filter.median(width);
break;
case OPENVDB_LEVELSET_FILTER_MEAN:
filter.mean(width);
break;
case OPENVDB_LEVELSET_FILTER_MEAN_CURVATURE:
filter.meanCurvature();
break;
case OPENVDB_LEVELSET_FILTER_LAPLACIAN:
filter.laplacian();
break;
case OPENVDB_LEVELSET_FILTER_DILATE:
filter.offset(distance);
break;
case OPENVDB_LEVELSET_FILTER_ERODE:
filter.offset(distance);
break;
case OPENVDB_LEVELSET_FILTER_NONE:
break;
}
}
openvdb::FloatGrid::Ptr OpenVDBLevelSet::CSG_operation_apply(
const openvdb::FloatGrid::Ptr &gridA,
const openvdb::FloatGrid::Ptr &gridB,
OpenVDBLevelSet_CSGOperation operation)
{
switch (operation) {
case OPENVDB_LEVELSET_CSG_UNION:
openvdb::tools::csgUnion(*gridA, *gridB);
break;
case OPENVDB_LEVELSET_CSG_DIFFERENCE:
openvdb::tools::csgDifference(*gridA, *gridB);
break;
case OPENVDB_LEVELSET_CSG_INTERSECTION:
openvdb::tools::csgIntersection(*gridA, *gridB);
break;
}
return gridA;
}
const openvdb::FloatGrid::Ptr &OpenVDBLevelSet::get_grid()
{
return this->grid;
}
void OpenVDBLevelSet::set_grid(const openvdb::FloatGrid::Ptr &grid)
{
this->grid = grid;
}

View File

@ -1,60 +0,0 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2015 Blender Foundation.
* All rights reserved.
*/
#ifndef __OPENVDB_LEVEL_SET_H__
#define __OPENVDB_LEVEL_SET_H__
#include "openvdb_capi.h"
#include <openvdb/math/FiniteDifference.h>
#include <openvdb/openvdb.h>
#include <openvdb/tools/GridTransformer.h>
#include <openvdb/tools/LevelSetFilter.h>
#include <openvdb/tools/MeshToVolume.h>
#include <openvdb/tools/VolumeToMesh.h>
struct OpenVDBLevelSet {
private:
openvdb::FloatGrid::Ptr grid;
public:
OpenVDBLevelSet();
~OpenVDBLevelSet();
const openvdb::FloatGrid::Ptr &get_grid();
void set_grid(const openvdb::FloatGrid::Ptr &grid);
void mesh_to_level_set(const float *vertices,
const int *faces,
const int totvertices,
const int totfaces,
const openvdb::math::Transform::Ptr &transform);
void volume_to_mesh(struct OpenVDBVolumeToMeshData *mesh,
const double isovalue,
const double adaptivity,
const bool relax_disoriented_triangles);
void filter(OpenVDBLevelSet_FilterType filter_type,
int width,
float distance,
OpenVDBLevelSet_FilterBias filter_bias);
openvdb::FloatGrid::Ptr CSG_operation_apply(const openvdb::FloatGrid::Ptr &gridA,
const openvdb::FloatGrid::Ptr &gridB,
OpenVDBLevelSet_CSGOperation operation);
};
#endif /* __OPENVDB_LEVEL_SET_H__ */

View File

@ -1,43 +0,0 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2015 Blender Foundation.
* All rights reserved.
*/
#include "openvdb_transform.h"
OpenVDBTransform::OpenVDBTransform()
{
}
OpenVDBTransform::~OpenVDBTransform()
{
}
void OpenVDBTransform::create_linear_transform(double voxel_size)
{
this->transform = openvdb::math::Transform::createLinearTransform(voxel_size);
}
const openvdb::math::Transform::Ptr &OpenVDBTransform::get_transform()
{
return this->transform;
}
void OpenVDBTransform::set_transform(const openvdb::math::Transform::Ptr &transform)
{
this->transform = transform;
}

View File

@ -1,37 +0,0 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2015 Blender Foundation.
* All rights reserved.
*/
#ifndef OPENVDB_TRANSFORM_H
#define OPENVDB_TRANSFORM_H
#include <openvdb/openvdb.h>
struct OpenVDBTransform {
private:
openvdb::math::Transform::Ptr transform;
public:
OpenVDBTransform();
~OpenVDBTransform();
void create_linear_transform(double voxel_size);
const openvdb::math::Transform::Ptr &get_transform();
void set_transform(const openvdb::math::Transform::Ptr &transform);
};
#endif // OPENVDB_TRANSFORM_H

View File

@ -18,151 +18,9 @@
*/
#include "openvdb_capi.h"
#include "openvdb_level_set.h"
#include "openvdb_transform.h"
#include "openvdb_util.h"
#include <openvdb/openvdb.h>
int OpenVDB_getVersionHex()
{
return openvdb::OPENVDB_LIBRARY_VERSION;
}
OpenVDBLevelSet *OpenVDBLevelSet_create(bool initGrid, OpenVDBTransform *xform)
{
OpenVDBLevelSet *level_set = new OpenVDBLevelSet();
if (initGrid) {
openvdb::FloatGrid::Ptr grid = openvdb::FloatGrid::create();
grid->setGridClass(openvdb::GRID_LEVEL_SET);
if (xform) {
grid->setTransform(xform->get_transform());
}
level_set->set_grid(grid);
}
return level_set;
}
OpenVDBTransform *OpenVDBTransform_create()
{
return new OpenVDBTransform();
}
void OpenVDBTransform_free(OpenVDBTransform *transform)
{
delete transform;
}
void OpenVDBTransform_create_linear_transform(OpenVDBTransform *transform, double voxel_size)
{
transform->create_linear_transform(voxel_size);
}
void OpenVDBLevelSet_free(OpenVDBLevelSet *level_set)
{
delete level_set;
}
void OpenVDBLevelSet_mesh_to_level_set(struct OpenVDBLevelSet *level_set,
const float *vertices,
const int *faces,
const int totvertices,
const int totfaces,
OpenVDBTransform *xform)
{
level_set->mesh_to_level_set(vertices, faces, totvertices, totfaces, xform->get_transform());
}
void OpenVDBLevelSet_mesh_to_level_set_transform(struct OpenVDBLevelSet *level_set,
const float *vertices,
const int *faces,
const int totvertices,
const int totfaces,
OpenVDBTransform *transform)
{
level_set->mesh_to_level_set(vertices, faces, totvertices, totfaces, transform->get_transform());
}
void OpenVDBLevelSet_volume_to_mesh(struct OpenVDBLevelSet *level_set,
struct OpenVDBVolumeToMeshData *mesh,
const double isovalue,
const double adaptivity,
const bool relax_disoriented_triangles)
{
level_set->volume_to_mesh(mesh, isovalue, adaptivity, relax_disoriented_triangles);
}
void OpenVDBLevelSet_filter(struct OpenVDBLevelSet *level_set,
OpenVDBLevelSet_FilterType filter_type,
int width,
float distance,
OpenVDBLevelSet_FilterBias bias)
{
level_set->filter(filter_type, width, distance, bias);
}
void OpenVDBLevelSet_CSG_operation(struct OpenVDBLevelSet *out,
struct OpenVDBLevelSet *gridA,
struct OpenVDBLevelSet *gridB,
OpenVDBLevelSet_CSGOperation operation)
{
openvdb::FloatGrid::Ptr grid = out->CSG_operation_apply(
gridA->get_grid(), gridB->get_grid(), operation);
out->set_grid(grid);
}
OpenVDBLevelSet *OpenVDBLevelSet_transform_and_resample(struct OpenVDBLevelSet *level_setA,
struct OpenVDBLevelSet *level_setB,
char sampler,
float isolevel)
{
openvdb::FloatGrid::Ptr sourceGrid = level_setA->get_grid();
openvdb::FloatGrid::Ptr targetGrid = level_setB->get_grid()->deepCopy();
const openvdb::math::Transform &sourceXform = sourceGrid->transform(),
&targetXform = targetGrid->transform();
// Compute a source grid to target grid transform.
// (For this example, we assume that both grids' transforms are linear,
// so that they can be represented as 4 x 4 matrices.)
openvdb::Mat4R xform = sourceXform.baseMap()->getAffineMap()->getMat4() *
targetXform.baseMap()->getAffineMap()->getMat4().inverse();
// Create the transformer.
openvdb::tools::GridTransformer transformer(xform);
switch (sampler) {
case OPENVDB_LEVELSET_GRIDSAMPLER_POINT:
// Resample using nearest-neighbor interpolation.
transformer.transformGrid<openvdb::tools::PointSampler, openvdb::FloatGrid>(*sourceGrid,
*targetGrid);
// Prune the target tree for optimal sparsity.
targetGrid->tree().prune();
break;
case OPENVDB_LEVELSET_GRIDSAMPLER_BOX:
// Resample using trilinear interpolation.
transformer.transformGrid<openvdb::tools::BoxSampler, openvdb::FloatGrid>(*sourceGrid,
*targetGrid);
// Prune the target tree for optimal sparsity.
targetGrid->tree().prune();
break;
case OPENVDB_LEVELSET_GRIDSAMPLER_QUADRATIC:
// Resample using triquadratic interpolation.
transformer.transformGrid<openvdb::tools::QuadraticSampler, openvdb::FloatGrid>(*sourceGrid,
*targetGrid);
// Prune the target tree for optimal sparsity.
targetGrid->tree().prune();
break;
case OPENVDB_LEVELSET_GRIDSAMPLER_NONE:
break;
}
targetGrid = openvdb::tools::levelSetRebuild(*targetGrid, isolevel, 1.0f);
openvdb::tools::pruneLevelSet(targetGrid->tree());
OpenVDBLevelSet *level_set = OpenVDBLevelSet_create(false, NULL);
level_set->set_grid(targetGrid);
return level_set;
}

View File

@ -24,124 +24,8 @@
extern "C" {
#endif
/* Level Set Filters */
typedef enum OpenVDBLevelSet_FilterType {
OPENVDB_LEVELSET_FILTER_NONE = 0,
OPENVDB_LEVELSET_FILTER_GAUSSIAN = 1,
OPENVDB_LEVELSET_FILTER_MEAN = 2,
OPENVDB_LEVELSET_FILTER_MEDIAN = 3,
OPENVDB_LEVELSET_FILTER_MEAN_CURVATURE = 4,
OPENVDB_LEVELSET_FILTER_LAPLACIAN = 5,
OPENVDB_LEVELSET_FILTER_DILATE = 6,
OPENVDB_LEVELSET_FILTER_ERODE = 7,
} OpenVDBLevelSet_FilterType;
typedef enum OpenVDBLevelSet_FilterBias {
OPENVDB_LEVELSET_FIRST_BIAS = 0,
OPENVDB_LEVELSET_SECOND_BIAS,
OPENVDB_LEVELSET_THIRD_BIAS,
OPENVDB_LEVELSET_WENO5_BIAS,
OPENVDB_LEVELSET_HJWENO5_BIAS,
} OpenVDBLevelSet_FilterBias;
/* Level Set CSG Operations */
typedef enum OpenVDBLevelSet_CSGOperation {
OPENVDB_LEVELSET_CSG_UNION = 0,
OPENVDB_LEVELSET_CSG_DIFFERENCE = 1,
OPENVDB_LEVELSET_CSG_INTERSECTION = 2,
} OpenVDBLevelSet_CSGOperation;
typedef enum OpenVDBLevelSet_GridSampler {
OPENVDB_LEVELSET_GRIDSAMPLER_NONE = 0,
OPENVDB_LEVELSET_GRIDSAMPLER_POINT = 1,
OPENVDB_LEVELSET_GRIDSAMPLER_BOX = 2,
OPENVDB_LEVELSET_GRIDSAMPLER_QUADRATIC = 3,
} OpenVDBLevelSet_Gridsampler;
struct OpenVDBTransform;
struct OpenVDBLevelSet;
struct OpenVDBVolumeToMeshData {
int tottriangles;
int totquads;
int totvertices;
float *vertices;
int *quads;
int *triangles;
};
struct OpenVDBRemeshData {
float *verts;
int *faces;
int totfaces;
int totverts;
float *out_verts;
int *out_faces;
int *out_tris;
int out_totverts;
int out_totfaces;
int out_tottris;
int filter_type;
enum OpenVDBLevelSet_FilterType filter_bias;
enum OpenVDBLevelSet_FilterBias filter_width; /* Parameter for gaussian, median, mean. */
float voxel_size;
float isovalue;
float adaptivity;
int relax_disoriented_triangles;
};
int OpenVDB_getVersionHex(void);
enum {
VEC_INVARIANT = 0,
VEC_COVARIANT = 1,
VEC_COVARIANT_NORMALIZE = 2,
VEC_CONTRAVARIANT_RELATIVE = 3,
VEC_CONTRAVARIANT_ABSOLUTE = 4,
};
struct OpenVDBTransform *OpenVDBTransform_create(void);
void OpenVDBTransform_free(struct OpenVDBTransform *transform);
void OpenVDBTransform_create_linear_transform(struct OpenVDBTransform *transform,
double voxel_size);
struct OpenVDBLevelSet *OpenVDBLevelSet_create(bool initGrid, struct OpenVDBTransform *xform);
void OpenVDBLevelSet_free(struct OpenVDBLevelSet *level_set);
void OpenVDBLevelSet_mesh_to_level_set(struct OpenVDBLevelSet *level_set,
const float *vertices,
const int *faces,
const int totvertices,
const int totfaces,
struct OpenVDBTransform *xform);
void OpenVDBLevelSet_mesh_to_level_set_transform(struct OpenVDBLevelSet *level_set,
const float *vertices,
const int *faces,
const int totvertices,
const int totfaces,
struct OpenVDBTransform *transform);
void OpenVDBLevelSet_volume_to_mesh(struct OpenVDBLevelSet *level_set,
struct OpenVDBVolumeToMeshData *mesh,
const double isovalue,
const double adaptivity,
const bool relax_disoriented_triangles);
void OpenVDBLevelSet_filter(struct OpenVDBLevelSet *level_set,
OpenVDBLevelSet_FilterType filter_type,
int width,
float distance,
OpenVDBLevelSet_FilterBias bias);
void OpenVDBLevelSet_CSG_operation(struct OpenVDBLevelSet *out,
struct OpenVDBLevelSet *gridA,
struct OpenVDBLevelSet *gridB,
OpenVDBLevelSet_CSGOperation operation);
struct OpenVDBLevelSet *OpenVDBLevelSet_transform_and_resample(struct OpenVDBLevelSet *level_setA,
struct OpenVDBLevelSet *level_setB,
char sampler,
float isolevel);
#ifdef __cplusplus
}
#endif

View File

@ -1,36 +0,0 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2015 Blender Foundation.
* All rights reserved.
*/
#include "openvdb_util.h"
#include <cstdio>
ScopeTimer::ScopeTimer(const std::string &message) : m_message(message), m_timer()
{
}
ScopeTimer::~ScopeTimer()
{
#if OPENVDB_LIBRARY_MAJOR_VERSION_NUMBER >= 7
double delta = m_timer.milliseconds();
#else
double delta = m_timer.delta(); /* Deprecated in OpenVDB 7. */
#endif
std::printf("%s: %fms\n", m_message.c_str(), delta);
}

View File

@ -1,51 +0,0 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2015 Blender Foundation.
* All rights reserved.
*/
#ifndef __OPENVDB_UTIL_H__
#define __OPENVDB_UTIL_H__
#include <openvdb/openvdb.h>
#include <openvdb/util/CpuTimer.h>
#define CATCH_KEYERROR \
catch (const openvdb::KeyError &e) \
{ \
std::cerr << e.what() << '\n'; \
}
//#define DEBUG_TIME
/* A utility class which prints the time elapsed during its lifetime, useful for
* e.g. timing the overall execution time of a function */
class ScopeTimer {
std::string m_message;
openvdb::util::CpuTimer m_timer;
public:
ScopeTimer(const std::string &message);
~ScopeTimer();
};
#ifdef DEBUG_TIME
# define Timer(x) ScopeTimer prof(x);
#else
# define Timer(x)
#endif
#endif /* __OPENVDB_UTIL_H__ */

View File

@ -2000,6 +2000,7 @@ def km_file_browser(params):
("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True},
{"properties": [("increment", -100)]}),
*_template_items_context_menu("FILEBROWSER_MT_context_menu", params.context_menu_event),
*_template_items_context_menu("ASSETBROWSER_MT_context_menu", params.context_menu_event),
])
return keymap

View File

@ -1249,6 +1249,7 @@ def km_file_browser(params):
("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True},
{"properties": [("increment", -100)]}),
*_template_items_context_menu("FILEBROWSER_MT_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}),
*_template_items_context_menu("ASSETBROWSER_MT_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}),
])
return keymap

View File

@ -205,6 +205,9 @@ class RENDER_PT_stamp(RenderOutputButtonsPanel, Panel):
col.prop(rd, "use_stamp_marker", text="Marker")
col.prop(rd, "use_stamp_filename", text="Filename")
if rd.use_sequencer:
col.prop(rd, "use_stamp_sequencer_strip", text="Strip Name")
class RENDER_PT_stamp_note(RenderOutputButtonsPanel, Panel):
bl_label = "Note"

View File

@ -52,18 +52,10 @@ class FILEBROWSER_HT_header(Header):
layout.prop_with_popover(
params,
"display_type",
panel="FILEBROWSER_PT_display",
panel="ASSETBROWSER_PT_display",
text="",
icon_only=True,
)
layout.prop_with_popover(
params,
"display_type",
panel="FILEBROWSER_PT_filter",
text="",
icon='FILTER',
icon_only=True,
)
layout.prop(params, "filter_search", text="", icon='VIEWZOOM')
@ -84,28 +76,36 @@ class FILEBROWSER_HT_header(Header):
if space_data.active_operator is None:
layout.template_header()
FILEBROWSER_MT_editor_menus.draw_collapsible(context, layout)
if SpaceAssetInfo.is_asset_browser(space_data):
ASSETBROWSER_MT_editor_menus.draw_collapsible(context, layout)
layout.separator()
self.draw_asset_browser_buttons(context)
else:
FILEBROWSER_MT_editor_menus.draw_collapsible(context, layout)
layout.separator_spacer()
if not context.screen.show_statusbar:
layout.template_running_jobs()
class FILEBROWSER_PT_display(Panel):
class FileBrowserPanel:
bl_space_type = 'FILE_BROWSER'
bl_region_type = 'HEADER'
bl_label = "Display Settings" # Shows as tooltip in popover
bl_ui_units_x = 10
@classmethod
def poll(cls, context):
space_data = context.space_data
# can be None when save/reload with a file selector open
return context.space_data.params is not None
if space_data.params is None:
return False
return space_data and space_data.type == 'FILE_BROWSER' and space_data.browse_mode == 'FILES'
class FILEBROWSER_PT_display(FileBrowserPanel, Panel):
bl_region_type = 'HEADER'
bl_label = "Display Settings" # Shows as tooltip in popover
bl_ui_units_x = 10
def draw(self, context):
layout = self.layout
@ -129,17 +129,11 @@ class FILEBROWSER_PT_display(Panel):
layout.prop(params, "use_sort_invert")
class FILEBROWSER_PT_filter(Panel):
bl_space_type = 'FILE_BROWSER'
class FILEBROWSER_PT_filter(FileBrowserPanel, Panel):
bl_region_type = 'HEADER'
bl_label = "Filter Settings" # Shows as tooltip in popover
bl_ui_units_x = 8
@classmethod
def poll(cls, context):
# can be None when save/reload with a file selector open
return context.space_data.params is not None
def draw(self, context):
layout = self.layout
@ -302,7 +296,7 @@ class FILEBROWSER_MT_bookmarks_context_menu(Menu):
text="Move to Bottom").direction = 'BOTTOM'
class FILEBROWSER_PT_bookmarks_favorites(Panel):
class FILEBROWSER_PT_bookmarks_favorites(FileBrowserPanel, Panel):
bl_space_type = 'FILE_BROWSER'
bl_region_type = 'TOOLS'
bl_category = "Bookmarks"
@ -477,7 +471,14 @@ class FILEBROWSER_PT_directory_path(Panel):
).region_type = 'TOOL_PROPS'
class FILEBROWSER_MT_editor_menus(Menu):
class FileBrowserMenu:
@classmethod
def poll(cls, context):
space_data = context.space_data
return space_data and space_data.type == 'FILE_BROWSER' and space_data.browse_mode == 'FILES'
class FILEBROWSER_MT_editor_menus(FileBrowserMenu, Menu):
bl_idname = "FILEBROWSER_MT_editor_menus"
bl_label = ""
@ -488,7 +489,7 @@ class FILEBROWSER_MT_editor_menus(Menu):
layout.menu("FILEBROWSER_MT_select")
class FILEBROWSER_MT_view(Menu):
class FILEBROWSER_MT_view(FileBrowserMenu, Menu):
bl_label = "View"
def draw(self, context):
@ -510,7 +511,7 @@ class FILEBROWSER_MT_view(Menu):
layout.menu("INFO_MT_area")
class FILEBROWSER_MT_select(Menu):
class FILEBROWSER_MT_select(FileBrowserMenu, Menu):
bl_label = "Select"
def draw(self, _context):
@ -525,7 +526,7 @@ class FILEBROWSER_MT_select(Menu):
layout.operator("file.select_box")
class FILEBROWSER_MT_context_menu(Menu):
class FILEBROWSER_MT_context_menu(FileBrowserMenu, Menu):
bl_label = "Files Context Menu"
def draw(self, context):
@ -552,10 +553,6 @@ class FILEBROWSER_MT_context_menu(Menu):
sub.operator_context = 'EXEC_DEFAULT'
sub.operator("file.delete", text="Delete")
active_asset = asset_utils.SpaceAssetInfo.get_active_asset(context)
if active_asset:
layout.operator("asset.open_containing_blend_file")
layout.separator()
sub = layout.row()
@ -572,6 +569,82 @@ class FILEBROWSER_MT_context_menu(Menu):
layout.prop_menu_enum(params, "sort_method")
class ASSETBROWSER_PT_display(asset_utils.AssetBrowserPanel, Panel):
bl_region_type = 'HEADER'
bl_label = "Display Settings" # Shows as tooltip in popover
bl_ui_units_x = 10
def draw(self, context):
layout = self.layout
space = context.space_data
params = space.params
layout.use_property_split = True
layout.use_property_decorate = False # No animation.
if params.display_type == 'THUMBNAIL':
layout.prop(params, "display_size", text="Size")
else:
col = layout.column(heading="Columns", align=True)
col.prop(params, "show_details_size", text="Size")
col.prop(params, "show_details_datetime", text="Date")
class AssetBrowserMenu:
@classmethod
def poll(cls, context):
from bpy_extras.asset_utils import SpaceAssetInfo
return SpaceAssetInfo.is_asset_browser_poll(context)
class ASSETBROWSER_MT_editor_menus(AssetBrowserMenu, Menu):
bl_idname = "ASSETBROWSER_MT_editor_menus"
bl_label = ""
def draw(self, _context):
layout = self.layout
layout.menu("ASSETBROWSER_MT_view")
layout.menu("ASSETBROWSER_MT_select")
class ASSETBROWSER_MT_view(AssetBrowserMenu, Menu):
bl_label = "View"
def draw(self, context):
layout = self.layout
st = context.space_data
params = st.params
layout.prop(st, "show_region_toolbar", text="Source List")
layout.prop(st, "show_region_tool_props", text="Asset Details")
layout.operator("file.view_selected")
layout.separator()
layout.prop_menu_enum(params, "display_size")
layout.separator()
layout.menu("INFO_MT_area")
class ASSETBROWSER_MT_select(AssetBrowserMenu, Menu):
bl_label = "Select"
def draw(self, _context):
layout = self.layout
layout.operator("file.select_all", text="All").action = 'SELECT'
layout.operator("file.select_all", text="None").action = 'DESELECT'
layout.operator("file.select_all", text="Inverse").action = 'INVERT'
layout.separator()
layout.operator("file.select_box")
class ASSETBROWSER_PT_navigation_bar(asset_utils.AssetBrowserPanel, Panel):
bl_label = "Asset Navigation"
bl_region_type = 'TOOLS'
@ -678,6 +751,32 @@ class ASSETBROWSER_UL_metadata_tags(UIList):
row.prop(tag, "name", text="", emboss=False, icon_value=icon)
class ASSETBROWSER_MT_context_menu(AssetBrowserMenu, Menu):
bl_label = "Assets Context Menu"
def draw(self, context):
layout = self.layout
st = context.space_data
params = st.params
layout.operator("file.refresh", text="Refresh")
layout.separator()
sub = layout.row()
sub.operator_context = 'EXEC_DEFAULT'
sub.operator("asset.clear", text="Clear Asset")
layout.separator()
layout.operator("asset.open_containing_blend_file")
layout.separator()
if params.display_type == 'THUMBNAIL':
layout.prop_menu_enum(params, "display_size")
classes = (
FILEBROWSER_HT_header,
FILEBROWSER_PT_display,
@ -694,12 +793,17 @@ classes = (
FILEBROWSER_MT_view,
FILEBROWSER_MT_select,
FILEBROWSER_MT_context_menu,
ASSETBROWSER_PT_display,
ASSETBROWSER_MT_editor_menus,
ASSETBROWSER_MT_view,
ASSETBROWSER_MT_select,
ASSETBROWSER_PT_navigation_bar,
ASSETBROWSER_PT_metadata,
ASSETBROWSER_PT_metadata_preview,
ASSETBROWSER_PT_metadata_details,
ASSETBROWSER_PT_metadata_tags,
ASSETBROWSER_UL_metadata_tags,
ASSETBROWSER_MT_context_menu,
)
if __name__ == "__main__": # only for live edit.

View File

@ -280,6 +280,7 @@ void BKE_mesh_recalc_looptri_with_normals(const struct MLoop *mloop,
/* *** mesh_normals.cc *** */
void BKE_mesh_normals_tag_dirty(struct Mesh *mesh);
void BKE_mesh_calc_normals_mapping_simple(struct Mesh *me);
void BKE_mesh_calc_normals_mapping(struct MVert *mverts,
int numVerts,

View File

@ -23,10 +23,6 @@
* \ingroup bke
*/
#ifdef WITH_OPENVDB
# include "openvdb_capi.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -40,8 +40,6 @@ using fn::GMutableSpan;
using fn::GSpan;
using fn::GVArray;
Span<MLoopTri> get_mesh_looptris(const Mesh &mesh);
void sample_point_attribute(const Mesh &mesh,
Span<int> looptri_indices,
Span<float3> bary_coords,

View File

@ -125,6 +125,9 @@ using NodeExpandInMFNetworkFunction = void (*)(blender::nodes::NodeMFNetworkBuil
using NodeGeometryExecFunction = void (*)(blender::nodes::GeoNodeExecParams params);
using SocketGetCPPTypeFunction = const blender::fn::CPPType *(*)();
using SocketGetCPPValueFunction = void (*)(const struct bNodeSocket &socket, void *r_value);
using SocketGetGeometryNodesCPPTypeFunction = const blender::fn::CPPType *(*)();
using SocketGetGeometryNodesCPPValueFunction = void (*)(const struct bNodeSocket &socket,
void *r_value);
using SocketExpandInMFNetworkFunction = void (*)(blender::nodes::SocketMFNetworkBuilder &builder);
#else
@ -132,6 +135,8 @@ typedef void *NodeExpandInMFNetworkFunction;
typedef void *SocketExpandInMFNetworkFunction;
typedef void *NodeGeometryExecFunction;
typedef void *SocketGetCPPTypeFunction;
typedef void *SocketGetGeometryNodesCPPTypeFunction;
typedef void *SocketGetGeometryNodesCPPValueFunction;
typedef void *SocketGetCPPValueFunction;
#endif
@ -194,9 +199,13 @@ typedef struct bNodeSocketType {
/* Expands the socket into a multi-function node that outputs the socket value. */
SocketExpandInMFNetworkFunction expand_in_mf_network;
/* Return the CPPType of this socket. */
SocketGetCPPTypeFunction get_cpp_type;
SocketGetCPPTypeFunction get_base_cpp_type;
/* Get the value of this socket in a generic way. */
SocketGetCPPValueFunction get_cpp_value;
SocketGetCPPValueFunction get_base_cpp_value;
/* Get geometry nodes cpp type. */
SocketGetGeometryNodesCPPTypeFunction get_geometry_nodes_cpp_type;
/* Get geometry nodes cpp value. */
SocketGetGeometryNodesCPPValueFunction get_geometry_nodes_cpp_value;
} bNodeSocketType;
typedef void *(*NodeInitExecFunction)(struct bNodeExecContext *context,

View File

@ -109,6 +109,7 @@ class Spline {
SplinePtr copy() const;
SplinePtr copy_only_settings() const;
SplinePtr copy_without_attributes() const;
static void copy_base_settings(const Spline &src, Spline &dst);
Spline::Type type() const;
@ -209,8 +210,6 @@ class Spline {
virtual void correct_end_tangents() const = 0;
virtual void copy_settings(Spline &dst) const = 0;
virtual void copy_data(Spline &dst) const = 0;
static void copy_base_settings(const Spline &src, Spline &dst);
};
/**

View File

@ -63,6 +63,12 @@ static CLG_LogRef LOG = {"bke.mesh_normals"};
/** \name Mesh Normal Calculation
* \{ */
void BKE_mesh_normals_tag_dirty(Mesh *mesh)
{
mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
mesh->runtime.cd_dirty_poly |= CD_MASK_NORMAL;
}
/**
* Call when there are no polygons.
*/

View File

@ -33,6 +33,7 @@
#include "BLI_array.hh"
#include "BLI_float3.hh"
#include "BLI_index_range.hh"
#include "BLI_span.hh"
#include "DNA_object_types.h"
#include "DNA_mesh_types.h"
@ -50,7 +51,9 @@
#include "bmesh_tools.h"
#ifdef WITH_OPENVDB
# include "openvdb_capi.h"
# include <openvdb/openvdb.h>
# include <openvdb/tools/MeshToVolume.h>
# include <openvdb/tools/VolumeToMesh.h>
#endif
#ifdef WITH_QUADRIFLOW
@ -60,6 +63,8 @@
using blender::Array;
using blender::float3;
using blender::IndexRange;
using blender::MutableSpan;
using blender::Span;
#ifdef WITH_QUADRIFLOW
static Mesh *remesh_quadriflow(const Mesh *input_mesh,
@ -74,7 +79,7 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh,
/* Ensure that the triangulated mesh data is up to data */
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(input_mesh);
/* Gather the required data for export to the internal quadiflow mesh format */
/* Gather the required data for export to the internal quadriflow mesh format. */
MVertTri *verttri = (MVertTri *)MEM_callocN(
sizeof(*verttri) * BKE_mesh_runtime_looptri_len(input_mesh), "remesh_looptri");
BKE_mesh_runtime_verttri_from_looptri(
@ -194,91 +199,80 @@ Mesh *BKE_mesh_remesh_quadriflow(const Mesh *mesh,
}
#ifdef WITH_OPENVDB
static struct OpenVDBLevelSet *remesh_voxel_level_set_create(const Mesh *mesh,
struct OpenVDBTransform *transform)
static openvdb::FloatGrid::Ptr remesh_voxel_level_set_create(const Mesh *mesh,
const float voxel_size)
{
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh);
MVertTri *verttri = (MVertTri *)MEM_callocN(
sizeof(*verttri) * BKE_mesh_runtime_looptri_len(mesh), "remesh_looptri");
BKE_mesh_runtime_verttri_from_looptri(
verttri, mesh->mloop, looptri, BKE_mesh_runtime_looptri_len(mesh));
Span<MLoop> mloop{mesh->mloop, mesh->totloop};
Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(mesh),
BKE_mesh_runtime_looptri_len(mesh)};
const int totfaces = BKE_mesh_runtime_looptri_len(mesh);
const int totverts = mesh->totvert;
Array<float3> verts(totverts);
Array<int> faces(totfaces * 3);
std::vector<openvdb::Vec3s> points(mesh->totvert);
std::vector<openvdb::Vec3I> triangles(looptris.size());
for (const int i : IndexRange(totverts)) {
verts[i] = mesh->mvert[i].co;
for (const int i : IndexRange(mesh->totvert)) {
const float3 co = mesh->mvert[i].co;
points[i] = openvdb::Vec3s(co.x, co.y, co.z);
}
for (const int i : IndexRange(totfaces)) {
MVertTri &vt = verttri[i];
faces[i * 3] = vt.tri[0];
faces[i * 3 + 1] = vt.tri[1];
faces[i * 3 + 2] = vt.tri[2];
for (const int i : IndexRange(looptris.size())) {
const MLoopTri &loop_tri = looptris[i];
triangles[i] = openvdb::Vec3I(
mloop[loop_tri.tri[0]].v, mloop[loop_tri.tri[1]].v, mloop[loop_tri.tri[2]].v);
}
struct OpenVDBLevelSet *level_set = OpenVDBLevelSet_create(false, nullptr);
OpenVDBLevelSet_mesh_to_level_set(
level_set, (const float *)verts.data(), faces.data(), totverts, totfaces, transform);
openvdb::math::Transform::Ptr transform = openvdb::math::Transform::createLinearTransform(
voxel_size);
openvdb::FloatGrid::Ptr grid = openvdb::tools::meshToLevelSet<openvdb::FloatGrid>(
*transform, points, triangles, 1.0f);
MEM_freeN(verttri);
return level_set;
return grid;
}
static Mesh *remesh_voxel_volume_to_mesh(struct OpenVDBLevelSet *level_set,
double isovalue,
double adaptivity,
bool relax_disoriented_triangles)
static Mesh *remesh_voxel_volume_to_mesh(const openvdb::FloatGrid::Ptr level_set_grid,
const float isovalue,
const float adaptivity,
const bool relax_disoriented_triangles)
{
struct OpenVDBVolumeToMeshData output_mesh;
OpenVDBLevelSet_volume_to_mesh(
level_set, &output_mesh, isovalue, adaptivity, relax_disoriented_triangles);
std::vector<openvdb::Vec3s> vertices;
std::vector<openvdb::Vec4I> quads;
std::vector<openvdb::Vec3I> tris;
openvdb::tools::volumeToMesh<openvdb::FloatGrid>(
*level_set_grid, vertices, tris, quads, isovalue, adaptivity, relax_disoriented_triangles);
Mesh *mesh = BKE_mesh_new_nomain(output_mesh.totvertices,
0,
0,
(output_mesh.totquads * 4) + (output_mesh.tottriangles * 3),
output_mesh.totquads + output_mesh.tottriangles);
Mesh *mesh = BKE_mesh_new_nomain(
vertices.size(), 0, 0, quads.size() * 4 + tris.size() * 3, quads.size() + tris.size());
MutableSpan<MVert> mverts{mesh->mvert, mesh->totvert};
MutableSpan<MLoop> mloops{mesh->mloop, mesh->totloop};
MutableSpan<MPoly> mpolys{mesh->mpoly, mesh->totpoly};
for (const int i : IndexRange(output_mesh.totvertices)) {
copy_v3_v3(mesh->mvert[i].co, &output_mesh.vertices[i * 3]);
for (const int i : mverts.index_range()) {
copy_v3_v3(mverts[i].co, float3(vertices[i].x(), vertices[i].y(), vertices[i].z()));
}
for (const int i : IndexRange(output_mesh.totquads)) {
MPoly &poly = mesh->mpoly[i];
for (const int i : IndexRange(quads.size())) {
MPoly &poly = mpolys[i];
const int loopstart = i * 4;
poly.loopstart = loopstart;
poly.totloop = 4;
mesh->mloop[loopstart].v = output_mesh.quads[loopstart];
mesh->mloop[loopstart + 1].v = output_mesh.quads[loopstart + 1];
mesh->mloop[loopstart + 2].v = output_mesh.quads[loopstart + 2];
mesh->mloop[loopstart + 3].v = output_mesh.quads[loopstart + 3];
mloops[loopstart].v = quads[i][0];
mloops[loopstart + 1].v = quads[i][3];
mloops[loopstart + 2].v = quads[i][2];
mloops[loopstart + 3].v = quads[i][1];
}
const int triangle_poly_start = output_mesh.totquads;
const int triangle_loop_start = output_mesh.totquads * 4;
for (const int i : IndexRange(output_mesh.tottriangles)) {
MPoly &poly = mesh->mpoly[triangle_poly_start + i];
const int triangle_loop_start = quads.size() * 4;
for (const int i : IndexRange(tris.size())) {
MPoly &poly = mpolys[quads.size() + i];
const int loopstart = triangle_loop_start + i * 3;
poly.loopstart = loopstart;
poly.totloop = 3;
mesh->mloop[loopstart].v = output_mesh.triangles[i * 3 + 2];
mesh->mloop[loopstart + 1].v = output_mesh.triangles[i * 3 + 1];
mesh->mloop[loopstart + 2].v = output_mesh.triangles[i * 3];
mloops[loopstart].v = tris[i][2];
mloops[loopstart + 1].v = tris[i][1];
mloops[loopstart + 2].v = tris[i][0];
}
BKE_mesh_calc_edges(mesh, false, false);
BKE_mesh_calc_normals(mesh);
MEM_freeN(output_mesh.quads);
MEM_freeN(output_mesh.vertices);
if (output_mesh.tottriangles > 0) {
MEM_freeN(output_mesh.triangles);
}
BKE_mesh_normals_tag_dirty(mesh);
return mesh;
}
@ -290,14 +284,8 @@ Mesh *BKE_mesh_remesh_voxel(const Mesh *mesh,
const float isovalue)
{
#ifdef WITH_OPENVDB
struct OpenVDBTransform *xform = OpenVDBTransform_create();
OpenVDBTransform_create_linear_transform(xform, (double)voxel_size);
struct OpenVDBLevelSet *level_set = remesh_voxel_level_set_create(mesh, xform);
Mesh *new_mesh = remesh_voxel_volume_to_mesh(
level_set, (double)isovalue, (double)adaptivity, false);
OpenVDBLevelSet_free(level_set);
OpenVDBTransform_free(xform);
return new_mesh;
openvdb::FloatGrid::Ptr level_set = remesh_voxel_level_set_create(mesh, voxel_size);
return remesh_voxel_volume_to_mesh(level_set, isovalue, adaptivity, false);
#else
UNUSED_VARS(mesh, voxel_size, adaptivity, isovalue);
return nullptr;

View File

@ -24,14 +24,6 @@
namespace blender::bke::mesh_surface_sample {
Span<MLoopTri> get_mesh_looptris(const Mesh &mesh)
{
/* This only updates a cache and can be considered to be logically const. */
const MLoopTri *looptris = BKE_mesh_runtime_looptri_ensure(const_cast<Mesh *>(&mesh));
const int looptris_len = BKE_mesh_runtime_looptri_len(&mesh);
return {looptris, looptris_len};
}
template<typename T>
BLI_NOINLINE static void sample_point_attribute(const Mesh &mesh,
const Span<int> looptri_indices,
@ -39,7 +31,8 @@ BLI_NOINLINE static void sample_point_attribute(const Mesh &mesh,
const VArray<T> &data_in,
const MutableSpan<T> data_out)
{
const Span<MLoopTri> looptris = get_mesh_looptris(mesh);
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
BKE_mesh_runtime_looptri_len(&mesh)};
for (const int i : bary_coords.index_range()) {
const int looptri_index = looptri_indices[i];
@ -85,7 +78,8 @@ BLI_NOINLINE static void sample_corner_attribute(const Mesh &mesh,
const VArray<T> &data_in,
const MutableSpan<T> data_out)
{
Span<MLoopTri> looptris = get_mesh_looptris(mesh);
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
BKE_mesh_runtime_looptri_len(&mesh)};
for (const int i : bary_coords.index_range()) {
const int looptri_index = looptri_indices[i];
@ -130,7 +124,8 @@ void sample_face_attribute(const Mesh &mesh,
const VArray<T> &data_in,
const MutableSpan<T> data_out)
{
Span<MLoopTri> looptris = get_mesh_looptris(mesh);
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
BKE_mesh_runtime_looptri_len(&mesh)};
for (const int i : data_out.index_range()) {
const int looptri_index = looptri_indices[i];
@ -172,7 +167,8 @@ Span<float3> MeshAttributeInterpolator::ensure_barycentric_coords()
}
bary_coords_.reinitialize(positions_.size());
Span<MLoopTri> looptris = get_mesh_looptris(*mesh_);
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(mesh_),
BKE_mesh_runtime_looptri_len(mesh_)};
for (const int i : bary_coords_.index_range()) {
const int looptri_index = looptri_indices_[i];
@ -199,7 +195,8 @@ Span<float3> MeshAttributeInterpolator::ensure_nearest_weights()
}
nearest_weights_.reinitialize(positions_.size());
Span<MLoopTri> looptris = get_mesh_looptris(*mesh_);
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(mesh_),
BKE_mesh_runtime_looptri_len(mesh_)};
for (const int i : nearest_weights_.index_range()) {
const int looptri_index = looptri_indices_[i];

View File

@ -159,7 +159,7 @@ static Mesh *new_mesh_from_openvdb_data(Span<openvdb::Vec3s> verts,
}
BKE_mesh_calc_edges(mesh, false, false);
BKE_mesh_calc_normals(mesh);
BKE_mesh_normals_tag_dirty(mesh);
return mesh;
}

View File

@ -1165,8 +1165,8 @@ static int filter_plane_side(const double3 &p,
* interesect_tri_tri and helper functions.
* This code uses the algorithm of Guigue and Devillers, as described
* in "Faster Triangle-Triangle Intersection Tests".
* Adapted from github code by Eric Haines:
* github.com/erich666/jgt-code/tree/master/Volume_08/Number_1/Guigue2003
* Adapted from code by Eric Haines:
* https://github.com/erich666/jgt-code/tree/master/Volume_08/Number_1/Guigue2003
*/
/**

View File

@ -50,6 +50,8 @@ static void bm_edge_tag_from_smooth(const float (*fnos)[3],
BMEdge *e,
const float split_angle_cos);
static void bm_edge_tag_clear(BMEdge *e);
/* -------------------------------------------------------------------- */
/** \name Update Vertex & Face Normals
* \{ */
@ -820,9 +822,10 @@ BLI_INLINE bool bm_edge_is_smooth_no_angle_test(const BMEdge *e,
const BMLoop *l_a,
const BMLoop *l_b)
{
BLI_assert(l_a->radial_next == l_b);
return (
/* The face is manifold. */
(l_a->radial_next == l_b) &&
(l_b->radial_next == l_a) &&
/* Faces have winding that faces the same way. */
(l_a->v != l_b->v) &&
/* The edge is smooth. */
@ -863,6 +866,13 @@ static void bm_edge_tag_from_smooth(const float (*fnos)[3], BMEdge *e, const flo
}
}
static void bm_edge_tag_clear(BMEdge *e)
{
/* No need for atomics here as this is a single byte. */
char *hflag_p = &e->head.hflag;
*hflag_p = *hflag_p & ~BM_ELEM_TAG;
}
/**
* A version of #bm_edge_tag_from_smooth that sets sharp edges
* when they would be considered smooth but exceed the split angle .
@ -944,9 +954,13 @@ static void bm_mesh_loops_calc_normals_for_vert_with_clnors(BMesh *bm,
continue;
}
/* Always set as #bm_mesh_loops_calc_normals_for_loop checks the tag. */
if (do_edge_tag) {
bm_edge_tag_from_smooth(fnos, e_curr_iter, split_angle_cos);
}
else {
bm_edge_tag_clear(e_curr_iter);
}
do { /* Radial loops. */
if (l_curr->v != v) {
@ -1052,9 +1066,13 @@ static void bm_mesh_loops_calc_normals_for_vert_without_clnors(
continue;
}
/* Always set as #bm_mesh_loops_calc_normals_for_loop checks the tag. */
if (do_edge_tag) {
bm_edge_tag_from_smooth(fnos, e_curr_iter, split_angle_cos);
}
else {
bm_edge_tag_clear(e_curr_iter);
}
do { /* Radial loops. */
if (l_curr->v != v) {

View File

@ -2577,10 +2577,7 @@ void ED_keymap_ui(struct wmKeyConfig *keyconf);
void ED_uilisttypes_ui(void);
void UI_drop_color_copy(struct wmDrag *drag, struct wmDropBox *drop);
bool UI_drop_color_poll(struct bContext *C,
struct wmDrag *drag,
const struct wmEvent *event,
const char **r_tooltip);
bool UI_drop_color_poll(struct bContext *C, struct wmDrag *drag, const struct wmEvent *event);
bool UI_context_copy_to_selected_list(struct bContext *C,
struct PointerRNA *ptr,

View File

@ -1759,10 +1759,7 @@ static void UI_OT_button_string_clear(wmOperatorType *ot)
/** \name Drop Color Operator
* \{ */
bool UI_drop_color_poll(struct bContext *C,
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
bool UI_drop_color_poll(struct bContext *C, wmDrag *drag, const wmEvent *UNUSED(event))
{
/* should only return true for regions that include buttons, for now
* return true always */

View File

@ -166,9 +166,10 @@ static int voxel_remesh_exec(bContext *C, wmOperator *op)
Mesh *mesh_fixed_poles = BKE_mesh_remesh_voxel_fix_poles(new_mesh);
BKE_id_free(nullptr, new_mesh);
new_mesh = mesh_fixed_poles;
BKE_mesh_calc_normals(new_mesh);
}
BKE_mesh_calc_normals(new_mesh);
if (mesh->flag & ME_REMESH_REPROJECT_VOLUME || mesh->flag & ME_REMESH_REPROJECT_PAINT_MASK ||
mesh->flag & ME_REMESH_REPROJECT_SCULPT_FACE_SETS ||
mesh->flag & ME_REMESH_REPROJECT_MATERIALS) {

View File

@ -4488,10 +4488,8 @@ static bool match_region_with_redraws(const ScrArea *area,
return false;
}
static void screen_animation_region_tag_redraw(ScrArea *area,
ARegion *region,
const Scene *scene,
eScreen_Redraws_Flag redraws)
static void screen_animation_region_tag_redraw(
bContext *C, ScrArea *area, ARegion *region, const Scene *scene, eScreen_Redraws_Flag redraws)
{
/* Do follow time here if editor type supports it */
if ((redraws & TIME_FOLLOW) &&
@ -4515,10 +4513,29 @@ static void screen_animation_region_tag_redraw(ScrArea *area,
* We do need to redraw when this area is in full screen as no other areas
* will be tagged for redrawing. */
if (region->regiontype == RGN_TYPE_WINDOW && !area->full) {
if (ELEM(area->spacetype, SPACE_GRAPH, SPACE_NLA, SPACE_ACTION)) {
if (ELEM(area->spacetype, SPACE_NLA, SPACE_ACTION)) {
return;
}
/* Drivers Editor needs a full redraw on playback for graph_draw_driver_debug().
* This will make it slower than regular graph editor during playback, but drawing this in
* graph_main_region_draw_overlay() is not feasible because it requires animation filtering
* which has significant overhead which needs to be avoided in the overlay which is redrawn on
* every UI interaction. */
if (area->spacetype == SPACE_GRAPH) {
const SpaceGraph *sipo = area->spacedata.first;
if (sipo->mode != SIPO_MODE_DRIVERS) {
return;
}
bAnimContext ac;
if (ANIM_animdata_get_context(C, &ac) == false) {
return;
}
if (ac.datatype != ANIMCONT_DRIVERS) {
return;
}
}
if (area->spacetype == SPACE_SEQ) {
const SpaceSeq *sseq = area->spacedata.first;
if (!ED_space_sequencer_has_playback_animation(sseq, scene)) {
@ -4712,7 +4729,7 @@ static int screen_animation_step_invoke(bContext *C, wmOperator *UNUSED(op), con
}
if (redraw) {
screen_animation_region_tag_redraw(area, region, scene, sad->redraws);
screen_animation_region_tag_redraw(C, area, region, scene, sad->redraws);
}
}
}
@ -5695,10 +5712,7 @@ static void keymap_modal_set(wmKeyConfig *keyconf)
WM_modalkeymap_assign(keymap, "SCREEN_OT_area_move");
}
static bool blend_file_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
static bool blend_file_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH) {
if (drag->icon == ICON_FILE_BLEND) {
@ -5728,8 +5742,9 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
/* dropbox for entire window */
ListBase *lb = WM_dropboxmap_find("Window", 0, 0);
WM_dropbox_add(lb, "WM_OT_drop_blend_file", blend_file_drop_poll, blend_file_drop_copy, NULL);
WM_dropbox_add(lb, "UI_OT_drop_color", UI_drop_color_poll, UI_drop_color_copy, NULL);
WM_dropbox_add(
lb, "WM_OT_drop_blend_file", blend_file_drop_poll, blend_file_drop_copy, NULL, NULL);
WM_dropbox_add(lb, "UI_OT_drop_color", UI_drop_color_poll, UI_drop_color_copy, NULL, NULL);
keymap_modal_set(keyconf);
}

View File

@ -605,10 +605,7 @@ static int /*eContextResult*/ clip_context(const bContext *C,
}
/* dropboxes */
static bool clip_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
static bool clip_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH) {
/* rule might not work? */
@ -639,7 +636,7 @@ static void clip_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("Clip", SPACE_CLIP, 0);
WM_dropbox_add(lb, "CLIP_OT_open", clip_drop_poll, clip_drop_copy, NULL);
WM_dropbox_add(lb, "CLIP_OT_open", clip_drop_poll, clip_drop_copy, NULL, NULL);
}
static void clip_refresh(const bContext *C, ScrArea *area)

View File

@ -158,10 +158,7 @@ static void console_cursor(wmWindow *win, ScrArea *UNUSED(area), ARegion *region
/* ************* dropboxes ************* */
static bool id_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(tooltip))
static bool id_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
return WM_drag_get_local_ID(drag, 0) != NULL;
}
@ -176,10 +173,7 @@ static void id_drop_copy(wmDrag *drag, wmDropBox *drop)
MEM_freeN(text);
}
static bool path_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(tooltip))
static bool path_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
return (drag->type == WM_DRAG_PATH);
}
@ -196,8 +190,8 @@ static void console_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("Console", SPACE_CONSOLE, RGN_TYPE_WINDOW);
WM_dropbox_add(lb, "CONSOLE_OT_insert", id_drop_poll, id_drop_copy, NULL);
WM_dropbox_add(lb, "CONSOLE_OT_insert", path_drop_poll, path_drop_copy, NULL);
WM_dropbox_add(lb, "CONSOLE_OT_insert", id_drop_poll, id_drop_copy, NULL, NULL);
WM_dropbox_add(lb, "CONSOLE_OT_insert", path_drop_poll, path_drop_copy, NULL, NULL);
}
/* ************* end drop *********** */

View File

@ -2830,20 +2830,10 @@ static bool file_delete_single(const FileSelectParams *params,
FileDirEntry *file,
const char **r_error_message)
{
if (file->typeflag & FILE_TYPE_ASSET) {
ID *id = filelist_file_get_id(file);
if (!id) {
*r_error_message = "File is not a local data-block asset.";
return false;
}
ED_asset_clear_id(id);
}
else {
char str[FILE_MAX];
BLI_join_dirfile(str, sizeof(str), params->dir, file->relpath);
if (BLI_delete_soft(str, r_error_message) != 0 || BLI_exists(str)) {
return false;
}
char str[FILE_MAX];
BLI_join_dirfile(str, sizeof(str), params->dir, file->relpath);
if (BLI_delete_soft(str, r_error_message) != 0 || BLI_exists(str)) {
return false;
}
return true;

View File

@ -815,10 +815,7 @@ static void file_ui_region_listener(const wmRegionListenerParams *listener_param
}
}
static bool filepath_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
static bool filepath_drop_poll(bContext *C, wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH) {
SpaceFile *sfile = CTX_wm_space_file(C);
@ -839,7 +836,7 @@ static void file_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("Window", SPACE_EMPTY, RGN_TYPE_WINDOW);
WM_dropbox_add(lb, "FILE_OT_filepath_drop", filepath_drop_poll, filepath_drop_copy, NULL);
WM_dropbox_add(lb, "FILE_OT_filepath_drop", filepath_drop_poll, filepath_drop_copy, NULL, NULL);
}
static int file_space_subtype_get(ScrArea *area)

View File

@ -253,10 +253,7 @@ static void image_keymap(struct wmKeyConfig *keyconf)
}
/* dropboxes */
static bool image_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool image_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ScrArea *area = CTX_wm_area(C);
if (ED_region_overlap_isect_any_xy(area, &event->x)) {
@ -282,7 +279,7 @@ static void image_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("Image", SPACE_IMAGE, 0);
WM_dropbox_add(lb, "IMAGE_OT_open", image_drop_poll, image_drop_copy, NULL);
WM_dropbox_add(lb, "IMAGE_OT_open", image_drop_poll, image_drop_copy, NULL, NULL);
}
/**

View File

@ -664,42 +664,29 @@ static void node_main_region_draw(const bContext *C, ARegion *region)
/* ************* dropboxes ************* */
static bool node_group_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
static bool node_group_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
return WM_drag_is_ID_type(drag, ID_NT);
}
static bool node_object_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
static bool node_object_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
return WM_drag_is_ID_type(drag, ID_OB);
}
static bool node_collection_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
const wmEvent *UNUSED(event))
{
return WM_drag_is_ID_type(drag, ID_GR);
}
static bool node_texture_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
static bool node_texture_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
return WM_drag_is_ID_type(drag, ID_TE);
}
static bool node_ima_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
static bool node_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH) {
/* rule might not work? */
@ -708,10 +695,7 @@ static bool node_ima_drop_poll(bContext *UNUSED(C),
return WM_drag_is_ID_type(drag, ID_IM);
}
static bool node_mask_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
static bool node_mask_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
return WM_drag_is_ID_type(drag, ID_MSK);
}
@ -753,32 +737,38 @@ static void node_dropboxes(void)
"NODE_OT_add_object",
node_object_drop_poll,
node_id_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"NODE_OT_add_collection",
node_collection_drop_poll,
node_id_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"NODE_OT_add_texture",
node_texture_drop_poll,
node_id_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"NODE_OT_add_group",
node_group_drop_poll,
node_group_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"NODE_OT_add_file",
node_ima_drop_poll,
node_id_path_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"NODE_OT_add_mask",
node_mask_drop_poll,
node_id_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
}
/* ************* end drop *********** */

View File

@ -31,6 +31,7 @@
#include "DNA_space_types.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLT_translation.h"
@ -316,10 +317,7 @@ static bool allow_parenting_without_modifier_key(SpaceOutliner *space_outliner)
}
}
static bool parent_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
@ -455,10 +453,7 @@ void OUTLINER_OT_parent_drop(wmOperatorType *ot)
/* ******************** Parent Clear Operator *********************** */
static bool parent_clear_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
@ -541,10 +536,7 @@ void OUTLINER_OT_parent_clear(wmOperatorType *ot)
/* ******************** Scene Drop Operator *********************** */
static bool scene_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool scene_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
/* Ensure item under cursor is valid drop target */
Object *ob = (Object *)WM_drag_get_local_ID(drag, ID_OB);
@ -609,10 +601,7 @@ void OUTLINER_OT_scene_drop(wmOperatorType *ot)
/* ******************** Material Drop Operator *********************** */
static bool material_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool material_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
/* Ensure item under cursor is valid drop target */
Material *ma = (Material *)WM_drag_get_local_ID(drag, ID_MA);
@ -833,10 +822,7 @@ static bool datastack_drop_are_types_valid(StackDropData *drop_data)
return true;
}
static bool datastack_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **r_tooltip)
static bool datastack_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
if (drag->type != WM_DRAG_DATASTACK) {
return false;
@ -873,28 +859,6 @@ static bool datastack_drop_poll(bContext *C,
break;
}
switch (drop_data->drop_action) {
case DATA_STACK_DROP_REORDER:
*r_tooltip = TIP_("Reorder");
break;
case DATA_STACK_DROP_COPY:
if (drop_data->pchan_parent) {
*r_tooltip = TIP_("Copy to bone");
}
else {
*r_tooltip = TIP_("Copy to object");
}
break;
case DATA_STACK_DROP_LINK:
if (drop_data->pchan_parent) {
*r_tooltip = TIP_("Link all to bone");
}
else {
*r_tooltip = TIP_("Link all to object");
}
break;
}
if (changed) {
ED_region_tag_redraw_no_rebuild(region);
}
@ -902,6 +866,35 @@ static bool datastack_drop_poll(bContext *C,
return true;
}
static char *datastack_drop_tooltip(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event))
{
StackDropData *drop_data = drag->poin;
switch (drop_data->drop_action) {
case DATA_STACK_DROP_REORDER:
return BLI_strdup(TIP_("Reorder"));
break;
case DATA_STACK_DROP_COPY:
if (drop_data->pchan_parent) {
return BLI_strdup(TIP_("Copy to bone"));
}
else {
return BLI_strdup(TIP_("Copy to object"));
}
break;
case DATA_STACK_DROP_LINK:
if (drop_data->pchan_parent) {
return BLI_strdup(TIP_("Link all to bone"));
}
else {
return BLI_strdup(TIP_("Link all to object"));
}
break;
}
return NULL;
}
static void datastack_drop_link(bContext *C, StackDropData *drop_data)
{
Main *bmain = CTX_data_main(C);
@ -1155,10 +1148,7 @@ static bool collection_drop_init(bContext *C,
return true;
}
static bool collection_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **r_tooltip)
static bool collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
ARegion *region = CTX_wm_region(C);
@ -1172,45 +1162,20 @@ static bool collection_drop_poll(bContext *C,
if (!data.from || event->ctrl) {
tselem->flag |= TSE_DRAG_INTO;
changed = true;
*r_tooltip = TIP_("Link inside Collection");
}
else {
switch (data.insert_type) {
case TE_INSERT_BEFORE:
tselem->flag |= TSE_DRAG_BEFORE;
changed = true;
if (te->prev && outliner_is_collection_tree_element(te->prev)) {
*r_tooltip = TIP_("Move between collections");
}
else {
*r_tooltip = TIP_("Move before collection");
}
break;
case TE_INSERT_AFTER:
tselem->flag |= TSE_DRAG_AFTER;
changed = true;
if (te->next && outliner_is_collection_tree_element(te->next)) {
*r_tooltip = TIP_("Move between collections");
}
else {
*r_tooltip = TIP_("Move after collection");
}
break;
case TE_INSERT_INTO: {
tselem->flag |= TSE_DRAG_INTO;
changed = true;
/* Check the type of the drag IDs to avoid the incorrect "Shift to parent"
* for collections. Checking the type of the first ID works fine here since
* all drag IDs are the same type. */
wmDragID *drag_id = (wmDragID *)drag->ids.first;
const bool is_object = (GS(drag_id->id->name) == ID_OB);
if (is_object) {
*r_tooltip = TIP_("Move inside collection (Ctrl to link, Shift to parent)");
}
else {
*r_tooltip = TIP_("Move inside collection (Ctrl to link)");
}
break;
}
}
@ -1226,6 +1191,49 @@ static bool collection_drop_poll(bContext *C,
return false;
}
static char *collection_drop_tooltip(bContext *C, wmDrag *drag, const wmEvent *event)
{
CollectionDrop data;
if (!event->shift && collection_drop_init(C, drag, event, &data)) {
TreeElement *te = data.te;
if (!data.from || event->ctrl) {
return BLI_strdup(TIP_("Link inside Collection"));
}
switch (data.insert_type) {
case TE_INSERT_BEFORE:
if (te->prev && outliner_is_collection_tree_element(te->prev)) {
return BLI_strdup(TIP_("Move between collections"));
}
else {
return BLI_strdup(TIP_("Move before collection"));
}
break;
case TE_INSERT_AFTER:
if (te->next && outliner_is_collection_tree_element(te->next)) {
return BLI_strdup(TIP_("Move between collections"));
}
else {
return BLI_strdup(TIP_("Move after collection"));
}
break;
case TE_INSERT_INTO: {
/* Check the type of the drag IDs to avoid the incorrect "Shift to parent"
* for collections. Checking the type of the first ID works fine here since
* all drag IDs are the same type. */
wmDragID *drag_id = (wmDragID *)drag->ids.first;
const bool is_object = (GS(drag_id->id->name) == ID_OB);
if (is_object) {
return BLI_strdup(TIP_("Move inside collection (Ctrl to link, Shift to parent)"));
}
return BLI_strdup(TIP_("Move inside collection (Ctrl to link)"));
break;
}
}
}
return NULL;
}
static int collection_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
Main *bmain = CTX_data_main(C);
@ -1499,10 +1507,16 @@ void outliner_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("Outliner", SPACE_OUTLINER, RGN_TYPE_WINDOW);
WM_dropbox_add(lb, "OUTLINER_OT_parent_drop", parent_drop_poll, NULL, NULL);
WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", parent_clear_poll, NULL, NULL);
WM_dropbox_add(lb, "OUTLINER_OT_scene_drop", scene_drop_poll, NULL, NULL);
WM_dropbox_add(lb, "OUTLINER_OT_material_drop", material_drop_poll, NULL, NULL);
WM_dropbox_add(lb, "OUTLINER_OT_datastack_drop", datastack_drop_poll, NULL, NULL);
WM_dropbox_add(lb, "OUTLINER_OT_collection_drop", collection_drop_poll, NULL, NULL);
WM_dropbox_add(lb, "OUTLINER_OT_parent_drop", parent_drop_poll, NULL, NULL, NULL);
WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", parent_clear_poll, NULL, NULL, NULL);
WM_dropbox_add(lb, "OUTLINER_OT_scene_drop", scene_drop_poll, NULL, NULL, NULL);
WM_dropbox_add(lb, "OUTLINER_OT_material_drop", material_drop_poll, NULL, NULL, NULL);
WM_dropbox_add(
lb, "OUTLINER_OT_datastack_drop", datastack_drop_poll, NULL, NULL, datastack_drop_tooltip);
WM_dropbox_add(lb,
"OUTLINER_OT_collection_drop",
collection_drop_poll,
NULL,
NULL,
collection_drop_tooltip);
}

View File

@ -275,7 +275,6 @@ static int sequencer_view_selected_exec(bContext *C, wmOperator *op)
View2D *v2d = UI_view2d_fromcontext(C);
ARegion *region = CTX_wm_region(C);
Editing *ed = SEQ_editing_get(scene, false);
Sequence *last_seq = SEQ_select_active_get(scene);
Sequence *seq;
rctf cur_new = v2d->cur;
@ -293,7 +292,7 @@ static int sequencer_view_selected_exec(bContext *C, wmOperator *op)
}
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
if ((seq->flag & SELECT) || (seq == last_seq)) {
if ((seq->flag & SELECT)) {
xmin = min_ii(xmin, seq->startdisp);
xmax = max_ii(xmax, seq->enddisp);

View File

@ -364,10 +364,7 @@ static void sequencer_listener(const wmSpaceTypeListenerParams *params)
/* ************* dropboxes ************* */
static bool image_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool image_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ARegion *region = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
@ -384,10 +381,7 @@ static bool image_drop_poll(bContext *C,
return 0;
}
static bool movie_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool movie_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ARegion *region = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
@ -403,10 +397,7 @@ static bool movie_drop_poll(bContext *C,
return 0;
}
static bool sound_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool sound_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ARegion *region = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
@ -448,9 +439,12 @@ static void sequencer_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("Sequencer", SPACE_SEQ, RGN_TYPE_WINDOW);
WM_dropbox_add(lb, "SEQUENCER_OT_image_strip_add", image_drop_poll, sequencer_drop_copy, NULL);
WM_dropbox_add(lb, "SEQUENCER_OT_movie_strip_add", movie_drop_poll, sequencer_drop_copy, NULL);
WM_dropbox_add(lb, "SEQUENCER_OT_sound_strip_add", sound_drop_poll, sequencer_drop_copy, NULL);
WM_dropbox_add(
lb, "SEQUENCER_OT_image_strip_add", image_drop_poll, sequencer_drop_copy, NULL, NULL);
WM_dropbox_add(
lb, "SEQUENCER_OT_movie_strip_add", movie_drop_poll, sequencer_drop_copy, NULL, NULL);
WM_dropbox_add(
lb, "SEQUENCER_OT_sound_strip_add", sound_drop_poll, sequencer_drop_copy, NULL, NULL);
}
/* ************* end drop *********** */

View File

@ -312,10 +312,7 @@ static void text_cursor(wmWindow *win, ScrArea *area, ARegion *region)
/* ************* dropboxes ************* */
static bool text_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
static bool text_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH) {
/* rule might not work? */
@ -332,10 +329,7 @@ static void text_drop_copy(wmDrag *drag, wmDropBox *drop)
RNA_string_set(drop->ptr, "filepath", drag->path);
}
static bool text_drop_paste_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
static bool text_drop_paste_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
return (drag->type == WM_DRAG_ID);
}
@ -356,8 +350,8 @@ static void text_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("Text", SPACE_TEXT, RGN_TYPE_WINDOW);
WM_dropbox_add(lb, "TEXT_OT_open", text_drop_poll, text_drop_copy, NULL);
WM_dropbox_add(lb, "TEXT_OT_insert", text_drop_paste_poll, text_drop_paste, NULL);
WM_dropbox_add(lb, "TEXT_OT_open", text_drop_poll, text_drop_copy, NULL, NULL);
WM_dropbox_add(lb, "TEXT_OT_insert", text_drop_paste_poll, text_drop_paste, NULL, NULL);
}
/* ************* end drop *********** */

View File

@ -513,49 +513,38 @@ static bool view3d_drop_id_in_main_region_poll(bContext *C,
return WM_drag_is_ID_type(drag, id_type);
}
static bool view3d_ob_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool view3d_ob_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
return view3d_drop_id_in_main_region_poll(C, drag, event, ID_OB);
}
static bool view3d_collection_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool view3d_collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
return view3d_drop_id_in_main_region_poll(C, drag, event, ID_GR);
}
static bool view3d_mat_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool view3d_mat_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
return view3d_drop_id_in_main_region_poll(C, drag, event, ID_MA);
}
static bool view3d_object_data_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **r_tooltip)
static bool view3d_object_data_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ID_Type id_type = view3d_drop_id_in_main_region_poll_get_id_type(C, drag, event);
if (id_type) {
if (OB_DATA_SUPPORT_ID(id_type)) {
*r_tooltip = TIP_("Create object instance from object-data");
return true;
}
if (id_type && OB_DATA_SUPPORT_ID(id_type)) {
return true;
}
return false;
}
static bool view3d_ima_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static char *view3d_object_data_drop_tooltip(bContext *UNUSED(C),
wmDrag *UNUSED(drag),
const wmEvent *UNUSED(event))
{
return BLI_strdup(TIP_("Create object instance from object-data"));
}
static bool view3d_ima_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
if (ED_region_overlap_isect_any_xy(CTX_wm_area(C), &event->x)) {
return false;
@ -580,12 +569,9 @@ static bool view3d_ima_bg_is_camera_view(bContext *C)
return false;
}
static bool view3d_ima_bg_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **r_tooltip)
static bool view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
if (!view3d_ima_drop_poll(C, drag, event, r_tooltip)) {
if (!view3d_ima_drop_poll(C, drag, event)) {
return false;
}
@ -596,12 +582,9 @@ static bool view3d_ima_bg_drop_poll(bContext *C,
return view3d_ima_bg_is_camera_view(C);
}
static bool view3d_ima_empty_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **r_tooltip)
static bool view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
if (!view3d_ima_drop_poll(C, drag, event, r_tooltip)) {
if (!view3d_ima_drop_poll(C, drag, event)) {
return false;
}
@ -620,8 +603,7 @@ static bool view3d_ima_empty_drop_poll(bContext *C,
static bool view3d_volume_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
const wmEvent *UNUSED(event))
{
return (drag->type == WM_DRAG_PATH) && (drag->icon == ICON_FILE_VOLUME);
}
@ -700,37 +682,44 @@ static void view3d_dropboxes(void)
"OBJECT_OT_add_named",
view3d_ob_drop_poll,
view3d_ob_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"OBJECT_OT_drop_named_material",
view3d_mat_drop_poll,
view3d_id_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"VIEW3D_OT_background_image_add",
view3d_ima_bg_drop_poll,
view3d_id_path_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"OBJECT_OT_drop_named_image",
view3d_ima_empty_drop_poll,
view3d_id_path_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"OBJECT_OT_volume_import",
view3d_volume_drop_poll,
view3d_id_path_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"OBJECT_OT_collection_instance_add",
view3d_collection_drop_poll,
view3d_collection_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"OBJECT_OT_data_instance_add",
view3d_object_data_drop_poll,
view3d_id_drop_copy_with_type,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
view3d_object_data_drop_tooltip);
}
static void view3d_widgets(void)

View File

@ -70,64 +70,73 @@
#include "BLI_string_ref.hh"
#include "BLI_utility_mixins.hh"
/**
* Different types support different features. Features like copy constructability can be detected
* automatically easily. For some features this is harder as of C++17. Those have flags in this
* enum and need to be determined by the programmer.
*/
enum class CPPTypeFlags {
None = 0,
Hashable = 1 << 0,
Printable = 1 << 1,
EqualityComparable = 1 << 2,
BasicType = Hashable | Printable | EqualityComparable,
};
ENUM_OPERATORS(CPPTypeFlags, CPPTypeFlags::EqualityComparable)
namespace blender::fn {
struct CPPTypeMembers {
int64_t size = 0;
int64_t alignment = 0;
uintptr_t alignment_mask = 0;
bool is_trivially_destructible = false;
bool has_special_member_functions = false;
void (*default_construct)(void *ptr) = nullptr;
void (*default_construct_indices)(void *ptr, IndexMask mask) = nullptr;
void (*destruct)(void *ptr) = nullptr;
void (*destruct_indices)(void *ptr, IndexMask mask) = nullptr;
void (*copy_assign)(const void *src, void *dst) = nullptr;
void (*copy_assign_indices)(const void *src, void *dst, IndexMask mask) = nullptr;
void (*copy_construct)(const void *src, void *dst) = nullptr;
void (*copy_construct_indices)(const void *src, void *dst, IndexMask mask) = nullptr;
void (*move_assign)(void *src, void *dst) = nullptr;
void (*move_assign_indices)(void *src, void *dst, IndexMask mask) = nullptr;
void (*move_construct)(void *src, void *dst) = nullptr;
void (*move_construct_indices)(void *src, void *dst, IndexMask mask) = nullptr;
void (*relocate_assign)(void *src, void *dst) = nullptr;
void (*relocate_assign_indices)(void *src, void *dst, IndexMask mask) = nullptr;
void (*relocate_construct)(void *src, void *dst) = nullptr;
void (*relocate_construct_indices)(void *src, void *dst, IndexMask mask) = nullptr;
void (*fill_assign_indices)(const void *value, void *dst, IndexMask mask) = nullptr;
void (*fill_construct_indices)(const void *value, void *dst, IndexMask mask) = nullptr;
void (*print)(const void *value, std::stringstream &ss) = nullptr;
bool (*is_equal)(const void *a, const void *b) = nullptr;
uint64_t (*hash)(const void *value) = nullptr;
const void *default_value = nullptr;
std::string name;
/** Utility class to pass template parameters to constructor of `CPPType`. */
template<typename T, CPPTypeFlags Flags> struct CPPTypeParam {
};
class CPPType : NonCopyable, NonMovable {
private:
CPPTypeMembers m_;
int64_t size_ = 0;
int64_t alignment_ = 0;
uintptr_t alignment_mask_ = 0;
bool is_trivially_destructible_ = false;
bool has_special_member_functions_ = false;
void (*default_construct_)(void *ptr) = nullptr;
void (*default_construct_indices_)(void *ptr, IndexMask mask) = nullptr;
void (*destruct_)(void *ptr) = nullptr;
void (*destruct_indices_)(void *ptr, IndexMask mask) = nullptr;
void (*copy_assign_)(const void *src, void *dst) = nullptr;
void (*copy_assign_indices_)(const void *src, void *dst, IndexMask mask) = nullptr;
void (*copy_construct_)(const void *src, void *dst) = nullptr;
void (*copy_construct_indices_)(const void *src, void *dst, IndexMask mask) = nullptr;
void (*move_assign_)(void *src, void *dst) = nullptr;
void (*move_assign_indices_)(void *src, void *dst, IndexMask mask) = nullptr;
void (*move_construct_)(void *src, void *dst) = nullptr;
void (*move_construct_indices_)(void *src, void *dst, IndexMask mask) = nullptr;
void (*relocate_assign_)(void *src, void *dst) = nullptr;
void (*relocate_assign_indices_)(void *src, void *dst, IndexMask mask) = nullptr;
void (*relocate_construct_)(void *src, void *dst) = nullptr;
void (*relocate_construct_indices_)(void *src, void *dst, IndexMask mask) = nullptr;
void (*fill_assign_indices_)(const void *value, void *dst, IndexMask mask) = nullptr;
void (*fill_construct_indices_)(const void *value, void *dst, IndexMask mask) = nullptr;
void (*print_)(const void *value, std::stringstream &ss) = nullptr;
bool (*is_equal_)(const void *a, const void *b) = nullptr;
uint64_t (*hash_)(const void *value) = nullptr;
const void *default_value_ = nullptr;
std::string debug_name_;
public:
CPPType(CPPTypeMembers members) : m_(std::move(members))
{
BLI_assert(is_power_of_2_i(m_.alignment));
m_.alignment_mask = (uintptr_t)members.alignment - (uintptr_t)1;
m_.has_special_member_functions = (m_.default_construct && m_.copy_construct &&
m_.copy_assign && m_.move_construct && m_.move_assign &&
m_.destruct);
}
template<typename T, CPPTypeFlags Flags> CPPType(CPPTypeParam<T, Flags>, StringRef debug_name);
virtual ~CPPType() = default;
/**
* Two types only compare equal when their pointer is equal. No two instances of CPPType for the
@ -148,7 +157,11 @@ class CPPType : NonCopyable, NonMovable {
* This only works for types that actually implement the template specialization using
* `MAKE_CPP_TYPE`.
*/
template<typename T> static const CPPType &get();
template<typename T> static const CPPType &get()
{
return CPPType::get_impl<std::remove_cv_t<T>>();
}
template<typename T> static const CPPType &get_impl();
/**
* Returns the name of the type for debugging purposes. This name should not be used as
@ -156,7 +169,7 @@ class CPPType : NonCopyable, NonMovable {
*/
StringRefNull name() const
{
return m_.name;
return debug_name_;
}
/**
@ -167,7 +180,7 @@ class CPPType : NonCopyable, NonMovable {
*/
int64_t size() const
{
return m_.size;
return size_;
}
/**
@ -178,7 +191,7 @@ class CPPType : NonCopyable, NonMovable {
*/
int64_t alignment() const
{
return m_.alignment;
return alignment_;
}
/**
@ -190,52 +203,52 @@ class CPPType : NonCopyable, NonMovable {
*/
bool is_trivially_destructible() const
{
return m_.is_trivially_destructible;
return is_trivially_destructible_;
}
bool is_default_constructible() const
{
return m_.default_construct != nullptr;
return default_construct_ != nullptr;
}
bool is_copy_constructible() const
{
return m_.copy_assign != nullptr;
return copy_assign_ != nullptr;
}
bool is_move_constructible() const
{
return m_.move_assign != nullptr;
return move_assign_ != nullptr;
}
bool is_destructible() const
{
return m_.destruct != nullptr;
return destruct_ != nullptr;
}
bool is_copy_assignable() const
{
return m_.copy_assign != nullptr;
return copy_assign_ != nullptr;
}
bool is_move_assignable() const
{
return m_.copy_construct != nullptr;
return copy_construct_ != nullptr;
}
bool is_printable() const
{
return m_.print != nullptr;
return print_ != nullptr;
}
bool is_equality_comparable() const
{
return m_.is_equal != nullptr;
return is_equal_ != nullptr;
}
bool is_hashable() const
{
return m_.hash != nullptr;
return hash_ != nullptr;
}
/**
@ -249,7 +262,7 @@ class CPPType : NonCopyable, NonMovable {
*/
bool has_special_member_functions() const
{
return m_.has_special_member_functions;
return has_special_member_functions_;
}
/**
@ -257,7 +270,7 @@ class CPPType : NonCopyable, NonMovable {
*/
bool pointer_has_valid_alignment(const void *ptr) const
{
return ((uintptr_t)ptr & m_.alignment_mask) == 0;
return ((uintptr_t)ptr & alignment_mask_) == 0;
}
bool pointer_can_point_to_instance(const void *ptr) const
@ -277,7 +290,7 @@ class CPPType : NonCopyable, NonMovable {
{
BLI_assert(this->pointer_can_point_to_instance(ptr));
m_.default_construct(ptr);
default_construct_(ptr);
}
void default_construct_n(void *ptr, int64_t n) const
@ -289,7 +302,7 @@ class CPPType : NonCopyable, NonMovable {
{
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(ptr));
m_.default_construct_indices(ptr, mask);
default_construct_indices_(ptr, mask);
}
/**
@ -304,7 +317,7 @@ class CPPType : NonCopyable, NonMovable {
{
BLI_assert(this->pointer_can_point_to_instance(ptr));
m_.destruct(ptr);
destruct_(ptr);
}
void destruct_n(void *ptr, int64_t n) const
@ -316,7 +329,7 @@ class CPPType : NonCopyable, NonMovable {
{
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(ptr));
m_.destruct_indices(ptr, mask);
destruct_indices_(ptr, mask);
}
/**
@ -331,7 +344,7 @@ class CPPType : NonCopyable, NonMovable {
BLI_assert(this->pointer_can_point_to_instance(src));
BLI_assert(this->pointer_can_point_to_instance(dst));
m_.copy_assign(src, dst);
copy_assign_(src, dst);
}
void copy_assign_n(const void *src, void *dst, int64_t n) const
@ -345,7 +358,7 @@ class CPPType : NonCopyable, NonMovable {
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src));
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
m_.copy_assign_indices(src, dst, mask);
copy_assign_indices_(src, dst, mask);
}
/**
@ -362,7 +375,7 @@ class CPPType : NonCopyable, NonMovable {
BLI_assert(this->pointer_can_point_to_instance(src));
BLI_assert(this->pointer_can_point_to_instance(dst));
m_.copy_construct(src, dst);
copy_construct_(src, dst);
}
void copy_construct_n(const void *src, void *dst, int64_t n) const
@ -376,7 +389,7 @@ class CPPType : NonCopyable, NonMovable {
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src));
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
m_.copy_construct_indices(src, dst, mask);
copy_construct_indices_(src, dst, mask);
}
/**
@ -393,7 +406,7 @@ class CPPType : NonCopyable, NonMovable {
BLI_assert(this->pointer_can_point_to_instance(src));
BLI_assert(this->pointer_can_point_to_instance(dst));
m_.move_assign(src, dst);
move_assign_(src, dst);
}
void move_assign_n(void *src, void *dst, int64_t n) const
@ -407,7 +420,7 @@ class CPPType : NonCopyable, NonMovable {
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src));
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
m_.move_assign_indices(src, dst, mask);
move_assign_indices_(src, dst, mask);
}
/**
@ -424,7 +437,7 @@ class CPPType : NonCopyable, NonMovable {
BLI_assert(this->pointer_can_point_to_instance(src));
BLI_assert(this->pointer_can_point_to_instance(dst));
m_.move_construct(src, dst);
move_construct_(src, dst);
}
void move_construct_n(void *src, void *dst, int64_t n) const
@ -438,7 +451,7 @@ class CPPType : NonCopyable, NonMovable {
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src));
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
m_.move_construct_indices(src, dst, mask);
move_construct_indices_(src, dst, mask);
}
/**
@ -455,7 +468,7 @@ class CPPType : NonCopyable, NonMovable {
BLI_assert(this->pointer_can_point_to_instance(src));
BLI_assert(this->pointer_can_point_to_instance(dst));
m_.relocate_assign(src, dst);
relocate_assign_(src, dst);
}
void relocate_assign_n(void *src, void *dst, int64_t n) const
@ -469,7 +482,7 @@ class CPPType : NonCopyable, NonMovable {
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src));
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
m_.relocate_assign_indices(src, dst, mask);
relocate_assign_indices_(src, dst, mask);
}
/**
@ -486,7 +499,7 @@ class CPPType : NonCopyable, NonMovable {
BLI_assert(this->pointer_can_point_to_instance(src));
BLI_assert(this->pointer_can_point_to_instance(dst));
m_.relocate_construct(src, dst);
relocate_construct_(src, dst);
}
void relocate_construct_n(void *src, void *dst, int64_t n) const
@ -500,7 +513,7 @@ class CPPType : NonCopyable, NonMovable {
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src));
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
m_.relocate_construct_indices(src, dst, mask);
relocate_construct_indices_(src, dst, mask);
}
/**
@ -518,7 +531,7 @@ class CPPType : NonCopyable, NonMovable {
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(value));
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
m_.fill_assign_indices(value, dst, mask);
fill_assign_indices_(value, dst, mask);
}
/**
@ -536,13 +549,13 @@ class CPPType : NonCopyable, NonMovable {
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(value));
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
m_.fill_construct_indices(value, dst, mask);
fill_construct_indices_(value, dst, mask);
}
void print(const void *value, std::stringstream &ss) const
{
BLI_assert(this->pointer_can_point_to_instance(value));
m_.print(value, ss);
print_(value, ss);
}
std::string to_string(const void *value) const
@ -566,7 +579,7 @@ class CPPType : NonCopyable, NonMovable {
{
BLI_assert(this->pointer_can_point_to_instance(a));
BLI_assert(this->pointer_can_point_to_instance(b));
return m_.is_equal(a, b);
return is_equal_(a, b);
}
bool is_equal_or_false(const void *a, const void *b) const
@ -580,7 +593,7 @@ class CPPType : NonCopyable, NonMovable {
uint64_t hash(const void *value) const
{
BLI_assert(this->pointer_can_point_to_instance(value));
return m_.hash(value);
return hash_(value);
}
uint64_t hash_or_fallback(const void *value, uint64_t fallback_hash) const
@ -597,7 +610,7 @@ class CPPType : NonCopyable, NonMovable {
*/
const void *default_value() const
{
return m_.default_value;
return default_value_;
}
uint64_t hash() const
@ -605,12 +618,9 @@ class CPPType : NonCopyable, NonMovable {
return get_default_hash(this);
}
/**
* Low level access to the callbacks for this CPPType.
*/
const CPPTypeMembers &members() const
void (*destruct_fn() const)(void *)
{
return m_;
return destruct_;
}
template<typename T> bool is() const

View File

@ -185,100 +185,80 @@ template<typename T> uint64_t hash_cb(const void *value)
} // namespace blender::fn::cpp_type_util
/**
* Different types support different features. Features like copy constructability can be detected
* automatically easily. For some features this is harder as of C++17. Those have flags in this
* enum and need to be determined by the programmer.
*/
enum class CPPTypeFlags {
None = 0,
Hashable = 1 << 0,
Printable = 1 << 1,
EqualityComparable = 1 << 2,
BasicType = Hashable | Printable | EqualityComparable,
};
ENUM_OPERATORS(CPPTypeFlags, CPPTypeFlags::EqualityComparable)
namespace blender::fn {
template<typename T, CPPTypeFlags flags>
inline std::unique_ptr<const CPPType> create_cpp_type(StringRef name)
template<typename T, CPPTypeFlags Flags>
CPPType::CPPType(CPPTypeParam<T, Flags> /* unused */, StringRef debug_name)
{
using namespace cpp_type_util;
CPPTypeMembers m;
m.name = name;
m.size = (int64_t)sizeof(T);
m.alignment = (int64_t)alignof(T);
m.is_trivially_destructible = std::is_trivially_destructible_v<T>;
debug_name_ = debug_name;
size_ = (int64_t)sizeof(T);
alignment_ = (int64_t)alignof(T);
is_trivially_destructible_ = std::is_trivially_destructible_v<T>;
if constexpr (std::is_default_constructible_v<T>) {
m.default_construct = default_construct_cb<T>;
m.default_construct_indices = default_construct_indices_cb<T>;
default_construct_ = default_construct_cb<T>;
default_construct_indices_ = default_construct_indices_cb<T>;
static T default_value;
m.default_value = (void *)&default_value;
default_value_ = (void *)&default_value;
}
if constexpr (std::is_destructible_v<T>) {
m.destruct = destruct_cb<T>;
m.destruct_indices = destruct_indices_cb<T>;
destruct_ = destruct_cb<T>;
destruct_indices_ = destruct_indices_cb<T>;
}
if constexpr (std::is_copy_assignable_v<T>) {
m.copy_assign = copy_assign_cb<T>;
m.copy_assign_indices = copy_assign_indices_cb<T>;
copy_assign_ = copy_assign_cb<T>;
copy_assign_indices_ = copy_assign_indices_cb<T>;
}
if constexpr (std::is_copy_constructible_v<T>) {
m.copy_construct = copy_construct_cb<T>;
m.copy_construct_indices = copy_construct_indices_cb<T>;
copy_construct_ = copy_construct_cb<T>;
copy_construct_indices_ = copy_construct_indices_cb<T>;
}
if constexpr (std::is_move_assignable_v<T>) {
m.move_assign = move_assign_cb<T>;
m.move_assign_indices = move_assign_indices_cb<T>;
move_assign_ = move_assign_cb<T>;
move_assign_indices_ = move_assign_indices_cb<T>;
}
if constexpr (std::is_move_constructible_v<T>) {
m.move_construct = move_construct_cb<T>;
m.move_construct_indices = move_construct_indices_cb<T>;
move_construct_ = move_construct_cb<T>;
move_construct_indices_ = move_construct_indices_cb<T>;
}
if constexpr (std::is_destructible_v<T>) {
if constexpr (std::is_move_assignable_v<T>) {
m.relocate_assign = relocate_assign_cb<T>;
m.relocate_assign_indices = relocate_assign_indices_cb<T>;
relocate_assign_ = relocate_assign_cb<T>;
relocate_assign_indices_ = relocate_assign_indices_cb<T>;
}
if constexpr (std::is_move_constructible_v<T>) {
m.relocate_construct = relocate_construct_cb<T>;
m.relocate_construct_indices = relocate_construct_indices_cb<T>;
relocate_construct_ = relocate_construct_cb<T>;
relocate_construct_indices_ = relocate_construct_indices_cb<T>;
}
}
if constexpr (std::is_copy_assignable_v<T>) {
m.fill_assign_indices = fill_assign_indices_cb<T>;
fill_assign_indices_ = fill_assign_indices_cb<T>;
}
if constexpr (std::is_copy_constructible_v<T>) {
m.fill_construct_indices = fill_construct_indices_cb<T>;
fill_construct_indices_ = fill_construct_indices_cb<T>;
}
if constexpr ((bool)(flags & CPPTypeFlags::Hashable)) {
m.hash = hash_cb<T>;
if constexpr ((bool)(Flags & CPPTypeFlags::Hashable)) {
hash_ = hash_cb<T>;
}
if constexpr ((bool)(flags & CPPTypeFlags::Printable)) {
m.print = print_cb<T>;
if constexpr ((bool)(Flags & CPPTypeFlags::Printable)) {
print_ = print_cb<T>;
}
if constexpr ((bool)(flags & CPPTypeFlags::EqualityComparable)) {
m.is_equal = is_equal_cb<T>;
if constexpr ((bool)(Flags & CPPTypeFlags::EqualityComparable)) {
is_equal_ = is_equal_cb<T>;
}
const CPPType *type = new CPPType(std::move(m));
return std::unique_ptr<const CPPType>(type);
alignment_mask_ = (uintptr_t)alignment_ - (uintptr_t)1;
has_special_member_functions_ = (default_construct_ && copy_construct_ && copy_assign_ &&
move_construct_ && move_assign_ && destruct_);
}
} // namespace blender::fn
#define MAKE_CPP_TYPE(IDENTIFIER, TYPE_NAME, FLAGS) \
template<> const blender::fn::CPPType &blender::fn::CPPType::get<TYPE_NAME>() \
template<> const blender::fn::CPPType &blender::fn::CPPType::get_impl<TYPE_NAME>() \
{ \
static std::unique_ptr<const CPPType> cpp_type = \
blender::fn::create_cpp_type<TYPE_NAME, FLAGS>(STRINGIFY(IDENTIFIER)); \
return *cpp_type; \
} \
/* Support using `CPPType::get<const T>()`. Otherwise the caller would have to remove const. */ \
template<> const blender::fn::CPPType &blender::fn::CPPType::get<const TYPE_NAME>() \
{ \
return blender::fn::CPPType::get<TYPE_NAME>(); \
static CPPType cpp_type{blender::fn::CPPTypeParam<TYPE_NAME, FLAGS>(), \
STRINGIFY(IDENTIFIER)}; \
return cpp_type; \
}

View File

@ -263,7 +263,7 @@ static Array<MFOutputSocket *> add_constant_folded_sockets(const MultiFunction &
const CPPType &cpp_type = data_type.single_type();
GMutableSpan array = params.computed_array(param_index);
void *buffer = array.data();
scope.add(buffer, array.type().members().destruct, AT);
scope.add(buffer, array.type().destruct_fn(), AT);
constant_fn = &scope.construct<CustomMF_GenericConstant>(AT, cpp_type, buffer);
break;

View File

@ -261,10 +261,12 @@ static void updateDepsgraph(GpencilModifierData *md,
else {
add_this_collection(ctx->scene->master_collection, ctx, mode);
}
DEG_add_object_relation(
ctx->node, ctx->scene->camera, DEG_OB_COMP_TRANSFORM, "Line Art Modifier");
DEG_add_object_relation(
ctx->node, ctx->scene->camera, DEG_OB_COMP_PARAMETERS, "Line Art Modifier");
if (ctx->scene->camera) {
DEG_add_object_relation(
ctx->node, ctx->scene->camera, DEG_OB_COMP_TRANSFORM, "Line Art Modifier");
DEG_add_object_relation(
ctx->node, ctx->scene->camera, DEG_OB_COMP_PARAMETERS, "Line Art Modifier");
}
}
static void foreachIDLink(GpencilModifierData *md, Object *ob, IDWalkFunc walk, void *userData)

View File

@ -452,8 +452,8 @@ static void compute_sss_translucence_kernel(const GPUSssKernelData *kd,
/* Distance from surface. */
float d = kd->max_radius * ((float)i + 0.00001f) / ((float)resolution);
/* For each distance d we compute the radiance incoming from an hypothetic parallel plane. */
/* Compute radius of the footprint on the hypothetic plane */
/* For each distance d we compute the radiance incoming from an hypothetical parallel plane. */
/* Compute radius of the footprint on the hypothetical plane. */
float r_fp = sqrtf(kd->max_radius * kd->max_radius - d * d);
float r_step = r_fp / INTEGRAL_RESOLUTION;
float area_accum = 0.0f;

View File

@ -778,6 +778,19 @@ static void rna_Space_show_region_toolbar_update(bContext *C, PointerRNA *ptr)
rna_Space_bool_from_region_flag_update_by_type(C, ptr, RGN_TYPE_TOOLS, RGN_FLAG_HIDDEN);
}
static bool rna_Space_show_region_tool_props_get(PointerRNA *ptr)
{
return !rna_Space_bool_from_region_flag_get_by_type(ptr, RGN_TYPE_TOOL_PROPS, RGN_FLAG_HIDDEN);
}
static void rna_Space_show_region_tool_props_set(PointerRNA *ptr, bool value)
{
rna_Space_bool_from_region_flag_set_by_type(ptr, RGN_TYPE_TOOL_PROPS, RGN_FLAG_HIDDEN, !value);
}
static void rna_Space_show_region_tool_props_update(bContext *C, PointerRNA *ptr)
{
rna_Space_bool_from_region_flag_update_by_type(C, ptr, RGN_TYPE_TOOL_PROPS, RGN_FLAG_HIDDEN);
}
/* Channels Region. */
static bool rna_Space_show_region_channels_get(PointerRNA *ptr)
{
@ -3196,6 +3209,10 @@ static void rna_def_space_generic_show_region_toggles(StructRNA *srna, int regio
region_type_mask &= ~(1 << RGN_TYPE_TOOLS);
DEF_SHOW_REGION_PROPERTY(show_region_toolbar, "Toolbar", "");
}
if (region_type_mask & (1 << RGN_TYPE_TOOL_PROPS)) {
region_type_mask &= ~(1 << RGN_TYPE_TOOL_PROPS);
DEF_SHOW_REGION_PROPERTY(show_region_tool_props, "Toolbar", "");
}
if (region_type_mask & (1 << RGN_TYPE_CHANNELS)) {
region_type_mask &= ~(1 << RGN_TYPE_CHANNELS);
DEF_SHOW_REGION_PROPERTY(show_region_channels, "Channels", "");
@ -6546,7 +6563,8 @@ static void rna_def_space_filebrowser(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "SpaceFile");
RNA_def_struct_ui_text(srna, "Space File Browser", "File browser space data");
rna_def_space_generic_show_region_toggles(srna, (1 << RGN_TYPE_TOOLS) | (1 << RGN_TYPE_UI));
rna_def_space_generic_show_region_toggles(
srna, (1 << RGN_TYPE_TOOLS) | (1 << RGN_TYPE_UI) | (1 << RGN_TYPE_TOOL_PROPS));
prop = RNA_def_property(srna, "browse_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_space_file_browse_mode_items);

View File

@ -721,17 +721,17 @@ static void initialize_group_input(NodesModifierData &nmd,
return;
}
if (nmd.settings.properties == nullptr) {
blender::nodes::socket_cpp_value_get(socket, r_value);
socket.typeinfo->get_geometry_nodes_cpp_value(socket, r_value);
return;
}
const IDProperty *property = IDP_GetPropertyFromGroup(nmd.settings.properties,
socket.identifier);
if (property == nullptr) {
blender::nodes::socket_cpp_value_get(socket, r_value);
socket.typeinfo->get_geometry_nodes_cpp_value(socket, r_value);
return;
}
if (!property_type->is_correct_type(*property)) {
blender::nodes::socket_cpp_value_get(socket, r_value);
socket.typeinfo->get_geometry_nodes_cpp_value(socket, r_value);
return;
}
property_type->init_cpp_value(*property, r_value);
@ -883,7 +883,7 @@ static GeometrySet compute_geometry(const DerivedNodeTree &tree,
/* Initialize remaining group inputs. */
for (const OutputSocketRef *socket : remaining_input_sockets) {
const CPPType &cpp_type = *blender::nodes::socket_cpp_type_get(*socket->typeinfo());
const CPPType &cpp_type = *socket->typeinfo()->get_geometry_nodes_cpp_type();
void *value_in = allocator.allocate(cpp_type.size(), cpp_type.alignment());
initialize_group_input(*nmd, *socket->bsocket(), cpp_type, value_in);
group_inputs.add_new({root_context, socket}, {cpp_type, value_in});

View File

@ -294,7 +294,11 @@ class LockedNode : NonCopyable, NonMovable {
static const CPPType *get_socket_cpp_type(const SocketRef &socket)
{
const CPPType *type = nodes::socket_cpp_type_get(*socket.typeinfo());
const bNodeSocketType *typeinfo = socket.typeinfo();
if (typeinfo->get_geometry_nodes_cpp_type == nullptr) {
return nullptr;
}
const CPPType *type = typeinfo->get_geometry_nodes_cpp_type();
if (type == nullptr) {
return nullptr;
}
@ -310,6 +314,12 @@ static const CPPType *get_socket_cpp_type(const DSocket socket)
return get_socket_cpp_type(*socket.socket_ref());
}
static void get_socket_value(const SocketRef &socket, void *r_value)
{
const bNodeSocketType *typeinfo = socket.typeinfo();
typeinfo->get_geometry_nodes_cpp_value(*socket.bsocket(), r_value);
}
static bool node_supports_laziness(const DNode node)
{
return node->typeinfo()->geometry_node_execute_supports_laziness;
@ -1363,10 +1373,9 @@ class GeometryNodesEvaluator {
{
LinearAllocator<> &allocator = local_allocators_.local();
bNodeSocket *bsocket = socket->bsocket();
const CPPType &type = *get_socket_cpp_type(socket);
void *buffer = allocator.allocate(type.size(), type.alignment());
blender::nodes::socket_cpp_value_get(*bsocket, buffer);
get_socket_value(*socket.socket_ref(), buffer);
if (type == required_type) {
return {type, buffer};

View File

@ -291,22 +291,22 @@ DefNode(GeometryNode, GEO_NODE_BOOLEAN, def_geo_boolean, "BOOLEAN", Boolean, "Bo
DefNode(GeometryNode, GEO_NODE_BOUNDING_BOX, 0, "BOUNDING_BOX", BoundBox, "Bounding Box", "")
DefNode(GeometryNode, GEO_NODE_COLLECTION_INFO, def_geo_collection_info, "COLLECTION_INFO", CollectionInfo, "Collection Info", "")
DefNode(GeometryNode, GEO_NODE_CONVEX_HULL, 0, "CONVEX_HULL", ConvexHull, "Convex Hull", "")
DefNode(GeometryNode, GEO_NODE_CURVE_ENDPOINTS, 0, "CURVE_ENDPOINTS", CurveEndpoints, "Curve Endpoints", "")
DefNode(GeometryNode, GEO_NODE_CURVE_LENGTH, 0, "CURVE_LENGTH", CurveLength, "Curve Length", "")
DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_BEZIER_SEGMENT, def_geo_curve_primitive_bezier_segment, "CURVE_PRIMITIVE_BEZIER_SEGMENT", CurvePrimitiveBezierSegment, "Bezier Segment", "")
DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_CIRCLE, def_geo_curve_primitive_circle, "CURVE_PRIMITIVE_CIRCLE", CurvePrimitiveCircle, "Curve Circle", "")
DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_LINE, def_geo_curve_primitive_line, "CURVE_PRIMITIVE_LINE", CurvePrimitiveLine, "Curve Line", "")
DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_QUADRILATERAL, def_geo_curve_primitive_quadrilateral, "CURVE_PRIMITIVE_QUADRILATERAL", CurvePrimitiveQuadrilateral, "Quadrilateral", "")
DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_QUADRATIC_BEZIER, 0, "CURVE_PRIMITIVE_QUADRATIC_BEZIER", CurveQuadraticBezier, "Quadratic Bezier", "")
DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_STAR, 0, "CURVE_PRIMITIVE_STAR", CurveStar, "Star", "")
DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_QUADRILATERAL, def_geo_curve_primitive_quadrilateral, "CURVE_PRIMITIVE_QUADRILATERAL", CurvePrimitiveQuadrilateral, "Quadrilateral", "")
DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_SPIRAL, 0, "CURVE_PRIMITIVE_SPIRAL", CurveSpiral, "Curve Spiral", "")
DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_STAR, 0, "CURVE_PRIMITIVE_STAR", CurveStar, "Star", "")
DefNode(GeometryNode, GEO_NODE_CURVE_RESAMPLE, def_geo_curve_resample, "CURVE_RESAMPLE", CurveResample, "Resample Curve", "")
DefNode(GeometryNode, GEO_NODE_CURVE_REVERSE, 0, "CURVE_REVERSE", CurveReverse, "Curve Reverse", "")
DefNode(GeometryNode, GEO_NODE_CURVE_SET_HANDLES, def_geo_curve_set_handles, "CURVE_SET_HANDLES", CurveSetHandles, "Set Handle Type", "")
DefNode(GeometryNode, GEO_NODE_CURVE_SUBDIVIDE, def_geo_curve_subdivide, "CURVE_SUBDIVIDE", CurveSubdivide, "Curve Subdivide", "")
DefNode(GeometryNode, GEO_NODE_CURVE_TO_MESH, 0, "CURVE_TO_MESH", CurveToMesh, "Curve to Mesh", "")
DefNode(GeometryNode, GEO_NODE_CURVE_TRIM, def_geo_curve_trim, "CURVE_TRIM", CurveTrim, "Curve Trim", "")
DefNode(GeometryNode, GEO_NODE_CURVE_REVERSE, 0, "CURVE_REVERSE", CurveReverse, "Curve Reverse", "")
DefNode(GeometryNode, GEO_NODE_CURVE_TO_POINTS, def_geo_curve_to_points, "CURVE_TO_POINTS", CurveToPoints, "Curve to Points", "")
DefNode(GeometryNode, GEO_NODE_CURVE_ENDPOINTS, 0, "CURVE_ENDPOINTS", CurveEndpoints, "Curve Endpoints", "")
DefNode(GeometryNode, GEO_NODE_CURVE_TRIM, def_geo_curve_trim, "CURVE_TRIM", CurveTrim, "Curve Trim", "")
DefNode(GeometryNode, GEO_NODE_DELETE_GEOMETRY, 0, "DELETE_GEOMETRY", DeleteGeometry, "Delete Geometry", "")
DefNode(GeometryNode, GEO_NODE_EDGE_SPLIT, 0, "EDGE_SPLIT", EdgeSplit, "Edge Split", "")
DefNode(GeometryNode, GEO_NODE_INPUT_MATERIAL, def_geo_input_material, "INPUT_MATERIAL", InputMaterial, "Material", "")
@ -322,6 +322,7 @@ DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_GRID, 0, "MESH_PRIMITIVE_GRID", Me
DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_ICO_SPHERE, 0, "MESH_PRIMITIVE_ICO_SPHERE", MeshIcoSphere, "Ico Sphere", "")
DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_LINE, def_geo_mesh_line, "MESH_PRIMITIVE_LINE", MeshLine, "Mesh Line", "")
DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_UV_SPHERE, 0, "MESH_PRIMITIVE_UV_SPHERE", MeshUVSphere, "UV Sphere", "")
DefNode(GeometryNode, GEO_NODE_MESH_SUBDIVIDE, 0, "MESH_SUBDIVIDE", MeshSubdivide, "Mesh Subdivide", "")
DefNode(GeometryNode, GEO_NODE_MESH_TO_CURVE, 0, "MESH_TO_CURVE", MeshToCurve, "Mesh to Curve", "")
DefNode(GeometryNode, GEO_NODE_OBJECT_INFO, def_geo_object_info, "OBJECT_INFO", ObjectInfo, "Object Info", "")
DefNode(GeometryNode, GEO_NODE_POINT_DISTRIBUTE, def_geo_point_distribute, "POINT_DISTRIBUTE", PointDistribute, "Point Distribute", "")
@ -334,7 +335,6 @@ DefNode(GeometryNode, GEO_NODE_POINTS_TO_VOLUME, def_geo_points_to_volume, "POIN
DefNode(GeometryNode, GEO_NODE_RAYCAST, def_geo_raycast, "RAYCAST", Raycast, "Raycast", "")
DefNode(GeometryNode, GEO_NODE_SELECT_BY_MATERIAL, 0, "SELECT_BY_MATERIAL", SelectByMaterial, "Select by Material", "")
DefNode(GeometryNode, GEO_NODE_SEPARATE_COMPONENTS, 0, "SEPARATE_COMPONENTS", SeparateComponents, "Separate Components", "")
DefNode(GeometryNode, GEO_NODE_MESH_SUBDIVIDE, 0, "MESH_SUBDIVIDE", MeshSubdivide, "Mesh Subdivide", "")
DefNode(GeometryNode, GEO_NODE_SUBDIVISION_SURFACE, 0, "SUBDIVISION_SURFACE", SubdivisionSurface, "Subdivision Surface", "")
DefNode(GeometryNode, GEO_NODE_SWITCH, def_geo_switch, "SWITCH", Switch, "Switch", "")
DefNode(GeometryNode, GEO_NODE_TRANSFORM, 0, "TRANSFORM", Transform, "Transform", "")

View File

@ -27,10 +27,8 @@ namespace blender::nodes {
using fn::CPPType;
using fn::MFDataType;
const CPPType *socket_cpp_type_get(const bNodeSocketType &stype);
std::optional<MFDataType> socket_mf_type_get(const bNodeSocketType &stype);
bool socket_is_mf_data_socket(const bNodeSocketType &stype);
bool socket_cpp_value_get(const bNodeSocket &socket, void *r_value);
void socket_expand_in_mf_network(SocketMFNetworkBuilder &builder);
} // namespace blender::nodes

View File

@ -204,7 +204,8 @@ static void get_closest_mesh_polygons(const Mesh &mesh,
Array<int> looptri_indices(positions.size());
get_closest_mesh_looptris(mesh, positions, looptri_indices, r_distances_sq, r_positions);
Span<MLoopTri> looptris = bke::mesh_surface_sample::get_mesh_looptris(mesh);
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
BKE_mesh_runtime_looptri_len(&mesh)};
for (const int i : positions.index_range()) {
const MLoopTri &looptri = looptris[looptri_indices[i]];
r_poly_indices[i] = looptri.poly;

View File

@ -150,7 +150,7 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords)
plConvexHullDelete(hull);
BKE_mesh_calc_normals(result);
BKE_mesh_normals_tag_dirty(result);
return result;
}

View File

@ -299,7 +299,7 @@ Mesh *create_cylinder_or_cone_mesh(const float radius_top,
mesh->medge[0].v1 = 0;
mesh->medge[0].v2 = 1;
mesh->medge[0].flag |= ME_LOOSEEDGE;
BKE_mesh_calc_normals(mesh);
BKE_mesh_normals_tag_dirty(mesh);
return mesh;
}
@ -534,12 +534,10 @@ Mesh *create_cylinder_or_cone_mesh(const float radius_top,
}
}
BKE_mesh_calc_normals(mesh);
BKE_mesh_normals_tag_dirty(mesh);
calculate_uvs(mesh, top_is_point, bottom_is_point, verts_num, fill_type);
BLI_assert(BKE_mesh_is_valid(mesh));
return mesh;
}

View File

@ -88,7 +88,7 @@ static void geo_node_mesh_subdivide_exec(GeoNodeExecParams params)
}
Mesh *mesh_out = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh_in);
BKE_mesh_calc_normals(mesh_out);
BKE_mesh_normals_tag_dirty(mesh_out);
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
mesh_component.replace(mesh_out);

View File

@ -81,13 +81,6 @@ static float3 normal_to_euler_rotation(const float3 normal)
return rotation;
}
static Span<MLoopTri> get_mesh_looptris(const Mesh &mesh)
{
const MLoopTri *looptris = BKE_mesh_runtime_looptri_ensure(&mesh);
const int looptris_len = BKE_mesh_runtime_looptri_len(&mesh);
return {looptris, looptris_len};
}
static void sample_mesh_surface(const Mesh &mesh,
const float4x4 &transform,
const float base_density,
@ -97,7 +90,8 @@ static void sample_mesh_surface(const Mesh &mesh,
Vector<float3> &r_bary_coords,
Vector<int> &r_looptri_indices)
{
Span<MLoopTri> looptris = get_mesh_looptris(mesh);
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
BKE_mesh_runtime_looptri_len(&mesh)};
for (const int looptri_index : looptris.index_range()) {
const MLoopTri &looptri = looptris[looptri_index];
@ -208,7 +202,8 @@ BLI_NOINLINE static void update_elimination_mask_based_on_density_factors(
Span<int> looptri_indices,
MutableSpan<bool> elimination_mask)
{
Span<MLoopTri> looptris = get_mesh_looptris(mesh);
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
BKE_mesh_runtime_looptri_len(&mesh)};
for (const int i : bary_coords.index_range()) {
if (elimination_mask[i]) {
continue;
@ -365,7 +360,8 @@ BLI_NOINLINE static void compute_special_attributes(Span<GeometryInstanceGroup>
const GeometrySet &set = set_group.geometry_set;
const MeshComponent &component = *set.get_component_for_read<MeshComponent>();
const Mesh &mesh = *component.get_for_read();
Span<MLoopTri> looptris = get_mesh_looptris(mesh);
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
BKE_mesh_runtime_looptri_len(&mesh)};
for (const float4x4 &transform : set_group.transforms) {
const int offset = instance_start_offsets[i_instance];

View File

@ -93,7 +93,7 @@ static void geo_node_subdivision_surface_exec(GeoNodeExecParams params)
}
Mesh *mesh_out = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh_in);
BKE_mesh_calc_normals(mesh_out);
BKE_mesh_normals_tag_dirty(mesh_out);
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
mesh_component.replace(mesh_out);

View File

@ -218,7 +218,7 @@ void GeoNodeExecParams::check_input_access(StringRef identifier,
BLI_assert_unreachable();
}
else if (requested_type != nullptr) {
const CPPType &expected_type = *socket_cpp_type_get(*found_socket->typeinfo);
const CPPType &expected_type = *found_socket->typeinfo->get_geometry_nodes_cpp_type();
if (*requested_type != expected_type) {
std::cout << "The requested type '" << requested_type->name() << "' is incorrect. Expected '"
<< expected_type.name() << "'.\n";
@ -258,7 +258,7 @@ void GeoNodeExecParams::check_output_access(StringRef identifier, const CPPType
BLI_assert_unreachable();
}
else {
const CPPType &expected_type = *socket_cpp_type_get(*found_socket->typeinfo);
const CPPType &expected_type = *found_socket->typeinfo->get_geometry_nodes_cpp_type();
if (value_type != expected_type) {
std::cout << "The value type '" << value_type.name() << "' is incorrect. Expected '"
<< expected_type.name() << "'.\n";

View File

@ -607,60 +607,74 @@ static bNodeSocketType *make_socket_type_virtual()
static bNodeSocketType *make_socket_type_bool()
{
bNodeSocketType *socktype = make_standard_socket_type(SOCK_BOOLEAN, PROP_NONE);
socktype->get_cpp_type = []() { return &blender::fn::CPPType::get<bool>(); };
socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) {
socktype->get_base_cpp_type = []() { return &blender::fn::CPPType::get<bool>(); };
socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) {
*(bool *)r_value = ((bNodeSocketValueBoolean *)socket.default_value)->value;
};
socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type;
socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value;
return socktype;
}
static bNodeSocketType *make_socket_type_float(PropertySubType subtype)
{
bNodeSocketType *socktype = make_standard_socket_type(SOCK_FLOAT, subtype);
socktype->get_cpp_type = []() { return &blender::fn::CPPType::get<float>(); };
socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) {
socktype->get_base_cpp_type = []() { return &blender::fn::CPPType::get<float>(); };
socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) {
*(float *)r_value = ((bNodeSocketValueFloat *)socket.default_value)->value;
};
socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type;
socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value;
return socktype;
}
static bNodeSocketType *make_socket_type_int(PropertySubType subtype)
{
bNodeSocketType *socktype = make_standard_socket_type(SOCK_INT, subtype);
socktype->get_cpp_type = []() { return &blender::fn::CPPType::get<int>(); };
socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) {
socktype->get_base_cpp_type = []() { return &blender::fn::CPPType::get<int>(); };
socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) {
*(int *)r_value = ((bNodeSocketValueInt *)socket.default_value)->value;
};
socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type;
socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value;
return socktype;
}
static bNodeSocketType *make_socket_type_vector(PropertySubType subtype)
{
bNodeSocketType *socktype = make_standard_socket_type(SOCK_VECTOR, subtype);
socktype->get_cpp_type = []() { return &blender::fn::CPPType::get<blender::float3>(); };
socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) {
socktype->get_base_cpp_type = []() { return &blender::fn::CPPType::get<blender::float3>(); };
socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) {
*(blender::float3 *)r_value = ((bNodeSocketValueVector *)socket.default_value)->value;
};
socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type;
socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value;
return socktype;
}
static bNodeSocketType *make_socket_type_rgba()
{
bNodeSocketType *socktype = make_standard_socket_type(SOCK_RGBA, PROP_NONE);
socktype->get_cpp_type = []() { return &blender::fn::CPPType::get<blender::ColorGeometry4f>(); };
socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) {
socktype->get_base_cpp_type = []() {
return &blender::fn::CPPType::get<blender::ColorGeometry4f>();
};
socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) {
*(blender::ColorGeometry4f *)r_value = ((bNodeSocketValueRGBA *)socket.default_value)->value;
};
socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type;
socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value;
return socktype;
}
static bNodeSocketType *make_socket_type_string()
{
bNodeSocketType *socktype = make_standard_socket_type(SOCK_STRING, PROP_NONE);
socktype->get_cpp_type = []() { return &blender::fn::CPPType::get<std::string>(); };
socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) {
socktype->get_base_cpp_type = []() { return &blender::fn::CPPType::get<std::string>(); };
socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) {
new (r_value) std::string(((bNodeSocketValueString *)socket.default_value)->value);
};
socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type;
socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value;
return socktype;
}
@ -672,50 +686,60 @@ MAKE_CPP_TYPE(Material, Material *, CPPTypeFlags::BasicType)
static bNodeSocketType *make_socket_type_object()
{
bNodeSocketType *socktype = make_standard_socket_type(SOCK_OBJECT, PROP_NONE);
socktype->get_cpp_type = []() { return &blender::fn::CPPType::get<Object *>(); };
socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) {
socktype->get_base_cpp_type = []() { return &blender::fn::CPPType::get<Object *>(); };
socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) {
*(Object **)r_value = ((bNodeSocketValueObject *)socket.default_value)->value;
};
socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type;
socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value;
return socktype;
}
static bNodeSocketType *make_socket_type_geometry()
{
bNodeSocketType *socktype = make_standard_socket_type(SOCK_GEOMETRY, PROP_NONE);
socktype->get_cpp_type = []() { return &blender::fn::CPPType::get<GeometrySet>(); };
socktype->get_cpp_value = [](const bNodeSocket &UNUSED(socket), void *r_value) {
socktype->get_base_cpp_type = []() { return &blender::fn::CPPType::get<GeometrySet>(); };
socktype->get_base_cpp_value = [](const bNodeSocket &UNUSED(socket), void *r_value) {
new (r_value) GeometrySet();
};
socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type;
socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value;
return socktype;
}
static bNodeSocketType *make_socket_type_collection()
{
bNodeSocketType *socktype = make_standard_socket_type(SOCK_COLLECTION, PROP_NONE);
socktype->get_cpp_type = []() { return &blender::fn::CPPType::get<Collection *>(); };
socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) {
socktype->get_base_cpp_type = []() { return &blender::fn::CPPType::get<Collection *>(); };
socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) {
*(Collection **)r_value = ((bNodeSocketValueCollection *)socket.default_value)->value;
};
socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type;
socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value;
return socktype;
}
static bNodeSocketType *make_socket_type_texture()
{
bNodeSocketType *socktype = make_standard_socket_type(SOCK_TEXTURE, PROP_NONE);
socktype->get_cpp_type = []() { return &blender::fn::CPPType::get<Tex *>(); };
socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) {
socktype->get_base_cpp_type = []() { return &blender::fn::CPPType::get<Tex *>(); };
socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) {
*(Tex **)r_value = ((bNodeSocketValueTexture *)socket.default_value)->value;
};
socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type;
socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value;
return socktype;
}
static bNodeSocketType *make_socket_type_material()
{
bNodeSocketType *socktype = make_standard_socket_type(SOCK_MATERIAL, PROP_NONE);
socktype->get_cpp_type = []() { return &blender::fn::CPPType::get<Material *>(); };
socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) {
socktype->get_base_cpp_type = []() { return &blender::fn::CPPType::get<Material *>(); };
socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) {
*(Material **)r_value = ((bNodeSocketValueMaterial *)socket.default_value)->value;
};
socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type;
socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value;
return socktype;
}

View File

@ -19,17 +19,9 @@
namespace blender::nodes {
const CPPType *socket_cpp_type_get(const bNodeSocketType &stype)
{
if (stype.get_cpp_type != nullptr) {
return stype.get_cpp_type();
}
return nullptr;
}
std::optional<MFDataType> socket_mf_type_get(const bNodeSocketType &stype)
{
const CPPType *cpp_type = socket_cpp_type_get(stype);
const CPPType *cpp_type = stype.get_base_cpp_type ? stype.get_base_cpp_type() : nullptr;
if (cpp_type != nullptr) {
return MFDataType::ForSingle(*cpp_type);
}
@ -41,32 +33,23 @@ bool socket_is_mf_data_socket(const bNodeSocketType &stype)
if (!socket_mf_type_get(stype).has_value()) {
return false;
}
if (stype.expand_in_mf_network == nullptr && stype.get_cpp_value == nullptr) {
if (stype.expand_in_mf_network == nullptr && stype.get_base_cpp_value == nullptr) {
return false;
}
return true;
}
bool socket_cpp_value_get(const bNodeSocket &socket, void *r_value)
{
if (socket.typeinfo->get_cpp_value != nullptr) {
socket.typeinfo->get_cpp_value(socket, r_value);
return true;
}
return false;
}
void socket_expand_in_mf_network(SocketMFNetworkBuilder &builder)
{
bNodeSocket &socket = builder.bsocket();
if (socket.typeinfo->expand_in_mf_network != nullptr) {
socket.typeinfo->expand_in_mf_network(builder);
}
else if (socket.typeinfo->get_cpp_value != nullptr) {
const CPPType &type = *socket_cpp_type_get(*socket.typeinfo);
else if (socket.typeinfo->get_base_cpp_value != nullptr) {
const CPPType &type = *socket.typeinfo->get_base_cpp_type();
void *buffer = builder.resource_scope().linear_allocator().allocate(type.size(),
type.alignment());
socket.typeinfo->get_cpp_value(socket, buffer);
socket.typeinfo->get_base_cpp_value(socket, buffer);
builder.set_constant_value(type, buffer);
}
else {

View File

@ -2204,7 +2204,7 @@ bool SIM_mass_spring_force_spring_bending_hair(Implicit_Data *data,
world_to_root_v3(data, j, goal, target);
spring_hairbend_forces(data, i, j, k, goal, stiffness, damping, k, vecnull, vecnull, fk);
negate_v3_v3(fj, fk); /* counterforce */
negate_v3_v3(fj, fk); /* Counter-force. */
spring_hairbend_estimate_dfdx(data, i, j, k, goal, stiffness, damping, i, dfk_dxi);
spring_hairbend_estimate_dfdx(data, i, j, k, goal, stiffness, damping, j, dfk_dxj);

View File

@ -34,6 +34,7 @@
#include "BLI_sys_types.h"
#include "DNA_windowmanager_types.h"
#include "WM_keymap.h"
#include "WM_types.h"
#ifdef __cplusplus
extern "C" {
@ -705,13 +706,13 @@ void WM_event_drag_image(struct wmDrag *, struct ImBuf *, float scale, int sx, i
void WM_drag_free(struct wmDrag *drag);
void WM_drag_data_free(int dragtype, void *poin);
void WM_drag_free_list(struct ListBase *lb);
struct wmDropBox *WM_dropbox_add(
ListBase *lb,
const char *idname,
bool (*poll)(struct bContext *, struct wmDrag *, const struct wmEvent *event, const char **),
bool (*poll)(struct bContext *, struct wmDrag *, const struct wmEvent *event),
void (*copy)(struct wmDrag *, struct wmDropBox *),
void (*cancel)(struct Main *, struct wmDrag *, struct wmDropBox *));
void (*cancel)(struct Main *, struct wmDrag *, struct wmDropBox *),
WMDropboxTooltipFunc tooltip);
ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid);
/* ID drag and drop */

View File

@ -114,6 +114,7 @@ struct bContext;
struct wmEvent;
struct wmOperator;
struct wmWindowManager;
struct wmDrag;
#include "BLI_compiler_attrs.h"
#include "DNA_listBase.h"
@ -934,6 +935,10 @@ typedef struct wmDragAsset {
int import_type; /* eFileAssetImportType */
} wmDragAsset;
typedef char *(*WMDropboxTooltipFunc)(struct bContext *,
struct wmDrag *,
const struct wmEvent *event);
typedef struct wmDrag {
struct wmDrag *next, *prev;
@ -949,8 +954,8 @@ typedef struct wmDrag {
float scale;
int sx, sy;
/** If set, draws operator name. */
char opname[200];
/** If filled, draws operator tooltip/operator name. */
char tooltip[200];
unsigned int flags;
/** List of wmDragIDs, all are guaranteed to have the same ID type. */
@ -964,8 +969,8 @@ typedef struct wmDrag {
typedef struct wmDropBox {
struct wmDropBox *next, *prev;
/** Test if the dropbox is active, then can print optype name. */
bool (*poll)(struct bContext *, struct wmDrag *, const wmEvent *, const char **);
/** Test if the dropbox is active. */
bool (*poll)(struct bContext *, struct wmDrag *, const wmEvent *);
/** Before exec, this copies drag info to #wmDrop properties. */
void (*copy)(struct wmDrag *, struct wmDropBox *);
@ -976,6 +981,9 @@ typedef struct wmDropBox {
*/
void (*cancel)(struct Main *, struct wmDrag *, struct wmDropBox *);
/** Custom tooltip shown during dragging. */
WMDropboxTooltipFunc tooltip;
/**
* If poll succeeds, operator is called.
* Not saved in file, so can be pointer.

View File

@ -96,14 +96,16 @@ ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid)
wmDropBox *WM_dropbox_add(ListBase *lb,
const char *idname,
bool (*poll)(bContext *, wmDrag *, const wmEvent *, const char **),
bool (*poll)(bContext *, wmDrag *, const wmEvent *),
void (*copy)(wmDrag *, wmDropBox *),
void (*cancel)(struct Main *, wmDrag *, wmDropBox *))
void (*cancel)(struct Main *, wmDrag *, wmDropBox *),
WMDropboxTooltipFunc tooltip)
{
wmDropBox *drop = MEM_callocN(sizeof(wmDropBox), "wmDropBox");
drop->poll = poll;
drop->copy = copy;
drop->cancel = cancel;
drop->tooltip = tooltip;
drop->ot = WM_operatortype_find(idname, 0);
drop->opcontext = WM_OP_INVOKE_DEFAULT;
@ -218,22 +220,36 @@ void WM_drag_free_list(struct ListBase *lb)
}
}
static const char *dropbox_active(bContext *C,
ListBase *handlers,
wmDrag *drag,
const wmEvent *event)
static char *dropbox_tooltip(bContext *C,
wmDrag *drag,
const wmEvent *event,
const wmDropBox *drop)
{
char *tooltip = NULL;
if (drop->tooltip) {
tooltip = drop->tooltip(C, drag, event);
}
if (!tooltip) {
tooltip = BLI_strdup(WM_operatortype_name(drop->ot, drop->ptr));
}
/* XXX Doing translation here might not be ideal, but later we have no more
* access to ot (and hence op context)... */
return tooltip;
}
static wmDropBox *dropbox_active(bContext *C,
ListBase *handlers,
wmDrag *drag,
const wmEvent *event)
{
LISTBASE_FOREACH (wmEventHandler *, handler_base, handlers) {
if (handler_base->type == WM_HANDLER_TYPE_DROPBOX) {
wmEventHandler_Dropbox *handler = (wmEventHandler_Dropbox *)handler_base;
if (handler->dropboxes) {
LISTBASE_FOREACH (wmDropBox *, drop, handler->dropboxes) {
const char *tooltip = NULL;
if (drop->poll(C, drag, event, &tooltip) &&
if (drop->poll(C, drag, event) &&
WM_operator_poll_context(C, drop->ot, drop->opcontext)) {
/* XXX Doing translation here might not be ideal, but later we have no more
* access to ot (and hence op context)... */
return (tooltip) ? tooltip : WM_operatortype_name(drop->ot, drop->ptr);
return drop;
}
}
}
@ -242,29 +258,22 @@ static const char *dropbox_active(bContext *C,
return NULL;
}
/* return active operator name when mouse is in box */
static const char *wm_dropbox_active(bContext *C, wmDrag *drag, const wmEvent *event)
/* return active operator tooltip/name when mouse is in box */
static char *wm_dropbox_active(bContext *C, wmDrag *drag, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
ScrArea *area = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
const char *name;
name = dropbox_active(C, &win->handlers, drag, event);
if (name) {
return name;
wmDropBox *drop = dropbox_active(C, &win->handlers, drag, event);
if (!drop) {
ScrArea *area = CTX_wm_area(C);
drop = dropbox_active(C, &area->handlers, drag, event);
}
name = dropbox_active(C, &area->handlers, drag, event);
if (name) {
return name;
if (!drop) {
ARegion *region = CTX_wm_region(C);
drop = dropbox_active(C, &region->handlers, drag, event);
}
name = dropbox_active(C, &region->handlers, drag, event);
if (name) {
return name;
if (drop) {
return dropbox_tooltip(C, drag, event, drop);
}
return NULL;
}
@ -279,17 +288,18 @@ static void wm_drop_operator_options(bContext *C, wmDrag *drag, const wmEvent *e
return;
}
drag->opname[0] = 0;
drag->tooltip[0] = 0;
/* check buttons (XXX todo rna and value) */
if (UI_but_active_drop_name(C)) {
BLI_strncpy(drag->opname, IFACE_("Paste name"), sizeof(drag->opname));
BLI_strncpy(drag->tooltip, IFACE_("Paste name"), sizeof(drag->tooltip));
}
else {
const char *opname = wm_dropbox_active(C, drag, event);
char *tooltip = wm_dropbox_active(C, drag, event);
if (opname) {
BLI_strncpy(drag->opname, opname, sizeof(drag->opname));
if (tooltip) {
BLI_strncpy(drag->tooltip, tooltip, sizeof(drag->tooltip));
MEM_freeN(tooltip);
// WM_cursor_modal_set(win, WM_CURSOR_COPY);
}
// else
@ -584,7 +594,7 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
}
/* operator name with roundbox */
if (drag->opname[0]) {
if (drag->tooltip[0]) {
if (drag->imb) {
x = cursorx - drag->sx / 2;
@ -611,7 +621,7 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
drag_rect_minmax(rect, x, y, x + w, y + iconsize);
}
else {
wm_drop_operator_draw(drag->opname, x, y);
wm_drop_operator_draw(drag->tooltip, x, y);
}
}
}

View File

@ -2851,8 +2851,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
if (event->custom == EVT_DATA_DRAGDROP) {
ListBase *lb = (ListBase *)event->customdata;
LISTBASE_FOREACH (wmDrag *, drag, lb) {
const char *tooltip = NULL;
if (drop->poll(C, drag, event, &tooltip)) {
if (drop->poll(C, drag, event)) {
/* Optionally copy drag information to operator properties. Don't call it if the
* operator fails anyway, it might do more than just set properties (e.g.
* typically import an asset). */

View File

@ -25,7 +25,7 @@ import sys
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from modules.mesh_test import BlendFileTest
geo_node_test = BlendFileTest("test_object", "expected_object")
geo_node_test = BlendFileTest("test_object", "expected_object", threshold=1e-4)
result = geo_node_test.run_test()
# Telling `ctest` about the failed test by raising Exception.