[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [53825] trunk/blender/intern/cycles: Cycles Hair: Introduction of Cardinal Spline Curve Segments and minor fixes.

Stuart Broadfoot gbroadfoot at hotmail.com
Tue Jan 15 20:44:41 CET 2013


Revision: 53825
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=53825
Author:   broadstu
Date:     2013-01-15 19:44:41 +0000 (Tue, 15 Jan 2013)
Log Message:
-----------
Cycles Hair: Introduction of Cardinal Spline Curve Segments and minor fixes.

The curve segment primitive has been added. This includes an intersection function and changes to the BVH.

A few small errors in the line segment intersection routine are also fixed.

Modified Paths:
--------------
    trunk/blender/intern/cycles/blender/addon/properties.py
    trunk/blender/intern/cycles/blender/addon/ui.py
    trunk/blender/intern/cycles/blender/blender_curves.cpp
    trunk/blender/intern/cycles/bvh/bvh.cpp
    trunk/blender/intern/cycles/bvh/bvh_build.cpp
    trunk/blender/intern/cycles/kernel/kernel_bvh.h
    trunk/blender/intern/cycles/kernel/kernel_types.h
    trunk/blender/intern/cycles/render/curves.cpp
    trunk/blender/intern/cycles/render/curves.h

Modified: trunk/blender/intern/cycles/blender/addon/properties.py
===================================================================
--- trunk/blender/intern/cycles/blender/addon/properties.py	2013-01-15 19:17:51 UTC (rev 53824)
+++ trunk/blender/intern/cycles/blender/addon/properties.py	2013-01-15 19:44:41 UTC (rev 53825)
@@ -74,13 +74,14 @@
 enum_curve_primitives = (
     ('TRIANGLES', "Triangles", "Create triangle geometry around strands"),
     ('LINE_SEGMENTS', "Line Segments", "Use line segment primitives"),
-    ('CURVE_SEGMENTS', "?Curve Segments?", "Use curve segment primitives (not implemented)"),
+    ('CURVE_SEGMENTS', "Curve Segments", "Use segmented cardinal curve primitives"),
+    ('CURVE_RIBBONS', "Curve Ribbons", "Use smooth cardinal curve ribbon primitives"),
     )
 
 enum_triangle_curves = (
-    ('CAMERA', "Planes", "Create individual triangles forming planes that face camera"),
-    ('RIBBONS', "Ribbons", "Create individual triangles forming ribbon"),
-    ('TESSELLATED', "Tessellated", "Create mesh surrounding each strand"),
+    ('CAMERA_TRIANGLES', "Planes", "Create individual triangles forming planes that face camera"),
+    ('RIBBON_TRIANGLES', "Ribbons", "Create individual triangles forming ribbon"),
+    ('TESSELLATED_TRIANGLES', "Tessellated", "Create mesh surrounding each strand"),
     )
 
 enum_line_curves = (
@@ -643,7 +644,7 @@
                 name="Mesh Geometry",
                 description="Method for creating triangle geometry",
                 items=enum_triangle_curves,
-                default='CAMERA',
+                default='CAMERA_TRIANGLES',
                 )
         cls.line_method = EnumProperty(
                 name="Intersection Method",
@@ -730,6 +731,12 @@
                 min=0, max=100.0,
                 default=1.01,
                 )
+        cls.subdivisions = IntProperty(
+                name="Subdivisions",
+                description="Number of subdivisions used in Cardinal curve intersection (power of 2)",
+                min=0, max=24,
+                default=3,
+                )
 
     @classmethod
     def unregister(cls):

Modified: trunk/blender/intern/cycles/blender/addon/ui.py
===================================================================
--- trunk/blender/intern/cycles/blender/addon/ui.py	2013-01-15 19:17:51 UTC (rev 53824)
+++ trunk/blender/intern/cycles/blender/addon/ui.py	2013-01-15 19:44:41 UTC (rev 53825)
@@ -976,7 +976,7 @@
         
             if cscene.primitive == 'TRIANGLES':
                 layout.prop(cscene, "triangle_method", text="Method")
-                if cscene.triangle_method == 'TESSELLATED':
+                if cscene.triangle_method == 'TESSELLATED_TRIANGLES':
                     layout.prop(cscene, "resolution", text="Resolution")
                 layout.prop(cscene, "use_smooth", text="Smooth")
             elif cscene.primitive == 'LINE_SEGMENTS':
@@ -997,6 +997,13 @@
                 row = layout.row()
                 row.prop(cscene, "segments", text="Segments")
                 row.prop(cscene, "normalmix", text="Ray Mix")
+            elif cscene.primitive == 'CURVE_SEGMENTS' or cscene.primitive == 'CURVE_RIBBONS':
+                layout.prop(cscene, "subdivisions", text="Curve subdivisions")
+                layout.prop(cscene, "use_backfacing", text="Check back-faces")
+                
+                layout.prop(cscene, "interpolation", text="Interpolation")
+                row = layout.row()
+                row.prop(cscene, "segments", text="Segments")
             
             row = layout.row()
             row.prop(cscene, "use_cache", text="Export cache with children")

Modified: trunk/blender/intern/cycles/blender/blender_curves.cpp
===================================================================
--- trunk/blender/intern/cycles/blender/blender_curves.cpp	2013-01-15 19:17:51 UTC (rev 53824)
+++ trunk/blender/intern/cycles/blender/blender_curves.cpp	2013-01-15 19:44:41 UTC (rev 53825)
@@ -929,6 +929,7 @@
 		curve_system_manager->resolution = get_int(csscene, "resolution");
 		curve_system_manager->segments = get_int(csscene, "segments");
 		curve_system_manager->use_smooth = get_boolean(csscene, "use_smooth");
+		curve_system_manager->subdivisions = get_int(csscene, "subdivisions");
 
 		curve_system_manager->normalmix = get_float(csscene, "normalmix");
 		curve_system_manager->encasing_ratio = get_float(csscene, "encasing_ratio");
@@ -1055,11 +1056,11 @@
 
 	if(primitive == CURVE_TRIANGLES){
 		int vert_num = mesh->triangles.size() * 3;
-		if(triangle_method == CURVE_CAMERA) {
+		if(triangle_method == CURVE_CAMERA_TRIANGLES) {
 			ExportCurveTrianglePlanes(mesh, &CData, interpolation, use_smooth, segments, RotCam);
 			ExportCurveTriangleUVs(mesh, &CData, interpolation, use_smooth, segments, vert_num, 1);
 		}
-		else if(triangle_method == CURVE_RIBBONS) {
+		else if(triangle_method == CURVE_RIBBON_TRIANGLES) {
 			ExportCurveTriangleRibbons(mesh, &CData, interpolation, use_smooth, segments);
 			ExportCurveTriangleUVs(mesh, &CData, interpolation, use_smooth, segments, vert_num, 1);
 		}

Modified: trunk/blender/intern/cycles/bvh/bvh.cpp
===================================================================
--- trunk/blender/intern/cycles/bvh/bvh.cpp	2013-01-15 19:17:51 UTC (rev 53824)
+++ trunk/blender/intern/cycles/bvh/bvh.cpp	2013-01-15 19:44:41 UTC (rev 53825)
@@ -18,6 +18,7 @@
 #include "mesh.h"
 #include "object.h"
 #include "scene.h"
+#include "curves.h"
 
 #include "bvh.h"
 #include "bvh_build.h"
@@ -631,8 +632,19 @@
 					int k0 = mesh->curves[pidx - str_offset].first_key + pack.prim_segment[prim]; // XXX!
 					int k1 = k0 + 1;
 
-					bbox.grow(mesh->curve_keys[k0].co, mesh->curve_keys[k0].radius);
-					bbox.grow(mesh->curve_keys[k1].co, mesh->curve_keys[k1].radius);
+					float3 p[4];
+					p[0] = mesh->curve_keys[max(k0 - 1,mesh->curves[pidx - str_offset].first_key)].co;
+					p[1] = mesh->curve_keys[k0].co;
+					p[2] = mesh->curve_keys[k1].co;
+					p[3] = mesh->curve_keys[min(k1 + 1,mesh->curves[pidx - str_offset].first_key + mesh->curves[pidx - str_offset].num_keys - 1)].co;
+					float3 lower;
+					float3 upper;
+					curvebounds(&lower.x, &upper.x, p, 0);
+					curvebounds(&lower.y, &upper.y, p, 1);
+					curvebounds(&lower.z, &upper.z, p, 2);
+					float mr = max(mesh->curve_keys[k0].radius,mesh->curve_keys[k1].radius);
+					bbox.grow(lower, mr);
+					bbox.grow(upper, mr);
 				}
 				else {
 					/* triangles */

Modified: trunk/blender/intern/cycles/bvh/bvh_build.cpp
===================================================================
--- trunk/blender/intern/cycles/bvh/bvh_build.cpp	2013-01-15 19:17:51 UTC (rev 53824)
+++ trunk/blender/intern/cycles/bvh/bvh_build.cpp	2013-01-15 19:44:41 UTC (rev 53825)
@@ -24,6 +24,7 @@
 #include "mesh.h"
 #include "object.h"
 #include "scene.h"
+#include "curves.h"
 
 #include "util_debug.h"
 #include "util_foreach.h"
@@ -91,11 +92,20 @@
 		for(int k = 0; k < curve.num_keys - 1; k++) {
 			BoundBox bounds = BoundBox::empty;
 
-			float3 co0 = mesh->curve_keys[curve.first_key + k].co;
-			float3 co1 = mesh->curve_keys[curve.first_key + k + 1].co;
+			float3 co[4];
+			co[0] = mesh->curve_keys[max(curve.first_key + k - 1,curve.first_key)].co;
+			co[1] = mesh->curve_keys[curve.first_key + k].co;
+			co[2] = mesh->curve_keys[curve.first_key + k + 1].co;
+			co[3] = mesh->curve_keys[min(curve.first_key + k + 2, curve.first_key + curve.num_keys - 1)].co;
 
-			bounds.grow(co0, mesh->curve_keys[curve.first_key + k].radius);
-			bounds.grow(co1, mesh->curve_keys[curve.first_key + k + 1].radius);
+			float3 lower;
+			float3 upper;
+			curvebounds(&lower.x, &upper.x, co, 0);
+			curvebounds(&lower.y, &upper.y, co, 1);
+			curvebounds(&lower.z, &upper.z, co, 2);
+			float mr = max(mesh->curve_keys[curve.first_key + k].radius, mesh->curve_keys[curve.first_key + k + 1].radius);
+			bounds.grow(lower, mr);
+			bounds.grow(upper, mr);
 
 			if(bounds.valid()) {
 				references.push_back(BVHReference(bounds, j, i, k));

Modified: trunk/blender/intern/cycles/kernel/kernel_bvh.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_bvh.h	2013-01-15 19:17:51 UTC (rev 53824)
+++ trunk/blender/intern/cycles/kernel/kernel_bvh.h	2013-01-15 19:44:41 UTC (rev 53825)
@@ -206,6 +206,315 @@
 }
 
 #ifdef __HAIR__
+__device_inline void curvebounds(float *lower, float *lowert, float *upper, float *uppert, float p0, float p1, float p2, float p3)
+{
+	float halfdiscroot = (p2 * p2 - 3 * p3 * p1);
+	float ta = -1.0f;
+	float tb = -1.0f;
+	*uppert = 0.0f;
+	*upper = p0;
+	*lowert = 1.0f;
+	*lower = p0 + p1 + p2 + p3;
+	if(*lower >= *upper) {
+		*uppert = 1.0f;
+		*upper = *lower;
+		*lowert = 0.0f;
+		*lower = p0;
+	}
+
+	if(halfdiscroot >= 0) {
+		halfdiscroot = sqrt(halfdiscroot);
+		ta = (-p2 - halfdiscroot) / (3 * p3);
+		tb = (-p2 + halfdiscroot) / (3 * p3);
+	}
+
+	float t2;
+	float t3;
+	if(ta > 0.0f && ta < 1.0f) {
+		t2 = ta * ta;
+		t3 = t2 * ta;
+		float extrem = p3 * t3 + p2 * t2 + p1 * ta + p0;
+		if(extrem > *upper) {
+			*upper = extrem;
+			*uppert = ta;
+		}
+		if(extrem < *lower) {
+			*lower = extrem;
+			*lowert = ta;
+		}
+	}
+	if(tb > 0.0f && tb < 1.0f) {
+		t2 = tb * tb;
+		t3 = t2 * tb;
+		float extrem = p3 * t3 + p2 * t2 + p1 * tb + p0;
+		if(extrem >= *upper) {
+			*upper = extrem;
+			*uppert = tb;
+		}
+		if(extrem <= *lower) {
+			*lower = extrem;
+			*lowert = tb;
+		}
+	}
+}
+
+__device_inline void bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersection *isect,
+	float3 P, float3 idir, uint visibility, int object, int curveAddr, int segment)
+{
+	int depth = kernel_data.curve_kernel_data.subdivisions;
+
+	/* curve Intersection check */
+	float3 dir = 1.0f/idir;
+	
+	int flags = kernel_data.curve_kernel_data.curveflags;
+
+	int prim = kernel_tex_fetch(__prim_index, curveAddr);
+
+	float3 curve_coef[4];
+	float r_st,r_en;
+
+	/*obtain curve parameters*/
+	{
+		/*ray transform created - this shold be created at beginning of intersection loop*/
+		Transform htfm;
+		float d = sqrtf(dir.x * dir.x + dir.z * dir.z);
+		htfm = make_transform(
+			dir.z / d, 0, -dir.x /d, 0,
+			-dir.x * dir.y /d, d, -dir.y * dir.z /d, 0,
+			dir.x, dir.y, dir.z, 0,
+			0, 0, 0, 1) * make_transform(
+			1, 0, 0, -P.x,
+			0, 1, 0, -P.y,
+			0, 0, 1, -P.z,
+			0, 0, 0, 1);
+
+		float4 v00 = kernel_tex_fetch(__curves, prim);
+
+		int k0 = __float_as_int(v00.x) + segment;

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list