[Bf-blender-cvs] [d6d101feca0] master: Fix T59395: Subdivision modifier with quality 1 crashes blender

Sergey Sharybin noreply at git.blender.org
Tue Jan 22 11:57:52 CET 2019


Commit: d6d101feca09ae17af00f080a76acbc4d6785c3e
Author: Sergey Sharybin
Date:   Mon Jan 21 16:43:30 2019 +0100
Branches: master
https://developer.blender.org/rBd6d101feca09ae17af00f080a76acbc4d6785c3e

Fix T59395: Subdivision modifier with quality 1 crashes blender

This is actually a workaround for the crash in OpenSubdiv.
Topology refiner will have a crash when special conditions
are met:

- Refiner is configured to use infinitely sharp patches.
- Refinement happens for the level 1 (which we call Quality 1 on
  Blender side).
- Mesh has non-quad faces.

The workaround is to force refinement to happen to level 2 (or
quality 2 on Blender side) when those conditions are met.

Later on with the next OpenSubdiv update we can remove this
workaround, since there was work done on OpenSubdiv side to
deal better with such configurations.

The modifier will now be somewhat slower, but this will be
compensated with upcoming topology cache enabled by default.

The workaround is done when initializing settings, so the
comparison of topology refiner settings is happening without
any extra workarounds there.

===================================================================

M	source/blender/blenkernel/BKE_subdiv.h
M	source/blender/blenkernel/intern/subdiv.c
M	source/blender/modifiers/intern/MOD_multires.c
M	source/blender/modifiers/intern/MOD_subsurf.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h
index 73470b15c61..6ff861e82d4 100644
--- a/source/blender/blenkernel/BKE_subdiv.h
+++ b/source/blender/blenkernel/BKE_subdiv.h
@@ -194,6 +194,9 @@ void BKE_subdiv_stats_print(const SubdivStats *stats);
 
 /* ================================ SETTINGS ================================ */
 
+void BKE_subdiv_settings_validate_for_mesh(SubdivSettings *settings,
+                                           const struct Mesh *mesh);
+
 bool BKE_subdiv_settings_equal(const SubdivSettings *settings_a,
                                const SubdivSettings *settings_b);
 
diff --git a/source/blender/blenkernel/intern/subdiv.c b/source/blender/blenkernel/intern/subdiv.c
index 635cb64c772..35c8fd0efd1 100644
--- a/source/blender/blenkernel/intern/subdiv.c
+++ b/source/blender/blenkernel/intern/subdiv.c
@@ -30,6 +30,7 @@
 #include "BKE_subdiv.h"
 
 #include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
 #include "DNA_modifier_types.h"
 
 #include "BLI_utildefines.h"
@@ -68,6 +69,28 @@ BKE_subdiv_fvar_interpolation_from_uv_smooth(int uv_smooth)
 
 /* ================================ SETTINGS ================================ */
 
+static bool check_mesh_has_non_quad(const Mesh *mesh)
+{
+	for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) {
+		const MPoly *poly = &mesh->mpoly[poly_index];
+		if (poly->totloop != 4) {
+			return true;
+		}
+	}
+	return false;
+}
+
+void BKE_subdiv_settings_validate_for_mesh(SubdivSettings *settings,
+                                           const Mesh *mesh)
+{
+	if (settings->level != 1) {
+		return;
+	}
+	if (check_mesh_has_non_quad(mesh)) {
+		settings->level = 2;
+	}
+}
+
 bool BKE_subdiv_settings_equal(const SubdivSettings *settings_a,
                                const SubdivSettings *settings_b)
 {
diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c
index 9775a536e99..a18fd6a4c5e 100644
--- a/source/blender/modifiers/intern/MOD_multires.c
+++ b/source/blender/modifiers/intern/MOD_multires.c
@@ -159,6 +159,7 @@ static Mesh *applyModifier(ModifierData *md,
 	if (subdiv_settings.level == 0) {
 		return result;
 	}
+	BKE_subdiv_settings_validate_for_mesh(&subdiv_settings, mesh);
 	Subdiv *subdiv = subdiv_descriptor_ensure(mmd, &subdiv_settings, mesh);
 	if (subdiv == NULL) {
 		/* Happens on bad topology, ut also on empty input mesh. */
diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c
index 6394ab458e7..3cabd1131cb 100644
--- a/source/blender/modifiers/intern/MOD_subsurf.c
+++ b/source/blender/modifiers/intern/MOD_subsurf.c
@@ -206,6 +206,7 @@ static Mesh *applyModifier(ModifierData *md,
 	if (subdiv_settings.level == 0) {
 		return result;
 	}
+	BKE_subdiv_settings_validate_for_mesh(&subdiv_settings, mesh);
 	Subdiv *subdiv = subdiv_descriptor_ensure(smd, &subdiv_settings, mesh);
 	if (subdiv == NULL) {
 		/* Happens on bad topology, but also on empty input mesh. */



More information about the Bf-blender-cvs mailing list