Commit: 2a5067d07c6831ca022117b542b2ea8b52227f06
Author: Lukas Tönne
Date:   Fri Jun 8 08:38:03 2018 +0100
Branches: hair_guides_grooming
https://developer.blender.org/rB2a5067d07c6831ca022117b542b2ea8b52227f06

Improved "Add Region" operator that binds to a selected face map and creates a 
default bundle.

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

M       release/scripts/startup/bl_ui/properties_data_groom.py
M       source/blender/blenkernel/BKE_groom.h
M       source/blender/blenkernel/intern/groom.c
M       source/blender/editors/groom/editgroom_region.c

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

diff --git a/release/scripts/startup/bl_ui/properties_data_groom.py 
b/release/scripts/startup/bl_ui/properties_data_groom.py
index f5ff9302fe1..84ce2b07983 100644
--- a/release/scripts/startup/bl_ui/properties_data_groom.py
+++ b/release/scripts/startup/bl_ui/properties_data_groom.py
@@ -93,9 +93,16 @@ class DATA_PT_groom_regions(DataButtonsPanel, Panel):
         groom = context.groom
         region = context.groom.regions.active
 
-        layout.template_list("GROOM_UL_regions", "regions",
-                             groom, "regions",
-                             groom.regions, "active_index")
+        row = layout.row()
+
+        row.template_list("GROOM_UL_regions", "regions",
+                          groom, "regions",
+                          groom.regions, "active_index")
+
+        col = row.column(align=True)
+        col.operator("groom.region_add", icon='ZOOMIN', text="")
+        #col.operator("object.material_slot_remove", icon='ZOOMOUT', text="")
+
         if region:
             col = layout.column()
             if groom.scalp_object:
diff --git a/source/blender/blenkernel/BKE_groom.h 
b/source/blender/blenkernel/BKE_groom.h
index 415c9feedab..20952819939 100644
--- a/source/blender/blenkernel/BKE_groom.h
+++ b/source/blender/blenkernel/BKE_groom.h
@@ -66,7 +66,7 @@ void BKE_groom_curve_cache_clear(struct Groom *groom);
 
 /* === Scalp regions === */
 
-struct Mesh* BKE_groom_get_scalp(const struct Depsgraph *depsgraph, struct 
Groom *groom);
+struct Mesh* BKE_groom_get_scalp(const struct Depsgraph *depsgraph, const 
struct Groom *groom);
 
 /* Set the region's facemap name.
  * Returns false if no facemap of that name can be found in the scalp object.
@@ -79,6 +79,8 @@ void BKE_groom_bind_scalp_regions(const struct Depsgraph 
*depsgraph, struct Groo
 bool BKE_groom_region_bind(const struct Depsgraph *depsgraph, struct Groom 
*groom, struct GroomRegion *region, bool force_rebind);
 void BKE_groom_region_unbind(struct GroomRegion *region);
 
+bool BKE_groom_region_reset_shape(const struct Depsgraph *depsgraph, const 
struct Groom *groom, struct GroomRegion *region);
+
 /* Calculates the scalp orientation at the root of the region */
 bool BKE_groom_calc_region_transform_on_scalp(const struct GroomRegion 
*region, const struct Mesh *scalp, float r_loc[3], float r_rot[3][3]);
 
diff --git a/source/blender/blenkernel/intern/groom.c 
b/source/blender/blenkernel/intern/groom.c
index 0aec6fc0da0..0cf3c952da2 100644
--- a/source/blender/blenkernel/intern/groom.c
+++ b/source/blender/blenkernel/intern/groom.c
@@ -295,7 +295,7 @@ void BKE_groom_boundbox_calc(Groom *groom)
 
 /* === Scalp regions === */
 
