[Bf-blender-cvs] [881881f] hair_system: Fix and nicer code structure for the smoothing algorithm.

Lukas Tönne noreply at git.blender.org
Wed Aug 6 14:42:28 CEST 2014


Commit: 881881fa397a6f49076332e8544a001e74a453b3
Author: Lukas Tönne
Date:   Wed Aug 6 14:40:00 2014 +0200
Branches: hair_system
https://developer.blender.org/rB881881fa397a6f49076332e8544a001e74a453b3

Fix and nicer code structure for the smoothing algorithm.

This was requiring careful index checks outside the actual iterators and
was prone to causing invalid memory access. Now the iterators use
"walker" struct definitions witch handle the details of the data access.

Note that currently the bending springs are broken, this will be fixed
in a separate commit.

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

M	source/blender/editors/space_view3d/drawhair.c
M	source/blender/hair/HAIR_capi.cpp
M	source/blender/hair/HAIR_capi.h
M	source/blender/hair/intern/HAIR_debug.h
M	source/blender/hair/intern/HAIR_smoothing.h
M	source/blender/hair/intern/HAIR_solver.cpp
M	source/blender/hair/intern/HAIR_solver.h

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

diff --git a/source/blender/editors/space_view3d/drawhair.c b/source/blender/editors/space_view3d/drawhair.c
index 6dd28cc..a36c045 100644
--- a/source/blender/editors/space_view3d/drawhair.c
+++ b/source/blender/editors/space_view3d/drawhair.c
@@ -105,7 +105,7 @@ bool draw_hair_system(Scene *UNUSED(scene), View3D *UNUSED(v3d), ARegion *ar, Ba
 /* ---------------- debug drawing ---------------- */
 
 //#define SHOW_ROOTS
-//#define SHOW_FRAMES
+#define SHOW_FRAMES
 //#define SHOW_SMOOTHING
 #define SHOW_CYLINDERS
 #define SHOW_CONTACTS
@@ -146,28 +146,28 @@ static void draw_hair_curve_debug_frames(HairSystem *hsys, HairCurve *hair)
 	const float scale = 0.1f;
 	
 	glBegin(GL_LINES);
-	iter = HAIR_frame_iter_new(hair, 1.0f / hair->totpoints, hsys->smooth, nor, tan, cotan);
-	copy_v3_v3(co, hair->points[0].co);
-	mul_v3_fl(nor, scale);
-	mul_v3_fl(tan, scale);
-	mul_v3_fl(cotan, scale);
-	add_v3_v3(nor, co);
-	add_v3_v3(tan, co);
-	add_v3_v3(cotan, co);
-	++k;
+	iter = HAIR_frame_iter_new(hair, 1.0f / hair->totpoints, hsys->smooth);
+//	copy_v3_v3(co, hair->points[0].co);
+//	mul_v3_fl(nor, scale);
+//	mul_v3_fl(tan, scale);
+//	mul_v3_fl(cotan, scale);
+//	add_v3_v3(nor, co);
+//	add_v3_v3(tan, co);
+//	add_v3_v3(cotan, co);
+//	++k;
 	
-	glColor3f(1.0f, 0.0f, 0.0f);
-	glVertex3fv(co);
-	glVertex3fv(nor);
-	glColor3f(0.0f, 1.0f, 0.0f);
-	glVertex3fv(co);
-	glVertex3fv(tan);
-	glColor3f(0.0f, 0.0f, 1.0f);
-	glVertex3fv(co);
-	glVertex3fv(cotan);
+//	glColor3f(1.0f, 0.0f, 0.0f);
+//	glVertex3fv(co);
+//	glVertex3fv(nor);
+//	glColor3f(0.0f, 1.0f, 0.0f);
+//	glVertex3fv(co);
+//	glVertex3fv(tan);
+//	glColor3f(0.0f, 0.0f, 1.0f);
+//	glVertex3fv(co);
+//	glVertex3fv(cotan);
 	
-	while (HAIR_frame_iter_valid(hair, iter)) {
-		HAIR_frame_iter_next(hair, iter, nor, tan, cotan);
+	while (HAIR_frame_iter_valid(iter)) {
+		HAIR_frame_iter_get(iter, nor, tan, cotan);
 		copy_v3_v3(co, hair->points[k].co);
 		mul_v3_fl(nor, scale);
 		mul_v3_fl(tan, scale);
@@ -186,6 +186,8 @@ static void draw_hair_curve_debug_frames(HairSystem *hsys, HairCurve *hair)
 		glColor3f(0.0f, 0.0f, 1.0f);
 		glVertex3fv(co);
 		glVertex3fv(cotan);
+		
+		HAIR_frame_iter_next(iter);
 	}
 	HAIR_frame_iter_free(iter);
 	glEnd();
@@ -207,27 +209,25 @@ static void draw_hair_curve_debug_smoothing(HairSystem *hsys, HairCurve *hair)
 	glColor3f(0.5f, 1.0f, 0.1f);
 	
 	glBegin(GL_LINE_STRIP);
-	iter = HAIR_smoothing_iter_new(hair, 1.0f / hair->totpoints, hsys->smooth, smooth_co);
-	glVertex3fv(smooth_co);
-	while (HAIR_smoothing_iter_valid(hair, iter)) {
-		HAIR_smoothing_iter_next(hair, iter, smooth_co);
+	iter = HAIR_smoothing_iter_new(hair, 1.0f / hair->totpoints, hsys->smooth);
+	while (HAIR_smoothing_iter_valid(iter)) {
+		HAIR_smoothing_iter_get(iter, smooth_co);
 		glVertex3fv(smooth_co);
+		
+		HAIR_smoothing_iter_next(iter);
 	}
-	HAIR_smoothing_iter_end(hair, iter, smooth_co);
-	glVertex3fv(smooth_co);
 	HAIR_smoothing_iter_free(iter);
 	glEnd();
 	
 	glPointSize(2.5f);
 	glBegin(GL_POINTS);
-	iter = HAIR_smoothing_iter_new(hair, 1.0f / hair->totpoints, hsys->smooth, smooth_co);
-	glVertex3fv(smooth_co);
-	while (HAIR_smoothing_iter_valid(hair, iter)) {
-		HAIR_smoothing_iter_next(hair, iter, smooth_co);
+	iter = HAIR_smoothing_iter_new(hair, 1.0f / hair->totpoints, hsys->smooth);
+	while (HAIR_smoothing_iter_valid(iter)) {
+		HAIR_smoothing_iter_get(iter, smooth_co);
 		glVertex3fv(smooth_co);
+		
+		HAIR_smoothing_iter_next(iter);
 	}
-	HAIR_smoothing_iter_end(hair, iter, smooth_co);
-	glVertex3fv(smooth_co);
 	HAIR_smoothing_iter_free(iter);
 	glEnd();
 	glPointSize(1.0f);
diff --git a/source/blender/hair/HAIR_capi.cpp b/source/blender/hair/HAIR_capi.cpp
index 79d67a3..daf5597 100644
--- a/source/blender/hair/HAIR_capi.cpp
+++ b/source/blender/hair/HAIR_capi.cpp
@@ -132,107 +132,100 @@ void HAIR_solver_apply(struct HAIR_Solver *csolver, Scene *scene, Object *ob, Ha
 }
 
 
-struct HAIR_SmoothingIteratorFloat3 *HAIR_smoothing_iter_new(HairCurve *curve, float rest_length, float amount, float cval[3])
-{
-	SmoothingIterator<float3> *iter = new SmoothingIterator<float3>(rest_length, amount);
-	
-	if (curve->totpoints >= 2) {
-		float *co0 = curve->points[0].co;
-		float *co1 = curve->points[1].co;
-		
-		float3 val = iter->begin(co0, co1);
-		copy_v3_v3(cval, val.data());
-	}
-	/* XXX setting iter->num is not nice, find a better way to invalidate the iterator */
-	else if (curve->totpoints >= 1) {
-		copy_v3_v3(cval, curve->points[0].co);
-		iter->num = 2; 
+struct HairCurveWalker {
+	typedef float3 data_t;
+	
+	HairCurveWalker(HairCurve *curve) :
+	    curve(curve),
+	    i(0)
+	{}
+	
+	float3 read()
+	{
+		float3 result(curve->points[i].co);
+		if (i < curve->totpoints-1)
+			++i;
+		return result;
 	}
-	else
-		iter->num = 1;
+	
+	int size() const { return curve->totpoints; }
+	
+	HairCurve *curve;
+	int i;
+};
+
+typedef SmoothingIterator<HairCurveWalker> HairCurveSmoothingIterator;
+typedef FrameIterator<HairCurveWalker> HairCurveFrameIterator;
+
+struct HAIR_SmoothingIteratorFloat3 *HAIR_smoothing_iter_new(HairCurve *curve, float rest_length, float amount)
+{
+	HairCurveSmoothingIterator *iter = new HairCurveSmoothingIterator(HairCurveWalker(curve), rest_length, amount);
 	
 	return (struct HAIR_SmoothingIteratorFloat3 *)iter;
 }
 
 void HAIR_smoothing_iter_free(struct HAIR_SmoothingIteratorFloat3 *citer)
 {
-	SmoothingIterator<float3> *iter = (SmoothingIterator<float3> *)citer;
+	HairCurveSmoothingIterator *iter = (HairCurveSmoothingIterator *)citer;
 	
 	delete iter;
 }
 
-bool HAIR_smoothing_iter_valid(HairCurve *curve, struct HAIR_SmoothingIteratorFloat3 *citer)
+bool HAIR_smoothing_iter_valid(struct HAIR_SmoothingIteratorFloat3 *citer)
 {
-	SmoothingIterator<float3> *iter = (SmoothingIterator<float3> *)citer;
+	HairCurveSmoothingIterator *iter = (HairCurveSmoothingIterator *)citer;
 	
-	return iter->num < curve->totpoints;
+	return iter->valid();
 }
 
-void HAIR_smoothing_iter_next(HairCurve *curve, struct HAIR_SmoothingIteratorFloat3 *citer, float cval[3])
+void HAIR_smoothing_iter_get(struct HAIR_SmoothingIteratorFloat3 *citer, float cval[3])
 {
-	SmoothingIterator<float3> *iter = (SmoothingIterator<float3> *)citer;
+	HairCurveSmoothingIterator *iter = (HairCurveSmoothingIterator *)citer;
 	
-	float *co = curve->points[iter->num].co;
-	float3 val = iter->next(co);
+	float3 val = iter->get();
 	copy_v3_v3(cval, val.data());
 }
 
-void HAIR_smoothing_iter_end(HairCurve *curve, struct HAIR_SmoothingIteratorFloat3 *citer, float cval[3])
+void HAIR_smoothing_iter_next(struct HAIR_SmoothingIteratorFloat3 *citer)
 {
-	SmoothingIterator<float3> *iter = (SmoothingIterator<float3> *)citer;
+	HairCurveSmoothingIterator *iter = (HairCurveSmoothingIterator *)citer;
 	
-	float *co = curve->points[iter->num-1].co;
-	float3 val = iter->next(co);
-	copy_v3_v3(cval, val.data());
+	iter->next();
 }
 
-
-struct HAIR_FrameIterator *HAIR_frame_iter_new(HairCurve *curve, float rest_length, float amount, float cnor[3], float ctan[3], float ccotan[3])
+struct HAIR_FrameIterator *HAIR_frame_iter_new(HairCurve *curve, float rest_length, float amount)
 {
-	FrameIterator *iter;
-	float3 co0, co1;
-	
-	if (curve->totpoints >= 2) {
-		co0 = curve->points[0].co;
-		co1 = curve->points[1].co;
-	}
-	else if (curve->totpoints >= 1) {
-		co0 = co1 = curve->points[0].co;
-	}
-	else {
-		static const float3 v(0.0f, 0.0f, 0.0f);
-		co0 = co1 = v;
-	}
-	
-	iter = new FrameIterator(rest_length, amount, curve->totpoints, co0, co1);
-	copy_v3_v3(cnor, iter->frame().normal.data());
-	copy_v3_v3(ctan, iter->frame().tangent.data());
-	copy_v3_v3(ccotan, iter->frame().cotangent.data());
+	HairCurveFrameIterator *iter = new HairCurveFrameIterator(HairCurveWalker(curve), rest_length, amount);
 	
 	return (struct HAIR_FrameIterator *)iter;
 }
 
 void HAIR_frame_iter_free(struct HAIR_FrameIterator *citer)
 {
-	FrameIterator *iter = (FrameIterator *)citer;
+	HairCurveFrameIterator *iter = (HairCurveFrameIterator *)citer;
 	
 	delete iter;
 }
 
-bool HAIR_frame_iter_valid(HairCurve *curve, struct HAIR_FrameIterator *citer)
+bool HAIR_frame_iter_valid(struct HAIR_FrameIterator *citer)
 {
-	FrameIterator *iter = (FrameIterator *)citer;
+	HairCurveFrameIterator *iter = (HairCurveFrameIterator *)citer;
 	
 	return iter->valid();
 }
 
-void HAIR_frame_iter_next(HairCurve *curve, struct HAIR_FrameIterator *citer, float cnor[3], float ctan[3], float ccotan[3])
+void HAIR_frame_iter_get(struct HAIR_FrameIterator *citer, float cnor[3], float ctan[3], float ccotan[3])
 {
-	FrameIterator *iter = (FrameIterator *)citer;
+	HairCurveFrameIterator *iter = (HairCurveFrameIterator *)citer;
 	
-	float *co = curve->points[iter->cur()].co;
-	iter->next(co);
 	copy_v3_v3(cnor, iter->frame().normal.data());
 	copy_v3_v3(ctan, iter->frame().tangent.data());
 	copy_v3_v3(ccotan, iter->frame().cotangent.data());
 }
+
+void HAIR_frame_iter_next(struct HAIR_FrameIterator *citer)
+{
+	HairCurveFrameIterator *iter = (HairCurveFrameIterator *)citer;
+	
+	iter->next();
+}
diff --git a/source/blender/hair/HAIR_capi.h b/source/blender/hair/HAIR_capi.h
index 6e6f6ec..50dbc1b 100644
--- a/source/blender/hair/HAIR_capi.h
+++ b/source/blender/hair/HAIR_capi.h
@@ -55,16 +55,17 @@ void HAIR_solver_step_debug(struct HAIR_Solver *csolver, float time, float times
 
 void HAIR_solver_apply(struct HAIR_Solver *solver, struct Scene *scene, struct Object *ob, struct HairSystem *hsys);
 
-struct HAIR_SmoothingIteratorFloat3 *HAIR_smoothing_iter_new(struct HairCurve *curve, float rest_length, float amount, float cval[3]);
+struct HAIR_SmoothingIteratorFloat3 *HAIR_smoothing_iter_new(HairCurve *curve, float rest_length, float amount);
 void HAIR_smoothing_iter_free(struct HAIR_SmoothingIteratorFloat3 *iter);
-bool HAIR_smoothing_iter_valid(struct HairCurve *curve, struct HAIR_SmoothingIteratorFloat3 *iter);
-void HAIR_smoothing_iter_next(struct HairCurve *curve, struct HAIR_SmoothingIteratorFloat3 *iter, float val[3]);
-void HAIR_smoothing_iter_end(struct HairCurve *curve, struct HAIR_SmoothingIteratorFloat3 *citer, float cval[3]);
+bool HAIR_smoothing_iter_valid(struct HAIR_SmoothingIteratorFloat3 *iter);
+void HAIR_smoothing_iter_get(struct HAIR_SmoothingIteratorFlo

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list