[Bf-blender-cvs] [d25fb51] temp-cycles-microdisplacement: Fix support for triangles in DiagSplit implementation

Mai Lavelle noreply at git.blender.org
Tue Apr 12 18:45:45 CEST 2016


Commit: d25fb5191eedd364996578b4dea07da8030b8e46
Author: Mai Lavelle
Date:   Fri Dec 4 00:12:11 2015 -0500
Branches: temp-cycles-microdisplacement
https://developer.blender.org/rBd25fb5191eedd364996578b4dea07da8030b8e46

Fix support for triangles in DiagSplit implementation

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

M	intern/cycles/subd/subd_dice.cpp
M	intern/cycles/subd/subd_split.cpp

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

diff --git a/intern/cycles/subd/subd_dice.cpp b/intern/cycles/subd/subd_dice.cpp
index 28248f5..2585d5f 100644
--- a/intern/cycles/subd/subd_dice.cpp
+++ b/intern/cycles/subd/subd_dice.cpp
@@ -259,17 +259,10 @@ float QuadDice::scale_factor(SubPatch& sub, EdgeFactors& ef, int Mu, int Mv)
 void QuadDice::add_corners(SubPatch& sub)
 {
 	/* add verts for patch corners */
-	if(sub.patch->is_triangle()) {
-		add_vert(sub, 0.0f, 0.0f);
-		add_vert(sub, 1.0f, 0.0f);
-		add_vert(sub, 0.0f, 1.0f);
-	}
-	else {
-		add_vert(sub, 0.0f, 0.0f);
-		add_vert(sub, 1.0f, 0.0f);
-		add_vert(sub, 0.0f, 1.0f);
-		add_vert(sub, 1.0f, 1.0f);
-	}
+	add_vert(sub, 0.0f, 0.0f);
+	add_vert(sub, 1.0f, 0.0f);
+	add_vert(sub, 0.0f, 1.0f);
+	add_vert(sub, 1.0f, 1.0f);
 }
 
 void QuadDice::add_grid(SubPatch& sub, int Mu, int Mv, int offset)
@@ -458,15 +451,21 @@ void TriangleDice::add_grid(SubPatch& sub, EdgeFactors& ef, int M)
 		add_triangle(sub.patch, outer_w[0], outer_u[0], outer_v[0]);
 	}
 	else {
-		/* center vertex + 6 triangles */
+		/* center vertex + up to 6 triangles */
 		int center = add_vert(sub, make_float2(1.0f/3.0f, 1.0f/3.0f));
 
 		add_triangle(sub.patch, outer_w[0], outer_w[1], center);
-		add_triangle(sub.patch, outer_w[1], outer_w[2], center);
+		/* if this is false then there is only one triangle on this side */
+		if(outer_w.size() > 2)
+			add_triangle(sub.patch, outer_w[1], outer_w[2], center);
+
 		add_triangle(sub.patch, outer_u[0], outer_u[1], center);
-		add_triangle(sub.patch, outer_u[1], outer_u[2], center);
+		if(outer_u.size() > 2)
+			add_triangle(sub.patch, outer_u[1], outer_u[2], center);
+
 		add_triangle(sub.patch, outer_v[0], outer_v[1], center);
-		add_triangle(sub.patch, outer_v[1], outer_v[2], center);
+		if(outer_v.size() > 2)
+			add_triangle(sub.patch, outer_v[1], outer_v[2], center);
 	}
 }
 
@@ -475,6 +474,9 @@ void TriangleDice::dice(SubPatch& sub, EdgeFactors& ef)
 	/* todo: handle 2 1 1 resolution */
 	int M = max(ef.tu, max(ef.tv, ef.tw));
 
+	float S = 0.7598356856515927f; /* (2*cos(30d)/3)**0.5 ; makes internal triangles more consistant with quad patches*/
+	M = max((int)ceil(S*M), 1);
+
 	reserve(ef, M);
 	add_grid(sub, ef, M);
 