-Mesh* BKE_groom_get_scalp(const Depsgraph *depsgraph, Groom *groom)
+Mesh* BKE_groom_get_scalp(const Depsgraph *depsgraph, const Groom *groom)
 {
        if (groom->scalp_object)
        {
@@ -369,8 +369,9 @@ bool BKE_groom_calc_region_transform_on_scalp(const 
GroomRegion *region, const M
        }
 }
 
-static bool groom_shape_rebuild(GroomRegion *region, const Mesh *scalp)
+bool BKE_groom_region_reset_shape(const Depsgraph *depsgraph, const Groom 
*groom, GroomRegion *region)
 {
+       const Mesh *scalp = BKE_groom_get_scalp(depsgraph, groom);
        GroomBundle *bundle = &region->bundle;
        BLI_assert(region->scalp_samples != NULL);
        const int numshapeverts = region->numverts;
@@ -485,6 +486,19 @@ static bool groom_region_from_mesh_fmap(const Depsgraph 
*depsgraph, Groom *groom
        const int numverts = region->numverts = 
BMO_slot_buffer_count(op.slots_out, "boundary");
        region->scalp_samples = MEM_callocN(sizeof(*region->scalp_samples) * 
(numverts + 1), "groom bundle scalp region");
        
+       /* Clear verts since they depend on region.numverts
+        * TODO this is error-prone, make it more robust!
+        */
+       {
+               GroomBundle *bundle = &region->bundle;
+               bundle->totverts = 0;
+               if (bundle->verts)
+               {
+                       MEM_freeN(bundle->verts);
+                       bundle->verts = NULL;
+               }
+       }
+       
        float center_co[3]; /* average vertex location for placing the center */
        {
                BMLoop *l;
@@ -538,7 +552,7 @@ static bool groom_region_from_mesh_fmap(const Depsgraph 
*depsgraph, Groom *groom
 finalize:
        if (result == true)
        {
-               groom_shape_rebuild(region, scalp);
+               BKE_groom_region_reset_shape(depsgraph, groom, region);
        }
        else
        {
diff --git a/source/blender/editors/groom/editgroom_region.c 
b/source/blender/editors/groom/editgroom_region.c
index 0e869ef8e98..2812bc3da89 100644
--- a/source/blender/editors/groom/editgroom_region.c
+++ b/source/blender/editors/groom/editgroom_region.c
@@ -43,6 +43,7 @@
 #include "BKE_context.h"
 #include "BKE_groom.h"
 #include "BKE_library.h"
+#include "BKE_object_facemap.h"
 
 #include "DEG_depsgraph.h"
 
@@ -58,63 +59,49 @@
 #include "ED_view3d.h"
 #include "ED_groom.h"
 
+#include "UI_resources.h"
+#include "UI_interface.h"
+
 #include "groom_intern.h"
 
 /* GROOM_OT_region_add */
 
-static void groom_bundle_section_init(
-        GroomSection *section,
-        GroomSectionVertex *verts,
-        int numverts,
-        float mat[4][4],
-        float x,
-        float y,
-        float z)
+static void region_add_set_bundle_curve(GroomRegion *region, const float 
loc[3], const float rot[3][3], float length)
 {
-       section->center[0] = x;
-       section->center[1] = y;
-       section->center[2] = z;
-       mul_m4_v3(mat, section->center);
+       GroomBundle *bundle = &region->bundle;
        
-       {
-               const float radius = 0.5f;
-               GroomSectionVertex *vertex = verts;
-               for (int i = 0; i < numverts; ++i, ++vertex)
-               {
-                       float angle = 2*M_PI * (float)i / (float)numverts;
-                       vertex->co[0] = cos(angle) * radius;
-                       vertex->co[1] = sin(angle) * radius;
-               }
-       }
+       bundle->totsections = 2;
+       bundle->sections = MEM_callocN(sizeof(GroomSection) * 
bundle->totsections, "groom bundle sections");
+       
+       madd_v3_v3v3fl(bundle->sections[0].center, loc, rot[2], 0.0f);
+       madd_v3_v3v3fl(bundle->sections[1].center, loc, rot[2], length);
 }
 
-static GroomRegion* groom_add_region(float mat[4][4])
+static int region_add_poll(bContext *C)
 {
-       GroomRegion *region = MEM_callocN(sizeof(GroomRegion), "groom region");
-       GroomBundle *bundle = &region->bundle;
-       
-       region->numverts = 6;
-       bundle->totsections = 4;
-       bundle->totverts = region->numverts * bundle->totsections;
-       bundle->sections = MEM_mallocN(sizeof(GroomSection) * 
bundle->totsections, "groom bundle sections");
-       bundle->verts = MEM_mallocN(sizeof(GroomSectionVertex) * 
bundle->totverts, "groom bundle vertices");
-       
-       int numverts = region->numverts;
-       groom_bundle_section_init(&bundle->sections[0], &bundle->verts[numverts 
* 0], numverts, mat, 0.0, 0.0, 0.0);
-       groom_bundle_section_init(&bundle->sections[1], &bundle->verts[numverts 
* 1], numverts, mat, 0.0, 0.0, 1.0);
-       groom_bundle_section_init(&bundle->sections[2], &bundle->verts[numverts 
* 2], numverts, mat, 0.4, -0.2, 1.2);
-       groom_bundle_section_init(&bundle->sections[3], &bundle->verts[numverts 
* 3], numverts, mat, 0.01, 0.7, 1.6);
+       if (!ED_groom_object_poll(C))
+       {
+               return false;
+       }
        
-       return region;
+       /* We want a scalp object to make this useful */
+       Object *ob = ED_object_context(C);
+       Groom *groom = ob->data;
+       return groom->scalp_object != NULL;
 }
 
 static int region_add_exec(bContext *C, wmOperator *op)
 {
        const Depsgraph *depsgraph = CTX_data_depsgraph(C);
-       Object *obedit = ED_object_context(C);
-       Groom *groom = obedit->data;
+       Object *ob = ED_object_context(C);
+       Groom *groom = ob->data;
        char scalp_facemap_name[MAX_VGROUP_NAME];
-       RNA_string_get(op->ptr, "scalp_facemap_name", scalp_facemap_name);
+       RNA_string_get(op->ptr, "scalp_facemap", scalp_facemap_name);
+       if (scalp_facemap_name[0] == '\0' ||
+           !BKE_object_facemap_find_name(groom->scalp_object, 
scalp_facemap_name))
+       {
+               return OPERATOR_CANCELLED;
+       }
 
        WM_operator_view3d_unit_defaults(C, op);
 
@@ -124,7 +111,7 @@ static int region_add_exec(bContext *C, wmOperator *op)
                return OPERATOR_CANCELLED;
 
        float mat[4][4];
-       ED_object_new_primitive_matrix(C, obedit, loc, rot, mat);
+       ED_object_new_primitive_matrix(C, ob, loc, rot, mat);
 
        GroomRegion *region = MEM_callocN(sizeof(GroomRegion), "groom region");
        ListBase *regions = (groom->editgroom ? &groom->editgroom->regions : 
&groom->regions);
@@ -135,25 +122,44 @@ static int region_add_exec(bContext *C, wmOperator *op)
        zero_v3(scalp_loc);
        unit_m3(scalp_rot);
        
-       if (scalp_facemap_name[0] != '\0')
+       if (BKE_groom_set_region_scalp_facemap(groom, region, 
scalp_facemap_name))
        {
-               if (BKE_groom_set_region_scalp_facemap(groom, region, 
scalp_facemap_name))
+               const struct Mesh *scalp = BKE_groom_get_scalp(depsgraph, 
groom);
+               BLI_assert(scalp != NULL);
+               
+               if (BKE_groom_region_bind(depsgraph, groom, region, true))
                {
-                       const struct Mesh *scalp = 
BKE_groom_get_scalp(depsgraph, groom);
-                       BLI_assert(scalp != NULL);
-                       
-                       BKE_groom_region_bind(depsgraph, groom, region, true);
-                       
                        BKE_groom_calc_region_transform_on_scalp(region, scalp, 
scalp_loc, scalp_rot);
                }
        }
-
-       WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit);
-       DEG_id_tag_update(&obedit->id, OB_RECALC_DATA);
+       
+       region_add_set_bundle_curve(region, scalp_loc, scalp_rot, 1.0f);
+       BKE_groom_region_reset_shape(depsgraph, groom, region);
+       
+       WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+       DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
 
        return OPERATOR_FINISHED;
 }
 
+static void region_add_draw(bContext *C, wmOperator *op)
+{
+       uiLayout *layout = op->layout;
+       Object *ob = ED_object_context(C);
+       Groom *groom = ob->data;
+       PointerRNA scalp_ob_ptr;
+       RNA_id_pointer_create(&groom->scalp_object->id, &scalp_ob_ptr);
+
+       if (groom->scalp_object)
+       {
+               uiItemPointerR(layout, op->ptr, "scalp_facemap", &scalp_ob_ptr, 
"face_maps", NULL, ICON_NONE);
+       }
+       else
+       {
+               uiItemR(layout, op->ptr, "scalp_facemap", 0, NULL, ICON_NONE);
+       }
+}
+
 void GROOM_OT_region_add(wmOperatorType *ot)
 {
        /* identifiers */
@@ -163,13 +169,15 @@ void GROOM_OT_region_add(wmOperatorType *ot)
 
        /* api callbacks */
        ot->exec = region_add_exec;
-       ot->poll = ED_groom_object_poll;
+       ot->poll = region_add_poll;
+       ot->invoke = WM_operator_props_popup_confirm;
+       ot->ui = region_add_draw;
 
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 
        ED_object_add_generic_props(ot, false);
-       RNA_def_string(ot->srna, "

@@ Diff output truncated at 10240 characters. @@

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

Reply via email to