Commit: d618da3d8e4688783336ee036017373a1ce1509a
Author: Lukas Tönne
Date:   Thu Dec 4 14:02:27 2014 +0100
Branches: hair_immediate_fixes
https://developer.blender.org/rBd618da3d8e4688783336ee036017373a1ce1509a

Added back different selection modes (strands, verts, tips) for hair
editing.

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

M       release/scripts/startup/bl_ui/space_view3d.py
M       source/blender/blenkernel/BKE_edithair.h
M       source/blender/bmesh/intern/bmesh_strands.h
M       source/blender/editors/space_view3d/drawobject.c
M       source/blender/editors/space_view3d/drawstrands.c
M       source/blender/editors/space_view3d/view3d_intern.h
M       source/blender/makesdna/DNA_scene_types.h
M       source/blender/makesrna/intern/rna_sculpt_paint.c

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

diff --git a/release/scripts/startup/bl_ui/space_view3d.py 
b/release/scripts/startup/bl_ui/space_view3d.py
index 8642f1d..1374bf9 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -50,6 +50,8 @@ class VIEW3D_HT_header(Header):
             # Particle edit
             if mode == 'PARTICLE_EDIT':
                 row.prop(toolsettings.particle_edit, "select_mode", text="", 
expand=True)
+            elif mode == 'HAIR_EDIT':
+                row.prop(toolsettings.hair_edit, "select_mode", text="", 
expand=True)
 
             # Occlude geometry
             if ((view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'} and 
(mode == 'PARTICLE_EDIT' or (mode == 'EDIT' and obj.type == 'MESH'))) or
diff --git a/source/blender/blenkernel/BKE_edithair.h 
b/source/blender/blenkernel/BKE_edithair.h
index 5653047..57cb6aa 100644
--- a/source/blender/blenkernel/BKE_edithair.h
+++ b/source/blender/blenkernel/BKE_edithair.h
@@ -59,6 +59,7 @@ typedef struct BMEditStrands {
        
        unsigned int vertex_glbuf;
        unsigned int elem_glbuf;
+       unsigned int dot_glbuf;
 } BMEditStrands;
 
 struct BMEditStrands *BKE_editstrands_create(struct BMesh *bm, struct 
DerivedMesh *root_dm);
diff --git a/source/blender/bmesh/intern/bmesh_strands.h 
b/source/blender/bmesh/intern/bmesh_strands.h
index 96d5fa9..8410bfd 100644
--- a/source/blender/bmesh/intern/bmesh_strands.h
+++ b/source/blender/bmesh/intern/bmesh_strands.h
@@ -51,6 +51,24 @@ BLI_INLINE bool BM_strands_vert_is_root(BMVert *v)
        return false;
 }
 
+/* True if v is the tip of a strand */
+BLI_INLINE bool BM_strands_vert_is_tip(BMVert *v)
+{
+       BMEdge *e_first = v->e;
+       BMEdge *e_next;
+       
+       e_next = bmesh_disk_edge_next(e_first, v);
+       
+       /* with a single edge, the vertex is either first or last of the curve;
+        * last vertex is defined as the tip
+        */
+       if (e_next == e_first) {
+               if (e_first->v2 == v)
+                       return true;
+       }
+       return false;
+}
+
 int BM_strands_count(BMesh *bm);
 int BM_strands_keys_count(BMVert *root);
 
diff --git a/source/blender/editors/space_view3d/drawobject.c 
b/source/blender/editors/space_view3d/drawobject.c
index 7ed5c71..d59f0de 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -7730,7 +7730,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, 
Base *base, const short
                if (ob->mode & OB_MODE_HAIR_EDIT && is_obact) {
                        BMEditStrands *edit = BKE_editstrands_from_object(ob);
                        if (edit) {
-                               draw_strands_edit(scene, v3d, edit);
+                               draw_strands_edit_hair(scene, v3d, edit);
                        }
                }
        }
diff --git a/source/blender/editors/space_view3d/drawstrands.c 
b/source/blender/editors/space_view3d/drawstrands.c
index 282621e..30e6716 100644
--- a/source/blender/editors/space_view3d/drawstrands.c
+++ b/source/blender/editors/space_view3d/drawstrands.c
@@ -61,6 +61,7 @@ typedef struct StrandsDrawInfo {
        bool use_zbuf_select;
        
        StrandsShadeMode shade_mode;
+       int select_mode;
        
        float col_base[4];
        float col_select[4];
@@ -71,19 +72,21 @@ BLI_INLINE bool strands_use_normals(const StrandsDrawInfo 
*info)
        return ELEM(info->shade_mode, STRANDS_SHADE_HAIR);
 }
 