diff --git a/intern/cycles/subd/subd_split.cpp b/intern/cycles/subd/subd_split.cpp
index 2be82bf..e17b612 100644
--- a/intern/cycles/subd/subd_split.cpp
+++ b/intern/cycles/subd/subd_split.cpp
@@ -128,82 +128,62 @@ void DiagSplit::split(TriangleDice::SubPatch& sub, TriangleDice::EdgeFactors& ef
 	assert(ef.tv == T(sub.patch, sub.Pw, sub.Pu));
 	assert(ef.tw == T(sub.patch, sub.Pu, sub.Pv));
 
-	if(depth == 0) {
-		dispatch(sub, ef);
-		return;
-	}
-
-	if(ef.tu == DSPLIT_NON_UNIFORM) {
-		/* partition edges */
-		TriangleDice::EdgeFactors ef0, ef1;
-		float2 Psplit;
-
-		partition_edge(sub.patch,
-			&Psplit, &ef1.tu, &ef0.tu, sub.Pv, sub.Pw, ef.tu);
-
-		/* split */
-		int tsplit = T(sub.patch, sub.Pu, Psplit);
-		ef0.tv = ef.tv;
-		ef0.tw = tsplit;
-
-		ef1.tv = tsplit;
-		ef1.tw = ef.tw;
-
-		/* create subpatches */
-		TriangleDice::SubPatch sub0 = {sub.patch, sub.Pu, Psplit, sub.Pw};
-		TriangleDice::SubPatch sub1 = {sub.patch, sub.Pu, sub.Pv, Psplit};
-
-		split(sub0, ef0, depth+1);
-		split(sub1, ef1, depth+1);
-	}
-	else if(ef.tv == DSPLIT_NON_UNIFORM) {
-		/* partition edges */
-		TriangleDice::EdgeFactors ef0, ef1;
-		float2 Psplit;
-
-		partition_edge(sub.patch,
-			&Psplit, &ef1.tu, &ef0.tu, sub.Pw, sub.Pu, ef.tv);
+	int non_uniform_count = int(ef.tu == DSPLIT_NON_UNIFORM) +
+	                        int(ef.tv == DSPLIT_NON_UNIFORM) +
+                            int(ef.tw == DSPLIT_NON_UNIFORM);
+
+	switch(non_uniform_count) {
+		case 1: {
+			/* one edge is non-uniform, split into two triangles */
+			// fallthru
+		}
+		case 2: {
+			/* two edges are non-uniform, split into triangle and quad */
+			// fallthru
+		}
+		case 3: {
+			/* all three edges are non-uniform, split into three quads */
 
-		/* split */
-		int tsplit = T(sub.patch, sub.Pv, Psplit);
-		ef0.tv = ef.tw;
-		ef0.tw = tsplit;
+			/* partition edges */
+			QuadDice::EdgeFactors ef0, ef1, ef2;
+			float2 Pu, Pv, Pw, Pcenter;
 
-		ef1.tv = tsplit;
-		ef1.tw = ef.tu;
+			partition_edge(sub.patch, &Pu, &ef1.tv0, &ef2.tu0, sub.Pw, sub.Pv, ef.tu);
+			partition_edge(sub.patch, &Pv, &ef0.tv0, &ef1.tu0, sub.Pu, sub.Pw, ef.tv);
+			partition_edge(sub.patch, &Pw, &ef2.tv0, &ef0.tu0, sub.Pv, sub.Pu, ef.tw);
+			Pcenter = (Pu + Pv + Pw) * (1.0f / 3.0f);
 
-		/* create subpatches */
-		TriangleDice::SubPatch sub0 = {sub.patch, sub.Pv, Psplit, sub.Pu};
-		TriangleDice::SubPatch sub1 = {sub.patch, sub.Pv, sub.Pw, Psplit};
+			/* split */
+			int tsplit01 = T(sub.patch, Pv, Pcenter);
+			int tsplit12 = T(sub.patch, Pu, Pcenter);
+			int tsplit20 = T(sub.patch, Pw, Pcenter);
 
-		split(sub0, ef0, depth+1);
-		split(sub1, ef1, depth+1);
-	}
-	else if(ef.tw == DSPLIT_NON_UNIFORM) {
-		/* partition edges */
-		TriangleDice::EdgeFactors ef0, ef1;
-		float2 Psplit;
+			ef0.tu1 = tsplit01;
+			ef0.tv1 = tsplit20;
 
-		partition_edge(sub.patch,
-			&Psplit, &ef1.tu, &ef0.tu, sub.Pu, sub.Pv, ef.tw);
+			ef1.tu1 = tsplit12;
+			ef1.tv1 = tsplit01;
 
-		/* split */
-		int tsplit = T(sub.patch, sub.Pw, Psplit);
-		ef0.tv = ef.tu;
-		ef0.tw = tsplit;
+			ef2.tu1 = tsplit20;
+			ef2.tv1 = tsplit12;
 
-		ef1.tv = tsplit;
-		ef1.tw = ef.tv;
+			/* create subpatches */
+			QuadDice::SubPatch sub0 = {sub.patch, sub.Pu, Pw, Pv, Pcenter};
+			QuadDice::SubPatch sub1 = {sub.patch, sub.Pw, Pv, Pu, Pcenter};
+			QuadDice::SubPatch sub2 = {sub.patch, sub.Pv, Pu, Pw, Pcenter};
 
-		/* create subpatches */
-		TriangleDice::SubPatch sub0 = {sub.patch, sub.Pw, Psplit, sub.Pv};
-		TriangleDice::SubPatch sub1 = {sub.patch, sub.Pw, sub.Pu, Psplit};
+			split(sub0, ef0, depth+1);
+			split(sub1, ef1, depth+1);
+			split(sub2, ef2, depth+1);
 
-		split(sub0, ef0, depth+1);
-		split(sub1, ef1, depth+1);
+			break;
+		}
+		default: {
+			/* all edges uniform, no splitting needed */
+			dispatch(sub, ef);
+			break;
+		}
 	}
-	else
-		dispatch(sub, ef);
 }
 
 void DiagSplit::split(QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef, int depth)
@@ -299,10 +279,6 @@ void DiagSplit::split_triangle(Patch *patch)
 		TriangleDice::SubPatch& sub = subpatches_triangle[i];
 		TriangleDice::EdgeFactors& ef = edgefactors_triangle[i];
 
-		ef.tu = 4;
-		ef.tv = 4;
-		ef.tw = 4;
-
 		ef.tu = max(ef.tu, 1);
 		ef.tv = max(ef.tv, 1);
 		ef.tw = max(ef.tw, 1);
@@ -312,6 +288,24 @@ void DiagSplit::split_triangle(Patch *patch)
 
 	subpatches_triangle.clear();
 	edgefactors_triangle.clear();
+
+	/* triangle might be split into quads so dice quad subpatches as well */
+	QuadDice qdice(params);
+
+	for(size_t i = 0; i < subpatches_quad.size(); i++) {
+		QuadDice::SubPatch& sub = subpatches_quad[i];
+		QuadDice::EdgeFactors& ef = edgefactors_quad[i];
+
+		ef.tu0 = max(ef.tu0, 1);
+		ef.tu1 = max(ef.tu1, 1);
+		ef.tv0 = max(ef.tv0, 1);
+		ef.tv1 = max(ef.tv1, 1);
+
+		qdice.dice(sub, ef);
+	}
+
+	subpatches_quad.clear();
+	edgefactors_quad.clear();
 }
 
 void DiagSplit::split_quad(Patch *patch)




More information about the Bf-blender-cvs mailing list