Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOve Murberg Henriksen <sorayasilvermoon@hotmail.com>2012-05-23 14:56:06 +0400
committerOve Murberg Henriksen <sorayasilvermoon@hotmail.com>2012-05-23 14:56:06 +0400
commit736daa9f046958195112a46df084525120bacec2 (patch)
tree5c6e5705479db19fdeedf0b20514284a32072034 /source/blender/editors/object
parentc4c75c33d0dd3222285b6799da3656316776592a (diff)
parentc0f59c44f8f4a15368335337adc7b9aafbe3fca6 (diff)
svn merge ^/trunk/blender -r46844:HEAD
Diffstat (limited to 'source/blender/editors/object')
-rw-r--r--source/blender/editors/object/object_bake.c2
-rw-r--r--source/blender/editors/object/object_intern.h4
-rw-r--r--source/blender/editors/object/object_modifier.c415
-rw-r--r--source/blender/editors/object/object_ops.c5
4 files changed, 423 insertions, 3 deletions
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index b89562e772b..810fe244984 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -534,7 +534,7 @@ static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm, const int *orig
int grid_index = origindex[face_index];
int loc_offs = face_index % (1 << (2 * lvl));
int cell_index = loc_offs % ((side - 1) * (side - 1));
- int cell_side = grid_size / (side - 1);
+ int cell_side = (grid_size - 1) / (side - 1);
int row = cell_index / (side - 1);
int col = cell_index % (side - 1);
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 4d67a620939..6f3cca442f0 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -160,6 +160,10 @@ void OBJECT_OT_multires_external_pack(struct wmOperatorType *ot);
void OBJECT_OT_meshdeform_bind(struct wmOperatorType *ot);
void OBJECT_OT_explode_refresh(struct wmOperatorType *ot);
void OBJECT_OT_ocean_bake(struct wmOperatorType *ot);
+void OBJECT_OT_skin_root_mark(struct wmOperatorType *ot);
+void OBJECT_OT_skin_loose_mark_clear(struct wmOperatorType *ot);
+void OBJECT_OT_skin_radii_equalize(struct wmOperatorType *ot);
+void OBJECT_OT_skin_armature_create(struct wmOperatorType *ot);
/* object_constraint.c */
void OBJECT_OT_constraint_add(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 47748fbd53b..9e891353f35 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -35,6 +35,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_anim_types.h"
+#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
@@ -42,6 +43,7 @@
#include "DNA_object_force.h"
#include "DNA_scene_types.h"
+#include "BLI_bitmap.h"
#include "BLI_math.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
@@ -85,6 +87,8 @@
#include "object_intern.h"
+static void modifier_skin_customdata_ensure(struct Object *ob);
+
/******************************** API ****************************/
ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type)
@@ -157,6 +161,10 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc
/* ensure that grid paint mask layer is created */
ED_sculpt_mask_layers_ensure(ob, (MultiresModifierData *)new_md);
}
+ else if (type == eModifierType_Skin) {
+ /* ensure skin-node customdata exists */
+ modifier_skin_customdata_ensure(ob);
+ }
}
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -1131,7 +1139,7 @@ static int multires_reshape_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- CTX_DATA_BEGIN (C, Object *, selob, selected_editable_objects)
+ CTX_DATA_BEGIN(C, Object *, selob, selected_editable_objects)
{
if (selob->type == OB_MESH && selob != ob) {
secondob = selob;
@@ -1327,6 +1335,409 @@ void OBJECT_OT_multires_base_apply(wmOperatorType *ot)
}
+/************************** skin modifier ***********************/
+
+static void modifier_skin_customdata_ensure(Object *ob)
+{
+ Mesh *me = ob->data;
+ BMesh *bm = me->edit_btmesh ? me->edit_btmesh->bm : NULL;
+ MVertSkin *vs;
+
+ if (bm && !CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN)) {
+ BMVert *v;
+ BMIter iter;
+
+ BM_data_layer_add(bm, &bm->vdata, CD_MVERT_SKIN);
+
+ /* Mark an arbitrary vertex as root */
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ vs = CustomData_bmesh_get(&bm->vdata, v->head.data,
+ CD_MVERT_SKIN);
+ vs->flag |= MVERT_SKIN_ROOT;
+ break;
+ }
+ }
+ else if (!CustomData_has_layer(&me->vdata, CD_MVERT_SKIN)) {
+ vs = CustomData_add_layer(&me->vdata,
+ CD_MVERT_SKIN,
+ CD_DEFAULT,
+ NULL,
+ me->totvert);
+
+ /* Mark an arbitrary vertex as root */
+ vs->flag |= MVERT_SKIN_ROOT;
+ }
+}
+
+static int skin_poll(bContext *C)
+{
+ return (!CTX_data_edit_object(C) &&
+ edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH)));
+}
+
+static int skin_edit_poll(bContext *C)
+{
+ return (CTX_data_edit_object(C) &&
+ edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH)));
+}
+
+static void skin_root_clear(BMesh *bm, BMVert *bm_vert, GHash *visited)
+{
+ BMEdge *bm_edge;
+ BMIter bm_iter;
+
+ BM_ITER_ELEM (bm_edge, &bm_iter, bm_vert, BM_EDGES_OF_VERT) {
+ BMVert *v2 = BM_edge_other_vert(bm_edge, bm_vert);
+
+ if (!BLI_ghash_lookup(visited, v2)) {
+ MVertSkin *vs = CustomData_bmesh_get(&bm->vdata,
+ v2->head.data,
+ CD_MVERT_SKIN);
+
+ /* clear vertex root flag and add to visited set */
+ vs->flag &= ~MVERT_SKIN_ROOT;
+ BLI_ghash_insert(visited, v2, v2);
+
+ skin_root_clear(bm, v2, visited);
+ }
+ }
+}
+
+static int skin_root_mark_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = CTX_data_edit_object(C);
+ Mesh *me = ob->data;
+ BMesh *bm = me->edit_btmesh->bm;
+ BMVert *bm_vert;
+ BMIter bm_iter;
+ GHash *visited;
+
+ visited = BLI_ghash_ptr_new("skin_root_mark_exec visited");
+
+ modifier_skin_customdata_ensure(ob);
+
+ BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) {
+ if (!BLI_ghash_lookup(visited, bm_vert) &&
+ bm_vert->head.hflag & BM_ELEM_SELECT)
+ {
+ MVertSkin *vs = CustomData_bmesh_get(&bm->vdata,
+ bm_vert->head.data,
+ CD_MVERT_SKIN);
+
+ /* mark vertex as root and add to visited set */
+ vs->flag |= MVERT_SKIN_ROOT;
+ BLI_ghash_insert(visited, bm_vert, bm_vert);
+
+ /* clear root flag from all connected vertices (recursively) */
+ skin_root_clear(bm, bm_vert, visited);
+ }
+ }
+
+ BLI_ghash_free(visited, NULL, NULL);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_skin_root_mark(wmOperatorType *ot)
+{
+ ot->name = "Skin Root Mark";
+ ot->description = "Mark selected vertices as roots";
+ ot->idname = "OBJECT_OT_skin_root_mark";
+
+ ot->poll = skin_edit_poll;
+ ot->exec = skin_root_mark_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+typedef enum {
+ SKIN_LOOSE_MARK,
+ SKIN_LOOSE_CLEAR
+} SkinLooseAction;
+
+static int skin_loose_mark_clear_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = CTX_data_edit_object(C);
+ Mesh *me = ob->data;
+ BMesh *bm = me->edit_btmesh->bm;
+ BMVert *bm_vert;
+ BMIter bm_iter;
+ SkinLooseAction action = RNA_enum_get(op->ptr, "action");
+
+ BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) {
+ if (bm_vert->head.hflag & BM_ELEM_SELECT) {
+ MVertSkin *vs = CustomData_bmesh_get(&bm->vdata,
+ bm_vert->head.data,
+ CD_MVERT_SKIN);
+
+
+ switch (action) {
+ case SKIN_LOOSE_MARK:
+ vs->flag |= MVERT_SKIN_LOOSE;
+ break;
+ case SKIN_LOOSE_CLEAR:
+ vs->flag &= ~MVERT_SKIN_LOOSE;
+ break;
+ }
+ }
+ }
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_skin_loose_mark_clear(wmOperatorType *ot)
+{
+ static EnumPropertyItem action_items[] = {
+ {SKIN_LOOSE_MARK, "MARK", 0, "Mark", "Mark selected vertices as loose"},
+ {SKIN_LOOSE_CLEAR, "CLEAR", 0, "Clear", "Set selected vertices as not loose"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ ot->name = "Skin Mark/Clear Loose";
+ ot->description = "Mark/clear selected vertices as loose";
+ ot->idname = "OBJECT_OT_skin_loose_mark_clear";
+
+ ot->poll = skin_edit_poll;
+ ot->exec = skin_loose_mark_clear_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_enum(ot->srna, "action", action_items, SKIN_LOOSE_MARK, "Action", NULL);
+}
+
+static int skin_radii_equalize_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = CTX_data_edit_object(C);
+ Mesh *me = ob->data;
+ BMesh *bm = me->edit_btmesh->bm;
+ BMVert *bm_vert;
+ BMIter bm_iter;
+
+ BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) {
+ if (bm_vert->head.hflag & BM_ELEM_SELECT) {
+ MVertSkin *vs = CustomData_bmesh_get(&bm->vdata,
+ bm_vert->head.data,
+ CD_MVERT_SKIN);
+ float avg = (vs->radius[0] + vs->radius[1]) * 0.5f;
+
+ vs->radius[0] = vs->radius[1] = avg;
+ }
+ }
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_skin_radii_equalize(wmOperatorType *ot)
+{
+ ot->name = "Skin Radii Equalize";
+ ot->description = "Make skin radii of selected vertices equal";
+ ot->idname = "OBJECT_OT_skin_radii_equalize";
+
+ ot->poll = skin_edit_poll;
+ ot->exec = skin_radii_equalize_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static void skin_armature_bone_create(Object *skin_ob,
+ MVert *mvert, MEdge *medge,
+ bArmature *arm,
+ BLI_bitmap edges_visited,
+ const MeshElemMap *emap,
+ EditBone *parent_bone,
+ int parent_v)
+{
+ int i;
+
+ for (i = 0; i < emap[parent_v].count; i++) {
+ int endx = emap[parent_v].indices[i];
+ const MEdge *e = &medge[endx];
+ EditBone *bone;
+ bDeformGroup *dg;
+ int v;
+
+ /* ignore edge if already visited */
+ if (BLI_BITMAP_GET(edges_visited, endx))
+ continue;
+ BLI_BITMAP_SET(edges_visited, endx);
+
+ v = (e->v1 == parent_v ? e->v2 : e->v1);
+
+ bone = MEM_callocN(sizeof(EditBone),
+ "skin_armature_bone_create EditBone");
+
+ bone->parent = parent_bone;
+ bone->layer = 1;
+ bone->flag |= BONE_CONNECTED;
+
+ copy_v3_v3(bone->head, mvert[parent_v].co);
+ copy_v3_v3(bone->tail, mvert[v].co);
+ bone->rad_head = bone->rad_tail = 0.25;
+ BLI_snprintf(bone->name, sizeof(bone->name), "Bone.%.2d", endx);
+
+ BLI_addtail(arm->edbo, bone);
+
+ /* add bDeformGroup */
+ if ((dg = ED_vgroup_add_name(skin_ob, bone->name))) {
+ ED_vgroup_vert_add(skin_ob, dg, parent_v, 1, WEIGHT_REPLACE);
+ ED_vgroup_vert_add(skin_ob, dg, v, 1, WEIGHT_REPLACE);
+ }
+
+ skin_armature_bone_create(skin_ob,
+ mvert, medge,
+ arm,
+ edges_visited,
+ emap,
+ bone,
+ v);
+ }
+}
+
+static Object *modifier_skin_armature_create(struct Scene *scene,
+ Object *skin_ob)
+{
+ BLI_bitmap edges_visited;
+ DerivedMesh *deform_dm;
+ MVert *mvert;
+ Mesh *me = skin_ob->data;
+ Object *arm_ob;
+ bArmature *arm;
+ MVertSkin *mvert_skin;
+ MeshElemMap *emap;
+ int *emap_mem;
+ int v;
+
+ deform_dm = mesh_get_derived_deform(scene, skin_ob, CD_MASK_BAREMESH);
+ mvert = deform_dm->getVertArray(deform_dm);
+
+ /* add vertex weights to original mesh */
+ CustomData_add_layer(&me->vdata,
+ CD_MDEFORMVERT,
+ CD_CALLOC,
+ NULL,
+ me->totvert);
+
+ arm_ob = BKE_object_add(scene, OB_ARMATURE);
+ BKE_object_transform_copy(arm_ob, skin_ob);
+ arm = arm_ob->data;
+ arm->layer = 1;
+ arm_ob->dtx |= OB_DRAWXRAY;
+ arm->drawtype = ARM_LINE;
+ arm->edbo = MEM_callocN(sizeof(ListBase), "edbo armature");
+
+ mvert_skin = CustomData_get_layer(&me->vdata, CD_MVERT_SKIN);
+ create_vert_edge_map(&emap, &emap_mem,
+ me->medge, me->totvert, me->totedge);
+
+ edges_visited = BLI_BITMAP_NEW(me->totedge, "edge_visited");
+
+ /* note: we use EditBones here, easier to set them up and use
+ * edit-armature functions to convert back to regular bones */
+ for (v = 0; v < me->totvert; v++) {
+ if (mvert_skin[v].flag & MVERT_SKIN_ROOT) {
+ EditBone *bone = NULL;
+
+ /* Unless the skin root has just one adjacent edge, create
+ * a fake root bone (have it going off in the Y direction
+ * (arbitrary) */
+ if (emap[v].count > 1) {
+ bone = MEM_callocN(sizeof(EditBone), "EditBone");
+
+ copy_v3_v3(bone->head, me->mvert[v].co);
+ copy_v3_v3(bone->tail, me->mvert[v].co);
+ bone->layer = 1;
+
+ bone->head[1] = 1.0f;
+ bone->rad_head = bone->rad_tail = 0.25;
+
+ BLI_addtail(arm->edbo, bone);
+ }
+
+ if (emap[v].count >= 1) {
+ skin_armature_bone_create(skin_ob,
+ mvert, me->medge,
+ arm,
+ edges_visited,
+ emap,
+ bone,
+ v);
+ }
+ }
+ }
+
+ MEM_freeN(edges_visited);
+ MEM_freeN(emap);
+ MEM_freeN(emap_mem);
+
+ ED_armature_from_edit(arm_ob);
+ ED_armature_edit_free(arm_ob);
+
+ return arm_ob;
+}
+
+static int skin_armature_create_exec(bContext *C, wmOperator *op)
+{
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C), *arm_ob;
+ ModifierData *skin_md;
+ ArmatureModifierData *arm_md;
+
+ /* create new armature */
+ arm_ob = modifier_skin_armature_create(scene, ob);
+
+ /* add a modifier to connect the new armature to the mesh */
+ arm_md = (ArmatureModifierData *)modifier_new(eModifierType_Armature);
+ if (arm_md) {
+ skin_md = edit_modifier_property_get(op, ob, eModifierType_Skin);
+ BLI_insertlinkafter(&ob->modifiers, skin_md, arm_md);
+
+ arm_md->object = arm_ob;
+ arm_md->deformflag = ARM_DEF_VGROUP | ARM_DEF_QUATERNION;
+ DAG_scene_sort(bmain, scene);
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ }
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static int skin_armature_create_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+{
+ if (edit_modifier_invoke_properties(C, op))
+ return skin_armature_create_exec(C, op);
+ else
+ return OPERATOR_CANCELLED;
+}
+
+void OBJECT_OT_skin_armature_create(wmOperatorType *ot)
+{
+ ot->name = "Skin Armature Create";
+ ot->description = "Create an armature that parallels the skin layout";
+ ot->idname = "OBJECT_OT_skin_armature_create";
+
+ ot->poll = skin_poll;
+ ot->invoke = skin_armature_create_invoke;
+ ot->exec = skin_armature_create_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ edit_modifier_properties(ot);
+}
+
/************************ mdef bind operator *********************/
static int meshdeform_poll(bContext *C)
@@ -1516,7 +1927,7 @@ static void oceanbake_free(void *customdata)
/* called by oceanbake, only to check job 'stop' value */
static int oceanbake_breakjob(void *UNUSED(customdata))
{
- //OceanBakeJob *ob= (OceanBakeJob *)customdata;
+ //OceanBakeJob *ob = (OceanBakeJob *)customdata;
//return *(ob->stop);
/* this is not nice yet, need to make the jobs list template better
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index afc493f66f9..0c50ab58487 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -139,6 +139,11 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_multires_base_apply);
WM_operatortype_append(OBJECT_OT_multires_external_save);
WM_operatortype_append(OBJECT_OT_multires_external_pack);
+ WM_operatortype_append(OBJECT_OT_skin_root_mark);
+ WM_operatortype_append(OBJECT_OT_skin_loose_mark_clear);
+ WM_operatortype_append(OBJECT_OT_skin_radii_equalize);
+ WM_operatortype_append(OBJECT_OT_skin_armature_create);
+
WM_operatortype_append(OBJECT_OT_meshdeform_bind);
WM_operatortype_append(OBJECT_OT_explode_refresh);
WM_operatortype_append(OBJECT_OT_ocean_bake);