-static void init_draw_info(StrandsDrawInfo *info, View3D *v3d)
+static void init_draw_info(StrandsDrawInfo *info, View3D *v3d,
+                           StrandsShadeMode shade_mode, int select_mode)
 {
        info->has_zbuf = v3d->zbuf;
        info->use_zbuf_select = (v3d->flag & V3D_ZBUF_SELECT);
        
-       info->shade_mode = STRANDS_SHADE_HAIR;
+       info->shade_mode = shade_mode;
+       info->select_mode = select_mode;
        
        /* get selection theme colors */
        UI_GetThemeColor4fv(TH_VERTEX, info->col_base);
        UI_GetThemeColor4fv(TH_VERTEX_SELECT, info->col_select);
 }
 
-static void set_opengl_state(const StrandsDrawInfo *info)
+static void set_opengl_state_strands(const StrandsDrawInfo *info)
 {
        if (!info->use_zbuf_select)
                glDisable(GL_DEPTH_TEST);
@@ -104,6 +107,18 @@ static void set_opengl_state(const StrandsDrawInfo *info)
                glEnableClientState(GL_NORMAL_ARRAY);
 }
 
+static void set_opengl_state_dots(const StrandsDrawInfo *info)
+{
+       if (!info->use_zbuf_select)
+               glDisable(GL_DEPTH_TEST);
+       glEnable(GL_BLEND);
+       
+       glDisable(GL_LIGHTING);
+       
+       glEnableClientState(GL_VERTEX_ARRAY);
+       glPointSize(3.0);
+}
+
 static void restore_opengl_state(const StrandsDrawInfo *info)
 {
        glDisableClientState(GL_NORMAL_ARRAY);
@@ -120,8 +135,9 @@ static void restore_opengl_state(const StrandsDrawInfo 
*info)
 }
 
 /* ------------------------------------------------------------------------- */
+/* strands */
 
-static void setup_gpu_buffers(BMEditStrands *edit, const StrandsDrawInfo *info)
+static void setup_gpu_buffers_strands(BMEditStrands *edit, const 
StrandsDrawInfo *info)
 {
        const size_t size_v3 = sizeof(float) * 3;
        const size_t size_vertex = (strands_use_normals(info) ? 2*size_v3 : 
size_v3);
@@ -136,8 +152,9 @@ static void setup_gpu_buffers(BMEditStrands *edit, const 
StrandsDrawInfo *info)
                glGenBuffers(1, &edit->elem_glbuf);
        
        glBindBuffer(GL_ARRAY_BUFFER, edit->vertex_glbuf);
-       glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, edit->elem_glbuf);
        glBufferData(GL_ARRAY_BUFFER, size_vertex * totvert, NULL, 
GL_DYNAMIC_DRAW);
+       
+       glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, edit->elem_glbuf);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * totedge * 
2, NULL, GL_DYNAMIC_DRAW);
        
        glVertexPointer(3, GL_FLOAT, size_vertex, NULL);
@@ -145,13 +162,13 @@ static void setup_gpu_buffers(BMEditStrands *edit, const 
StrandsDrawInfo *info)
                glNormalPointer(GL_FLOAT, size_vertex, (GLubyte *)NULL + 
size_v3);
 }
 
-static void unbind_gpu_buffers(void)
+static void unbind_gpu_buffers_strands(void)
 {
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 }
 
