[Bf-blender-cvs] [0740ae9] hair_system: Added regular display options for hair systems.

Lukas Tönne noreply at git.blender.org
Sat Aug 9 20:45:22 CEST 2014


Commit: 0740ae9fe5d25e90c6d8c4fe726a1c2d89a3bcf2
Author: Lukas Tönne
Date:   Sat Aug 9 19:28:38 2014 +0200
Branches: hair_system
https://developer.blender.org/rB0740ae9fe5d25e90c6d8c4fe726a1c2d89a3bcf2

Added regular display options for hair systems.

Only has a mode setting so far, which defines the overall style of
display.

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

M	release/scripts/startup/bl_ui/properties_data_modifier.py
M	source/blender/editors/space_view3d/drawhair.c
M	source/blender/makesdna/DNA_hair_types.h
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesrna/intern/rna_hair.c
M	source/blender/makesrna/intern/rna_modifier.c

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

diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index d9b11f7..e81210a 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -1225,6 +1225,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
     def HAIR(self, layout, ob, md):
         hsys = md.hair_system
         params = hsys.params
+        display = hsys.display
         col = layout.column()
         
         col.separator()
@@ -1261,12 +1262,17 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
         
         col.separator()
         
+        col.label("Display:")
+        row = col.row()
+        row.prop(display, "mode", expand=True)
+        
+        col.separator()
+        
         col.prop(md, "show_debug")
         col2 = col.column()
         col2.active = md.show_debug
         col2.prop(md, "show_debug_contacts")
         col2.prop(md, "show_debug_size")
-        col2.prop(md, "show_debug_cylinders")
         col2.prop(md, "show_debug_roots")
         col2.prop(md, "show_debug_frames")
         col2.prop(md, "show_debug_smoothing")
diff --git a/source/blender/editors/space_view3d/drawhair.c b/source/blender/editors/space_view3d/drawhair.c
index 012d73e..f37e022 100644
--- a/source/blender/editors/space_view3d/drawhair.c
+++ b/source/blender/editors/space_view3d/drawhair.c
@@ -83,6 +83,203 @@ static void draw_hair_curve(HairSystem *UNUSED(hsys), HairCurve *hair)
 	glPointSize(1.0f);
 }
 
