[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 = ®ion->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 = ®ion->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 = ®ion->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 = ®ion->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