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. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to