Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Vazquez <blendergit@gmail.com>2020-01-23 18:56:26 +0300
committerAntonio Vazquez <blendergit@gmail.com>2020-01-23 18:56:26 +0300
commitfb671035be082a67e6ffc58fb098c0d5140ba6b0 (patch)
treed8befc157c786d22c4ae66aa490b990adc7958ef
parent8482ba6d2e1a97e038175a7fb693ed40c03ca5d9 (diff)
parentd9d11e2faf0502eab215f8f13661972f9b459d3a (diff)
Merge branch 'blender-v2.82-release'
-rw-r--r--intern/cycles/device/device_optix.cpp3
-rw-r--r--intern/cycles/util/util_math_float4.h5
-rw-r--r--intern/cycles/util/util_transform.cpp36
-rw-r--r--intern/mantaflow/intern/MANTA_main.cpp261
-rw-r--r--release/scripts/startup/bl_ui/properties_particle.py5
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide_edgering.c5
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl14
-rw-r--r--source/blender/draw/engines/overlay/overlay_extra.c5
-rw-r--r--source/blender/draw/intern/draw_cache.c28
-rw-r--r--source/blender/editors/gpencil/gpencil_brush.c9
10 files changed, 206 insertions, 165 deletions
diff --git a/intern/cycles/device/device_optix.cpp b/intern/cycles/device/device_optix.cpp
index 6306f747b33..c1106b367ca 100644
--- a/intern/cycles/device/device_optix.cpp
+++ b/intern/cycles/device/device_optix.cpp
@@ -1461,6 +1461,9 @@ class OptiXDevice : public Device {
srt_data[i].a = decomp[i].z.x; // scale.x.y
srt_data[i].b = decomp[i].z.y; // scale.x.z
srt_data[i].c = decomp[i].w.x; // scale.y.z
+ assert(decomp[i].z.z == 0.0f); // scale.y.x
+ assert(decomp[i].w.y == 0.0f); // scale.z.x
+ assert(decomp[i].w.z == 0.0f); // scale.z.y
// Pivot point
srt_data[i].pvx = 0.0f;
diff --git a/intern/cycles/util/util_math_float4.h b/intern/cycles/util/util_math_float4.h
index bc5322a22bb..cd4b3e3b74c 100644
--- a/intern/cycles/util/util_math_float4.h
+++ b/intern/cycles/util/util_math_float4.h
@@ -179,6 +179,11 @@ ccl_device_inline float4 operator+=(float4 &a, const float4 &b)
return a = a + b;
}
+ccl_device_inline float4 operator-=(float4 &a, const float4 &b)
+{
+ return a = a - b;
+}
+
ccl_device_inline float4 operator*=(float4 &a, const float4 &b)
{
return a = a * b;
diff --git a/intern/cycles/util/util_transform.cpp b/intern/cycles/util/util_transform.cpp
index 5d64e08b022..302a8a386ac 100644
--- a/intern/cycles/util/util_transform.cpp
+++ b/intern/cycles/util/util_transform.cpp
@@ -227,6 +227,7 @@ static void transform_decompose(DecomposedTransform *decomp, const Transform *tf
M.y.w = 0.0f;
M.z.w = 0.0f;
+#if 0
Transform R = M;
float norm;
int iteration = 0;
@@ -260,6 +261,41 @@ static void transform_decompose(DecomposedTransform *decomp, const Transform *tf
decomp->y.w = scale.x.x;
decomp->z = make_float4(scale.x.y, scale.x.z, scale.y.x, scale.y.y);
decomp->w = make_float4(scale.y.z, scale.z.x, scale.z.y, scale.z.z);
+#else
+ float3 colx = transform_get_column(&M, 0);
+ float3 coly = transform_get_column(&M, 1);
+ float3 colz = transform_get_column(&M, 2);
+
+ /* extract scale and shear first */
+ float3 scale, shear;
+ scale.x = len(colx);
+ colx /= scale.x;
+ shear.z = dot(colx, coly);
+ coly -= shear.z * colx;
+ scale.y = len(coly);
+ coly /= scale.y;
+ shear.y = dot(colx, colz);
+ colz -= shear.y * colx;
+ shear.x = dot(coly, colz);
+ colz -= shear.x * coly;
+ scale.z = len(colz);
+ colz /= scale.z;
+
+ transform_set_column(&M, 0, colx);
+ transform_set_column(&M, 1, coly);
+ transform_set_column(&M, 2, colz);
+
+ if (transform_negative_scale(M)) {
+ scale *= -1.0f;
+ M = M * transform_scale(-1.0f, -1.0f, -1.0f);
+ }
+
+ decomp->x = transform_to_quat(M);
+
+ decomp->y.w = scale.x;
+ decomp->z = make_float4(shear.z, shear.y, 0.0f, scale.y);
+ decomp->w = make_float4(shear.x, 0.0f, 0.0f, scale.z);
+#endif
}
void transform_motion_decompose(DecomposedTransform *decomp, const Transform *motion, size_t size)
diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp
index 05e6999c193..024c562e64c 100644
--- a/intern/mantaflow/intern/MANTA_main.cpp
+++ b/intern/mantaflow/intern/MANTA_main.cpp
@@ -2008,8 +2008,13 @@ void MANTA::exportLiquidScript(FluidModifierData *mmd)
myfile.close();
}
-/* Call Mantaflow python functions through this function. Use isAttribute for object attributes,
- * e.g. s.cfl (here 's' is varname, 'cfl' functionName, and isAttribute true) */
+/* Call Mantaflow Python functions through this function. Use isAttribute for object attributes,
+ * e.g. s.cfl (here 's' is varname, 'cfl' functionName, and isAttribute true) or
+ * grid.getDataPointer (here 's' is varname, 'getDataPointer' functionName, and isAttribute
+ * false)
+ *
+ * Important! Return value: New reference or nullptr
+ * Caller of this function needs to handle reference count of returned object. */
static PyObject *callPythonFunction(std::string varName,
std::string functionName,
bool isAttribute = false)
@@ -2051,41 +2056,63 @@ static PyObject *callPythonFunction(std::string varName,
return (!isAttribute) ? returnedValue : func;
}
-static char *pyObjectToString(PyObject *inputObject)
+/* Argument of this function may be a nullptr.
+ * If it's not function will handle the reference count decrement of that argument. */
+static void *pyObjectToPointer(PyObject *inputObject)
{
+ if (!inputObject)
+ return nullptr;
+
PyGILState_STATE gilstate = PyGILState_Ensure();
PyObject *encoded = PyUnicode_AsUTF8String(inputObject);
char *result = PyBytes_AsString(encoded);
- /* Do not decref (i.e. Py_DECREF(encoded)) of string 'encoded' PyObject.
- * Otherwise those objects will be invalidated too early (see T72894).
- * Reference count of those Python objects will be decreased with 'del' in Python scripts. */
Py_DECREF(inputObject);
+ std::string str(result);
+ std::istringstream in(str);
+ void *dataPointer = nullptr;
+ in >> dataPointer;
+
+ Py_DECREF(encoded);
+
PyGILState_Release(gilstate);
- return result;
+ return dataPointer;
}
+/* Argument of this function may be a nullptr.
+ * If it's not function will handle the reference count decrement of that argument. */
static double pyObjectToDouble(PyObject *inputObject)
{
- // Cannot use PyFloat_AsDouble() since its error check crashes - likely because of Real (aka
- // float) type in Mantaflow
- return PyFloat_AS_DOUBLE(inputObject);
+ if (!inputObject)
+ return 0.0;
+
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+
+ /* Cannot use PyFloat_AsDouble() since its error check crashes.
+ * Likely because of typedef 'Real' for 'float' types in Mantaflow. */
+ double result = PyFloat_AS_DOUBLE(inputObject);
+ Py_DECREF(inputObject);
+
+ PyGILState_Release(gilstate);
+ return result;
}
+/* Argument of this function may be a nullptr.
+ * If it's not function will handle the reference count decrement of that argument. */
static long pyObjectToLong(PyObject *inputObject)
{
- return PyLong_AsLong(inputObject);
-}
+ if (!inputObject)
+ return 0;
-static void *stringToPointer(char *inputString)
-{
- std::string str(inputString);
- std::istringstream in(str);
- void *dataPointer = nullptr;
- in >> dataPointer;
- return dataPointer;
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+
+ long result = PyLong_AsLong(inputObject);
+ Py_DECREF(inputObject);
+
+ PyGILState_Release(gilstate);
+ return result;
}
int MANTA::getFrame()
@@ -2109,7 +2136,7 @@ float MANTA::getTimestep()
std::string id = std::to_string(mCurrentID);
std::string solver = "s" + id;
- return pyObjectToDouble(callPythonFunction(solver, func, true));
+ return (float)pyObjectToDouble(callPythonFunction(solver, func, true));
}
bool MANTA::needsRealloc(FluidModifierData *mmd)
@@ -2527,158 +2554,108 @@ void MANTA::updatePointers()
std::string mesh_ext2 = "_" + mesh2;
std::string noise_ext = "_" + noise;
- mObstacle = (int *)stringToPointer(
- pyObjectToString(callPythonFunction("flags" + solver_ext, func)));
- mPhiIn = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("phiIn" + solver_ext, func)));
- mVelocityX = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("x_vel" + solver_ext, func)));
- mVelocityY = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("y_vel" + solver_ext, func)));
- mVelocityZ = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("z_vel" + solver_ext, func)));
- mForceX = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("x_force" + solver_ext, func)));
- mForceY = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("y_force" + solver_ext, func)));
- mForceZ = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("z_force" + solver_ext, func)));
+ mObstacle = (int *)pyObjectToPointer(callPythonFunction("flags" + solver_ext, func));
+ mPhiIn = (float *)pyObjectToPointer(callPythonFunction("phiIn" + solver_ext, func));
+ mVelocityX = (float *)pyObjectToPointer(callPythonFunction("x_vel" + solver_ext, func));
+ mVelocityY = (float *)pyObjectToPointer(callPythonFunction("y_vel" + solver_ext, func));
+ mVelocityZ = (float *)pyObjectToPointer(callPythonFunction("z_vel" + solver_ext, func));
+ mForceX = (float *)pyObjectToPointer(callPythonFunction("x_force" + solver_ext, func));
+ mForceY = (float *)pyObjectToPointer(callPythonFunction("y_force" + solver_ext, func));
+ mForceZ = (float *)pyObjectToPointer(callPythonFunction("z_force" + solver_ext, func));
if (mUsingOutflow) {
- mPhiOutIn = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("phiOutIn" + solver_ext, func)));
+ mPhiOutIn = (float *)pyObjectToPointer(callPythonFunction("phiOutIn" + solver_ext, func));
}
if (mUsingObstacle) {
- mPhiObsIn = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("phiObsIn" + solver_ext, func)));
- mObVelocityX = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("x_obvel" + solver_ext, func)));
- mObVelocityY = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("y_obvel" + solver_ext, func)));
- mObVelocityZ = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("z_obvel" + solver_ext, func)));
- mNumObstacle = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("numObs" + solver_ext, func)));
+ mPhiObsIn = (float *)pyObjectToPointer(callPythonFunction("phiObsIn" + solver_ext, func));
+ mObVelocityX = (float *)pyObjectToPointer(callPythonFunction("x_obvel" + solver_ext, func));
+ mObVelocityY = (float *)pyObjectToPointer(callPythonFunction("y_obvel" + solver_ext, func));
+ mObVelocityZ = (float *)pyObjectToPointer(callPythonFunction("z_obvel" + solver_ext, func));
+ mNumObstacle = (float *)pyObjectToPointer(callPythonFunction("numObs" + solver_ext, func));
}
if (mUsingGuiding) {
- mPhiGuideIn = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("phiGuideIn" + solver_ext, func)));
- mGuideVelocityX = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("x_guidevel" + solver_ext, func)));
- mGuideVelocityY = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("y_guidevel" + solver_ext, func)));
- mGuideVelocityZ = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("z_guidevel" + solver_ext, func)));
- mNumGuide = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("numGuides" + solver_ext, func)));
+ mPhiGuideIn = (float *)pyObjectToPointer(callPythonFunction("phiGuideIn" + solver_ext, func));
+ mGuideVelocityX = (float *)pyObjectToPointer(
+ callPythonFunction("x_guidevel" + solver_ext, func));
+ mGuideVelocityY = (float *)pyObjectToPointer(
+ callPythonFunction("y_guidevel" + solver_ext, func));
+ mGuideVelocityZ = (float *)pyObjectToPointer(
+ callPythonFunction("z_guidevel" + solver_ext, func));
+ mNumGuide = (float *)pyObjectToPointer(callPythonFunction("numGuides" + solver_ext, func));
}
if (mUsingInvel) {
- mInVelocityX = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("x_invel" + solver_ext, func)));
- mInVelocityY = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("y_invel" + solver_ext, func)));
- mInVelocityZ = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("z_invel" + solver_ext, func)));
+ mInVelocityX = (float *)pyObjectToPointer(callPythonFunction("x_invel" + solver_ext, func));
+ mInVelocityY = (float *)pyObjectToPointer(callPythonFunction("y_invel" + solver_ext, func));
+ mInVelocityZ = (float *)pyObjectToPointer(callPythonFunction("z_invel" + solver_ext, func));
}
if (mUsingSmoke) {
- mDensity = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("density" + solver_ext, func)));
- mDensityIn = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("densityIn" + solver_ext, func)));
- mShadow = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("shadow" + solver_ext, func)));
- mEmissionIn = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("emissionIn" + solver_ext, func)));
+ mDensity = (float *)pyObjectToPointer(callPythonFunction("density" + solver_ext, func));
+ mDensityIn = (float *)pyObjectToPointer(callPythonFunction("densityIn" + solver_ext, func));
+ mShadow = (float *)pyObjectToPointer(callPythonFunction("shadow" + solver_ext, func));
+ mEmissionIn = (float *)pyObjectToPointer(callPythonFunction("emissionIn" + solver_ext, func));
}
if (mUsingSmoke && mUsingHeat) {
- mHeat = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("heat" + solver_ext, func)));
- mHeatIn = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("heatIn" + solver_ext, func)));
+ mHeat = (float *)pyObjectToPointer(callPythonFunction("heat" + solver_ext, func));
+ mHeatIn = (float *)pyObjectToPointer(callPythonFunction("heatIn" + solver_ext, func));
}
if (mUsingSmoke && mUsingFire) {
- mFlame = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("flame" + solver_ext, func)));
- mFuel = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("fuel" + solver_ext, func)));
- mReact = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("react" + solver_ext, func)));
- mFuelIn = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("fuelIn" + solver_ext, func)));
- mReactIn = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("reactIn" + solver_ext, func)));
+ mFlame = (float *)pyObjectToPointer(callPythonFunction("flame" + solver_ext, func));
+ mFuel = (float *)pyObjectToPointer(callPythonFunction("fuel" + solver_ext, func));
+ mReact = (float *)pyObjectToPointer(callPythonFunction("react" + solver_ext, func));
+ mFuelIn = (float *)pyObjectToPointer(callPythonFunction("fuelIn" + solver_ext, func));
+ mReactIn = (float *)pyObjectToPointer(callPythonFunction("reactIn" + solver_ext, func));
}
if (mUsingSmoke && mUsingColors) {
- mColorR = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("color_r" + solver_ext, func)));
- mColorG = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("color_g" + solver_ext, func)));
- mColorB = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("color_b" + solver_ext, func)));
- mColorRIn = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("color_r_in" + solver_ext, func)));
- mColorGIn = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("color_g_in" + solver_ext, func)));
- mColorBIn = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("color_b_in" + solver_ext, func)));
+ mColorR = (float *)pyObjectToPointer(callPythonFunction("color_r" + solver_ext, func));
+ mColorG = (float *)pyObjectToPointer(callPythonFunction("color_g" + solver_ext, func));
+ mColorB = (float *)pyObjectToPointer(callPythonFunction("color_b" + solver_ext, func));
+ mColorRIn = (float *)pyObjectToPointer(callPythonFunction("color_r_in" + solver_ext, func));
+ mColorGIn = (float *)pyObjectToPointer(callPythonFunction("color_g_in" + solver_ext, func));
+ mColorBIn = (float *)pyObjectToPointer(callPythonFunction("color_b_in" + solver_ext, func));
}
if (mUsingSmoke && mUsingNoise) {
- mDensityHigh = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("density" + noise_ext, func)));
- mTextureU = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("texture_u" + solver_ext, func)));
- mTextureV = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("texture_v" + solver_ext, func)));
- mTextureW = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("texture_w" + solver_ext, func)));
- mTextureU2 = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("texture_u2" + solver_ext, func)));
- mTextureV2 = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("texture_v2" + solver_ext, func)));
- mTextureW2 = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("texture_w2" + solver_ext, func)));
+ mDensityHigh = (float *)pyObjectToPointer(callPythonFunction("density" + noise_ext, func));
+ mTextureU = (float *)pyObjectToPointer(callPythonFunction("texture_u" + solver_ext, func));
+ mTextureV = (float *)pyObjectToPointer(callPythonFunction("texture_v" + solver_ext, func));
+ mTextureW = (float *)pyObjectToPointer(callPythonFunction("texture_w" + solver_ext, func));
+ mTextureU2 = (float *)pyObjectToPointer(callPythonFunction("texture_u2" + solver_ext, func));
+ mTextureV2 = (float *)pyObjectToPointer(callPythonFunction("texture_v2" + solver_ext, func));
+ mTextureW2 = (float *)pyObjectToPointer(callPythonFunction("texture_w2" + solver_ext, func));
}
if (mUsingSmoke && mUsingNoise && mUsingFire) {
- mFlameHigh = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("flame" + noise_ext, func)));
- mFuelHigh = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("fuel" + noise_ext, func)));
- mReactHigh = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("react" + noise_ext, func)));
+ mFlameHigh = (float *)pyObjectToPointer(callPythonFunction("flame" + noise_ext, func));
+ mFuelHigh = (float *)pyObjectToPointer(callPythonFunction("fuel" + noise_ext, func));
+ mReactHigh = (float *)pyObjectToPointer(callPythonFunction("react" + noise_ext, func));
}
if (mUsingSmoke && mUsingNoise && mUsingColors) {
- mColorRHigh = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("color_r" + noise_ext, func)));
- mColorGHigh = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("color_g" + noise_ext, func)));
- mColorBHigh = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("color_b" + noise_ext, func)));
+ mColorRHigh = (float *)pyObjectToPointer(callPythonFunction("color_r" + noise_ext, func));
+ mColorGHigh = (float *)pyObjectToPointer(callPythonFunction("color_g" + noise_ext, func));
+ mColorBHigh = (float *)pyObjectToPointer(callPythonFunction("color_b" + noise_ext, func));
}
if (mUsingLiquid) {
- mPhi = (float *)stringToPointer(
- pyObjectToString(callPythonFunction("phi" + solver_ext, func)));
- mFlipParticleData = (std::vector<pData> *)stringToPointer(
- pyObjectToString(callPythonFunction("pp" + solver_ext, func)));
- mFlipParticleVelocity = (std::vector<pVel> *)stringToPointer(
- pyObjectToString(callPythonFunction("pVel" + parts_ext, func)));
+ mPhi = (float *)pyObjectToPointer(callPythonFunction("phi" + solver_ext, func));
+ mFlipParticleData = (std::vector<pData> *)pyObjectToPointer(
+ callPythonFunction("pp" + solver_ext, func));
+ mFlipParticleVelocity = (std::vector<pVel> *)pyObjectToPointer(
+ callPythonFunction("pVel" + parts_ext, func));
}
if (mUsingLiquid && mUsingMesh) {
- mMeshNodes = (std::vector<Node> *)stringToPointer(
- pyObjectToString(callPythonFunction("mesh" + mesh_ext, funcNodes)));
- mMeshTriangles = (std::vector<Triangle> *)stringToPointer(
- pyObjectToString(callPythonFunction("mesh" + mesh_ext, funcTris)));
+ mMeshNodes = (std::vector<Node> *)pyObjectToPointer(
+ callPythonFunction("mesh" + mesh_ext, funcNodes));
+ mMeshTriangles = (std::vector<Triangle> *)pyObjectToPointer(
+ callPythonFunction("mesh" + mesh_ext, funcTris));
}
if (mUsingLiquid && mUsingMVel) {
- mMeshVelocities = (std::vector<pVel> *)stringToPointer(
- pyObjectToString(callPythonFunction("mVel" + mesh_ext2, func)));
+ mMeshVelocities = (std::vector<pVel> *)pyObjectToPointer(
+ callPythonFunction("mVel" + mesh_ext2, func));
}
if (mUsingLiquid && (mUsingDrops | mUsingBubbles | mUsingFloats | mUsingTracers)) {
- mSndParticleData = (std::vector<pData> *)stringToPointer(
- pyObjectToString(callPythonFunction("ppSnd" + snd_ext, func)));
- mSndParticleVelocity = (std::vector<pVel> *)stringToPointer(
- pyObjectToString(callPythonFunction("pVelSnd" + parts_ext, func)));
- mSndParticleLife = (std::vector<float> *)stringToPointer(
- pyObjectToString(callPythonFunction("pLifeSnd" + parts_ext, func)));
+ mSndParticleData = (std::vector<pData> *)pyObjectToPointer(
+ callPythonFunction("ppSnd" + snd_ext, func));
+ mSndParticleVelocity = (std::vector<pVel> *)pyObjectToPointer(
+ callPythonFunction("pVelSnd" + parts_ext, func));
+ mSndParticleLife = (std::vector<float> *)pyObjectToPointer(
+ callPythonFunction("pLifeSnd" + parts_ext, func));
}
mFlipFromFile = true;
diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py
index 2028857640e..34ff386893b 100644
--- a/release/scripts/startup/bl_ui/properties_particle.py
+++ b/release/scripts/startup/bl_ui/properties_particle.py
@@ -582,7 +582,10 @@ class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel):
else:
part = context.space_data.pin_id
- self.layout.prop(part, "use_rotations", text="")
+ layout = self.layout
+ layout.prop(part, "use_rotations", text="")
+ layout.enabled = particle_panel_enabled(context, psys) and part.use_rotations
+
def draw(self, context):
layout = self.layout
diff --git a/source/blender/bmesh/operators/bmo_subdivide_edgering.c b/source/blender/bmesh/operators/bmo_subdivide_edgering.c
index f93d33bb05f..b9d5548f5d4 100644
--- a/source/blender/bmesh/operators/bmo_subdivide_edgering.c
+++ b/source/blender/bmesh/operators/bmo_subdivide_edgering.c
@@ -828,6 +828,11 @@ static void bm_face_slice(BMesh *bm, BMLoop *l, const int cuts)
for (i = 0; i < cuts; i++) {
/* no chance of double */
BM_face_split(bm, l_new->f, l_new->prev, l_new->next->next, &l_new, NULL, false);
+ if (l_new == NULL) {
+ /* This happens when l_new->prev and l_new->next->next are adjacent. Since
+ * this sets l_new to NULL, we cannot continue this for-loop. */
+ break;
+ }
if (l_new->f->len < l_new->radial_next->f->len) {
l_new = l_new->radial_next;
}
diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl
index ca4940ceffb..5277bfa32bb 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl
@@ -41,6 +41,12 @@ float max_v4(vec4 v)
return max(max(v.x, v.y), max(v.z, v.w));
}
+vec4 safe_color(vec4 c)
+{
+ /* Clamp to avoid black square artifacts if a pixel goes NaN. */
+ return clamp(c, vec4(0.0), vec4(1e20)); /* 1e20 arbitrary. */
+}
+
#define THRESHOLD 1.0
#ifdef STEP_DOWNSAMPLE
@@ -57,10 +63,10 @@ void main(void)
ivec4 uvs = ivec4(gl_FragCoord.xyxy) * 2 + ivec4(0, 0, 1, 1);
/* custom downsampling */
- vec4 color1 = texelFetch(colorBuffer, uvs.xy, 0);
- vec4 color2 = texelFetch(colorBuffer, uvs.zw, 0);
- vec4 color3 = texelFetch(colorBuffer, uvs.zy, 0);
- vec4 color4 = texelFetch(colorBuffer, uvs.xw, 0);
+ vec4 color1 = safe_color(texelFetch(colorBuffer, uvs.xy, 0));
+ vec4 color2 = safe_color(texelFetch(colorBuffer, uvs.zw, 0));
+ vec4 color3 = safe_color(texelFetch(colorBuffer, uvs.zy, 0));
+ vec4 color4 = safe_color(texelFetch(colorBuffer, uvs.xw, 0));
/* Leverage SIMD by combining 4 depth samples into a vec4 */
vec4 depth;
diff --git a/source/blender/draw/engines/overlay/overlay_extra.c b/source/blender/draw/engines/overlay/overlay_extra.c
index c5dc6860ac2..fc52efb0174 100644
--- a/source/blender/draw/engines/overlay/overlay_extra.c
+++ b/source/blender/draw/engines/overlay/overlay_extra.c
@@ -623,8 +623,9 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob)
copy_m4_m4(instdata.mat, ob->obmat);
/* FIXME / TODO: clipend has no meaning nowadays.
* In EEVEE, Only clipsta is used shadowmaping.
- * Clip end is computed automatically based on light power. */
- instdata.clip_end = la->clipend;
+ * Clip end is computed automatically based on light power.
+ * For now, always use the custom distance as clipend. */
+ instdata.clip_end = la->att_dist;
instdata.clip_sta = la->clipsta;
DRW_buffer_add_entry(cb->groundline, instdata.pos);
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index a0e4af8fc8d..bfb74a9576f 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -1208,10 +1208,11 @@ GPUBatch *DRW_cache_field_curve_get(void)
GPUBatch *DRW_cache_field_tube_limit_get(void)
{
#define CIRCLE_RESOL 32
+#define SIDE_STIPPLE 32
if (!SHC.drw_field_tube_limit) {
GPUVertFormat format = extra_vert_format();
- int v_len = 2 * (CIRCLE_RESOL * 2 + 4);
+ int v_len = 2 * (CIRCLE_RESOL * 2 + 4 * SIDE_STIPPLE / 2);
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
GPU_vertbuf_data_alloc(vbo, v_len);
@@ -1219,14 +1220,14 @@ GPUBatch *DRW_cache_field_tube_limit_get(void)
int flag = VCLASS_EMPTY_SIZE;
/* Caps */
for (int i = 0; i < 2; i++) {
- float z = (float)i * 2.0f - 1.0f;
- circle_verts(vbo, &v, CIRCLE_RESOL, 1.0f, z, flag);
+ float z = i * 2.0f - 1.0f;
+ circle_dashed_verts(vbo, &v, CIRCLE_RESOL, 1.0f, z, flag);
}
/* Side Edges */
for (int a = 0; a < 4; a++) {
- for (int i = 0; i < 2; i++) {
- float z = (float)i * 2.0f - 1.0f;
- float angle = (2.0f * M_PI * a) / 4.0f;
+ float angle = (2.0f * M_PI * a) / 4.0f;
+ for (int i = 0; i < SIDE_STIPPLE; i++) {
+ float z = (i / (float)SIDE_STIPPLE) * 2.0f - 1.0f;
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{sinf(angle), cosf(angle), z}, flag});
}
}
@@ -1234,16 +1235,18 @@ GPUBatch *DRW_cache_field_tube_limit_get(void)
SHC.drw_field_tube_limit = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
}
return SHC.drw_field_tube_limit;
+#undef SIDE_STIPPLE
#undef CIRCLE_RESOL
}
GPUBatch *DRW_cache_field_cone_limit_get(void)
{
#define CIRCLE_RESOL 32
+#define SIDE_STIPPLE 32
if (!SHC.drw_field_cone_limit) {
GPUVertFormat format = extra_vert_format();
- int v_len = 2 * (CIRCLE_RESOL * 2 + 4);
+ int v_len = 2 * (CIRCLE_RESOL * 2 + 4 * SIDE_STIPPLE / 2);
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
GPU_vertbuf_data_alloc(vbo, v_len);
@@ -1251,14 +1254,14 @@ GPUBatch *DRW_cache_field_cone_limit_get(void)
int flag = VCLASS_EMPTY_SIZE;
/* Caps */
for (int i = 0; i < 2; i++) {
- float z = (float)i * 2.0f - 1.0f;
- circle_verts(vbo, &v, CIRCLE_RESOL, 1.0f, z, flag);
+ float z = i * 2.0f - 1.0f;
+ circle_dashed_verts(vbo, &v, CIRCLE_RESOL, 1.0f, z, flag);
}
/* Side Edges */
for (int a = 0; a < 4; a++) {
- for (int i = 0; i < 2; i++) {
- float z = (float)i * 2.0f - 1.0f;
- float angle = (2.0f * M_PI * a) / 4.0f;
+ float angle = (2.0f * M_PI * a) / 4.0f;
+ for (int i = 0; i < SIDE_STIPPLE; i++) {
+ float z = (i / (float)SIDE_STIPPLE) * 2.0f - 1.0f;
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{sinf(angle) * z, cosf(angle) * z, z}, flag});
}
}
@@ -1266,6 +1269,7 @@ GPUBatch *DRW_cache_field_cone_limit_get(void)
SHC.drw_field_cone_limit = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
}
return SHC.drw_field_cone_limit;
+#undef SIDE_STIPPLE
#undef CIRCLE_RESOL
}
diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c
index 690fee61005..c2f1e9f091a 100644
--- a/source/blender/editors/gpencil/gpencil_brush.c
+++ b/source/blender/editors/gpencil/gpencil_brush.c
@@ -424,7 +424,8 @@ static bool gp_brush_strength_apply(tGP_BrushEditData *gso,
* - We divide the strength, so that users can set "sane" values.
* Otherwise, good default values are in the range of 0.093
*/
- inf = gp_brush_influence_calc(gso, radius, co) / 20.0f;
+ inf = gp_brush_influence_calc(gso, radius, co) / 2.0f;
+ CLAMP_MIN(inf, 0.01f);
/* apply */
if (gp_brush_invert_check(gso)) {
@@ -435,12 +436,12 @@ static bool gp_brush_strength_apply(tGP_BrushEditData *gso,
/* make line more opaque - increase stroke strength */
pt->strength += inf;
}
- /* smooth the strength */
- BKE_gpencil_smooth_stroke_strength(gps, pt_index, inf);
-
/* Strength should stay within [0.0, 1.0] */
CLAMP(pt->strength, 0.0f, 1.0f);
+ /* smooth the strength */
+ BKE_gpencil_smooth_stroke_strength(gps, pt_index, inf);
+
return true;
}