-static void write_gpu_buffers(BMEditStrands *edit, const StrandsDrawInfo *info)
+static int write_gpu_buffers_strands(BMEditStrands *edit, const 
StrandsDrawInfo *info)
 {
        const size_t size_v3 = sizeof(float) * 3;
        const size_t size_vertex = (strands_use_normals(info) ? 2*size_v3 : 
size_v3);
@@ -207,20 +224,124 @@ static void write_gpu_buffers(BMEditStrands *edit, const 
StrandsDrawInfo *info)
        
        glUnmapBuffer(GL_ARRAY_BUFFER);
        glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+       
+       return index_edge;
+}
+
+/* ------------------------------------------------------------------------- */
+/* dots */
+
+static void setup_gpu_buffers_dots(BMEditStrands *edit, const StrandsDrawInfo 
*info)
+{
+       const size_t size_v3 = sizeof(float) * 3;
+       const size_t size_vertex = size_v3;
+       
+       BMVert *v;
+       BMIter iter;
+       int totvert;
+       
+       switch (info->select_mode) {
+               case HAIR_SELECT_STRAND:
+                       totvert = 0;
+                       break;
+               case HAIR_SELECT_VERTEX:
+                       totvert = edit->bm->totvert;
+                       break;
+               case HAIR_SELECT_TIP:
+                       totvert = 0;
+                       BM_ITER_MESH(v, &iter, edit->bm, BM_VERTS_OF_MESH) {
+                               if (BM_strands_vert_is_tip(v))
+                                       ++totvert;
+                       }
+                       break;
+       }
+       
+       if (totvert == 0)
+               return;
+       
+       if (!edit->dot_glbuf)
+               glGenBuffers(1, &edit->dot_glbuf);
+       
+       glBindBuffer(GL_ARRAY_BUFFER, edit->dot_glbuf);
+       glBufferData(GL_ARRAY_BUFFER, size_vertex * totvert, NULL, 
GL_DYNAMIC_DRAW);
+       
+       glVertexPointer(3, GL_FLOAT, size_vertex, NULL);
+}
+
+static void unbind_gpu_buffers_dots(void)
+{
+       glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+static int write_gpu_buffers_dots(BMEditStrands *edit, const StrandsDrawInfo 
*info)
+{
+       const size_t size_v3 = sizeof(float) * 3;
+       const size_t size_vertex = size_v3;
+       
+       GLubyte *vertex_data;
+       BMVert *v;
+       BMIter iter;
+       int index_dot;
+       
+       if (info->select_mode == HAIR_SELECT_STRAND)
+               return 0;
+       
+       vertex_data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+       
+       BM_mesh_elem_index_ensure(edit->bm, BM_VERT);
+       
+       index_dot = 0;
+       switch (info->select_mode) {
+               case HAIR_SELECT_STRAND:
+                       /* already exited, but keep the case for the compiler */
+                       break;
+               case HAIR_SELECT_VERTEX:
+                       BM_ITER_MESH(v, &iter, edit->bm, BM_VERTS_OF_MESH) {
+                               size_t offset_co = index_dot * size_vertex;
+                               copy_v3_v3((float *)(vertex_data + offset_co), 
v->co);
+                               ++index_dot;
+                       }
+                       break;
+               case HAIR_SELECT_TIP:
+                       BM_ITER_MESH(v, &iter, edit->bm, BM_VERTS_OF_MESH) {
+                               if (BM_strands_vert_is_tip(v)) {
+                                       size_t offset_co = index_dot * 
size_vertex;
+                                       copy_v3_v3((float *)(vertex_data + 
offset_co), v->co);
+                                       ++index_dot;
+                               }
+                       }
+                       break;
+       }
+       
+       glUnmapBuffer(GL_ARRAY_BUFFER);
+       
+       return index_dot;
 }
 
-void draw_strands_edit(Scene *UNUSED(scene), View3D *v3d, BMEditStrands *edit)
+/* ------------------------------------------------------------------------- */
+
+void draw_strands_edit_hair(Scene *scene, View3D *v3d, BMEditStrands *edit)
 {
+       HairEditSettings *settings = &scene->toolsettings->hair_edit;
+       
        StrandsDrawInfo info;
+       int totelem;
        
-       init_draw_info(&info, v3d);
+       init_draw_info(&info, v3d, STRANDS_SHADE_HAIR, settings->select_mode);
        
-       set_opengl_state(&info);
+       set_opengl_state_strands(&info);
+       setup_gpu_buffers_strands(edit, &info);
+       totelem = write_gpu_buffers_strands(edit, &info);
+       if (totelem > 0)
+               glDrawElements(GL_LINES, totelem, GL_UNSIGNED_INT, NULL);
+       unbind_gpu_buffers_strands();
        
-       setup_gpu_buffers(edit, &info);
-       write_gpu_buffers(edit, &info);
-       glDrawElements(GL_LINES, edit->bm->totedge * 2, GL_UNSIGNED_INT, NULL);
-       unbind_gpu_buffers();
+       set_opengl_state_dots(&info);
+       setup_gpu_buffers_dots(edit, &info);
+       totelem = write_gpu_buffers_dots(edit, &info);
+       if (totelem > 0)
+               glDrawArrays(GL_POINTS, 0, totelem);
+       unbind_gpu_buffers_dots();
        
        restore_opengl_state(&info);
 }
diff --git a/source/blender/editors/space_view3d/view3d_intern.h 
b/source/blender/editors/space_view3d/view3d_intern.h
index 430d0f2..3b9ae75 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -185,7 +185,7 @@ void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d,
 void draw_sim_debug_data(Scene *scene, View3D *v3d, ARegion *ar, Base *base, 
struct SimDebugData *debug_data);
 
 /* drawstrands.c */
-void draw_strands_edit(Scene *scene, View3D *v3d, struct BMEditStrands *edit);
+void draw_strands_edit_hair(Scene *scene, View3D *v3d, struct BMEditStrands 

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to