diff options
author | Antonio Vazquez <blendergit@gmail.com> | 2020-01-23 18:56:26 +0300 |
---|---|---|
committer | Antonio Vazquez <blendergit@gmail.com> | 2020-01-23 18:56:26 +0300 |
commit | fb671035be082a67e6ffc58fb098c0d5140ba6b0 (patch) | |
tree | d8befc157c786d22c4ae66aa490b990adc7958ef | |
parent | 8482ba6d2e1a97e038175a7fb693ed40c03ca5d9 (diff) | |
parent | d9d11e2faf0502eab215f8f13661972f9b459d3a (diff) |
Merge branch 'blender-v2.82-release'
-rw-r--r-- | intern/cycles/device/device_optix.cpp | 3 | ||||
-rw-r--r-- | intern/cycles/util/util_math_float4.h | 5 | ||||
-rw-r--r-- | intern/cycles/util/util_transform.cpp | 36 | ||||
-rw-r--r-- | intern/mantaflow/intern/MANTA_main.cpp | 261 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/properties_particle.py | 5 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_subdivide_edgering.c | 5 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl | 14 | ||||
-rw-r--r-- | source/blender/draw/engines/overlay/overlay_extra.c | 5 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.c | 28 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_brush.c | 9 |
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; } |