+static void count_hairs(HairSystem *hsys, int *totpoints, int *validhairs)
+{
+	HairCurve *hair;
+	int i;
+	
+	*totpoints = *validhairs = 0;
+	for (hair = hsys->curves, i = 0; i < hsys->totcurves; ++hair, ++i) {
+		if (hair->totpoints > 1) {
+			*totpoints += hair->totpoints;
+			*validhairs += 1;
+		}
+	}
+}
+
+/* preview of hairs as cylinders */
+/* XXX warning, computation here hurts a lot! */
+static void draw_hair_hulls(HairSystem *hsys)
+{
+	HairCurve *hair;
+	HairPoint *point, *next_point;
+	int k, i, s;
+	float upvec[] = {0.0f, 0.0f, 1.0f};
+	float sidevec[] = {1.0f, 0.0f, 0.0f};
+
+	float radius_factor = 1.0f;
+	/* number of cylinder subdivisions */
+	int subdiv = 8;
+	
+	int totpoints, validhairs;
+	int tot_verts, tot_elems;
+
+	/* vertex array variables */
+	float (*vert_data)[3];
+	unsigned int *elem_data;
+	unsigned int offset = 0;
+	unsigned int elem_offset = 0;
+
+	static unsigned int hairbuf = 0;
+	static unsigned int hairelem = 0;
+
+	count_hairs(hsys, &totpoints, &validhairs);
+	/* twice for all for the normals */
+	tot_verts = totpoints * 2 * subdiv;
+	tot_elems = (totpoints - validhairs) * 6 * subdiv;
+
+	/* set up OpenGL code */
+	if (!hairbuf) {
+		glGenBuffers(1, &hairbuf);
+		glGenBuffers(1, &hairelem);
+	}
+	glBindBuffer(GL_ARRAY_BUFFER, hairbuf);
+	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, hairelem);
+	glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * tot_verts, NULL, GL_DYNAMIC_DRAW);
+	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * tot_elems, NULL, GL_DYNAMIC_DRAW);
+
+	glEnableClientState(GL_VERTEX_ARRAY);
+	glEnableClientState(GL_NORMAL_ARRAY);
+
+	glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), NULL);
+	glNormalPointer(GL_FLOAT, 6 * sizeof(float), (GLubyte *)NULL + 3 * sizeof(float));
+
+	vert_data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+	elem_data = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
+
+	/* generate the data and copy to the display buffers */
+	for (hair = hsys->curves, i = 0; i < hsys->totcurves; ++hair, ++i) {
+		float normal[3];
+		float dir[3];
+		float tangent[3];
+		unsigned int cur_offset = offset / 2;
+
+		if (hair->totpoints == 1)
+			continue;
+		point = hair->points;
+		next_point = hair->points + 1;
+
+		sub_v3_v3v3(dir, next_point->co, point->co);
+		normalize_v3_v3(normal, dir);
+
+		/* calculate a tangent by cross product between z vector and normal */
+		if (fabs(dot_v3v3(normal, upvec)) < 0.99f) {
+			cross_v3_v3v3(tangent, normal, upvec);
+		}
+		else
+			cross_v3_v3v3(tangent, normal, sidevec);
+
+		normalize_v3(tangent);
+
+		for (k = 0; k < hair->totpoints - 1; ++point, ++next_point, ++k) {
+			float pivot_axis[3];
+			float new_normal[3];
+			float cosine;
+			/* first step is to compute a tangent vector to the surface and rotate around the normal */
+			sub_v3_v3v3(dir, next_point->co, point->co);
+			normalize_v3_v3(new_normal, dir);
+			cosine = dot_v3v3(new_normal, normal);
+
+			cur_offset = offset / 2;
+
+			/* if needed rotate the previous original tangent to the new frame by using cross product between current
+			 * and previous segment */
+			if (fabs(cosine) < 0.999f) {
+				float rot_quat[4];
+				float halfcosine;
+				float halfsine;
+				/* substitute by cosine of half angle because we are doing smooth-like interpolation */
+				cosine = sqrt(0.5 + cosine * 0.5);
+
+				/* half angle cosines needed for quaternion rotation */
+				halfcosine = sqrt(0.5 + cosine * 0.5);
+				halfsine = sqrt(0.5 - cosine * 0.5);
+
+				cross_v3_v3v3(pivot_axis, normal, new_normal);
+				normalize_v3(pivot_axis);
+
+				rot_quat[0] = halfcosine;
+				rot_quat[1] = halfsine * pivot_axis[0];
+				rot_quat[2] = halfsine * pivot_axis[1];
+				rot_quat[3] = halfsine * pivot_axis[2];
+
+				mul_qt_v3(rot_quat, tangent);
+
+				/* also rotate by the half amount the rotation axis */
+				copy_v3_v3(pivot_axis, normal);
+				mul_qt_v3(rot_quat, pivot_axis);
+
+				normalize_v3(tangent);
+			}
+			else
+				copy_v3_v3(pivot_axis, normal);
+
+			copy_v3_v3(normal, new_normal);
+
+			/* and repeat */
+			copy_v3_v3(vert_data[offset], tangent);
+			mul_v3_fl(vert_data[offset], point->radius * radius_factor);
+			add_v3_v3(vert_data[offset++], point->co);
+			copy_v3_v3(vert_data[offset++], tangent);
+
+			/* create quaternion to rotate tangent around normal */
+			for (s = 1; s < subdiv; s++) {
+				float v_nor[3];
+				float rot_quat[4];
+				float half_angle = (M_PI * s) / subdiv;
+				float sine = sin(half_angle);
+
+				copy_v3_v3(v_nor, tangent);
+
+				rot_quat[0] = cos(half_angle);
+				rot_quat[1] = sine * pivot_axis[0];
+				rot_quat[2] = sine * pivot_axis[1];
+				rot_quat[3] = sine * pivot_axis[2];
+
+				mul_qt_v3(rot_quat, v_nor);
+				copy_v3_v3(vert_data[offset], v_nor);
+				mul_v3_fl(vert_data[offset], point->radius * radius_factor);
+				add_v3_v3(vert_data[offset++], point->co);
+				copy_v3_v3(vert_data[offset++], v_nor);
+			}
+
+			for (s = 0; s < subdiv; s++) {
+				elem_data[elem_offset++] = cur_offset + s;
+				elem_data[elem_offset++] = cur_offset + s + subdiv;
+				elem_data[elem_offset++] = cur_offset + (s + 1) % subdiv;
+
+				elem_data[elem_offset++] = cur_offset + s + subdiv;
+				elem_data[elem_offset++] = cur_offset + (s + 1) % subdiv;
+				elem_data[elem_offset++] = cur_offset + (s + 1) % subdiv + subdiv;
+			}
+		}
+
+		/* finally add the last point */
+		for (s = 0; s < subdiv; s++) {
+			add_v3_v3v3(vert_data[offset], vert_data[offset - 2 * subdiv], dir);
+			offset++;
+			copy_v3_v3(vert_data[offset], vert_data[offset - 2 * subdiv]);
+			offset++;
+		}
+
+	}
+
+	glUnmapBuffer(GL_ARRAY_BUFFER);
+	glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+
+	glEnable(GL_LIGHTING);
+	/* draw */
+	glShadeModel(GL_SMOOTH);
+	glDrawElements(GL_TRIANGLES, elem_offset, GL_UNSIGNED_INT, NULL);
+	glDisable(GL_LIGHTING);
+
+	glDisableClientState(GL_VERTEX_ARRAY);
+	glDisableClientState(GL_NORMAL_ARRAY);
+
+	glBindBuffer(GL_ARRAY_BUFFER, 0);
+	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+}
+
 /* called from drawobject.c, return true if nothing was drawn */
 bool draw_hair_system(Scene *UNUSED(scene), View3D *UNUSED(v3d), ARegion *ar, Base *base, HairSystem *hsys)
 {
@@ -95,8 +292,18 @@ bool draw_hair_system(Scene *UNUSED(scene), View3D *UNUSED(v3d), ARegion *ar, Ba
 	glLoadMatrixf(rv3d->viewmat);
 	glMultMatrixf(ob->obmat);
 	
-	for (hair = hsys->curves, i = 0; i < hsys->totcurves; ++hair, ++i) {
-		draw_hair_curve(hsys, hair);
+	switch (hsys->display.mode) {
+		case HAIR_DISPLAY_LINE:
+			for (hair = hsys->curves, i = 0; i < hsys->totcurves; ++hair, ++i) {
+				draw_hair_curve(hsys, hair);
+			}
+			break;
+		case HAIR_DISPLAY_RENDER:
+			// TODO
+			break;
+		case HAIR_DISPLAY_HULL:
+			draw_hair_hulls(hsys);
+			break;
 	}
 	
 	return retval;
@@ -109,7 +316,6 @@ bool draw_hair_system(Scene *UNUSED(scene), View3D *UNUSED(v3d), ARegion *ar, Ba
 #define SHOW_ROOTS
 #define SHOW_FRAMES
 //#define SHOW_SMOOTHING
-#define SHOW_CYLINDERS
 #define SHOW_CONTACTS
 
 static void draw_hair_debug_points(HairSystem *hsys, HAIR_SolverDebugPoint *dpoints, int dtotpoints)
@@ -353,190 +559,6 @@ static void draw_hair_debug_contacts(HairSystem *UNUSED(hsys), HAIR_SolverDebugC
 #endif
 }
 
-/* debug preview of hairs as cylinders. warning, computation here hurts a lot! */
-static void draw_hair_debug_cylinders(HairSystem *hsys, int totpoints, int valid_points)
-{
-#ifdef SHOW_CYLINDERS
-	HairCurve *hair;
-	HairPoint *point, *next_point;
-	int k, i, s;
-	float upvec[] = {0.0f, 0.0f, 1.0f};
-	float sidevec[] = {1.0f, 0.0f, 0.0f};
-
-	float radius_factor = 1.0f;
-	/* number of cylinder subdivisions */
-	int subdiv = 8;
-
-	/* vertex array variables */
-	float (*vert_data)[3];
-	unsigned int *elem_data;
-	unsigned int offset = 0;
-	unsigned int elem_offset = 0;
-
-	/* twive for all for the normals */
-	int tot_verts = totpoints * 2 * subdiv;
-	int tot_elems = (totpoints - valid_points) * 6 * subdiv;
-
-	static unsigned int hairbuf = 0;
-	static unsigned int hairelem = 0;
-
-	/* set up OpenGL code */
-	if (!hairbuf) {
-		glGenBuffers(1, &hairbuf);
-		glGenBuffers(1, &hairelem);
-	}
-	glBindBuffer(GL_ARRAY_BUFFER, hairbuf);
-	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, hairelem);
-	glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * tot_verts, NULL, GL_DYNAMIC_DRAW);
-	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * tot_elems, NULL, GL_DYNAMIC_DRAW);
-
-	glEnableClientState(GL_VERTEX_ARRAY);
-	glEnableClientState(GL_NORMAL_ARRAY);
-
-	glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), NULL);
-	glNormalPointer(GL_FLOAT, 6 * sizeof(float), (GLubyte *)NULL + 3 * sizeof(float));
-
-	vert_data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
-	elem_data = glMapB

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list