[Bf-blender-cvs] [2a5067d07c6] hair_guides_grooming: Improved "Add Region" operator that binds to a selected face map and creates a default bundle.

Lukas Tönne noreply at git.blender.org
Fri Jun 8 09:38:43 CEST 2018


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



More information about the Bf-blender-cvs mailing list