Ejemplo n.º 1
0
static int shape_key_move_exec(bContext *C, wmOperator *op)
{
	Object *ob = ED_object_context(C);

	Key *key = BKE_key_from_object(ob);
	const int type = RNA_enum_get(op->ptr, "type");
	const int totkey = key->totkey;
	const int act_index = ob->shapenr - 1;
	int new_index;

	switch (type) {
		case KB_MOVE_TOP:
			/* Replace the ref key only if we're at the top already (only for relative keys) */
			new_index = (ELEM(act_index, 0, 1) || key->type == KEY_NORMAL) ? 0 : 1;
			break;
		case KB_MOVE_BOTTOM:
			new_index = totkey - 1;
			break;
		case KB_MOVE_UP:
		case KB_MOVE_DOWN:
		default:
			new_index = (totkey + act_index + type) % totkey;
			break;
	}

	if (!BKE_keyblock_move(ob, act_index, new_index)) {
		return OPERATOR_CANCELLED;
	}

	DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
	WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);

	return OPERATOR_FINISHED;
}
Ejemplo n.º 2
0
/* Criteria:
 *  1) There must be an dopesheet/action editor, and it must be in a mode which uses actions...
 *        OR
 *     The NLA Editor is active (i.e. Animation Data panel -> new action)
 *  2) The associated AnimData block must not be in tweakmode
 */
static int action_new_poll(bContext *C)
{
	Scene *scene = CTX_data_scene(C);
	
	/* Check tweakmode is off (as you don't want to be tampering with the action in that case) */
	/* NOTE: unlike for pushdown, this operator needs to be run when creating an action from nothing... */	
	if (ED_operator_action_active(C)) {
		SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
		Object *ob = CTX_data_active_object(C);
		
		/* For now, actions are only for the active object, and on object and shapekey levels... */
		if (saction->mode == SACTCONT_ACTION) {
			/* XXX: This assumes that actions are assigned to the active object in this mode */
			if (ob) {
				if ((ob->adt == NULL) || (ob->adt->flag & ADT_NLA_EDIT_ON) == 0)
					return true;
			}
		}
		else if (saction->mode == SACTCONT_SHAPEKEY) {
			Key *key = BKE_key_from_object(ob);
			if (key) {
				if ((key->adt == NULL) || (key->adt->flag & ADT_NLA_EDIT_ON) == 0)
					return true;
			}
		}
	}
	else if (ED_operator_nla_active(C)) {
		if (!(scene->flag & SCE_NLA_EDIT_ON)) {
			return true;
		}
	}
	
	/* something failed... */
	return false;
}
Ejemplo n.º 3
0
static int shape_key_move_poll(bContext *C)
{
	/* Same as shape_key_mode_exists_poll above, but ensure we have at least two shapes! */
	Object *ob = ED_object_context(C);
	ID *data = (ob) ? ob->data : NULL;
	Key *key = BKE_key_from_object(ob);

	return (ob && !ob->id.lib && data && !data->lib && ob->mode != OB_MODE_EDIT && key && key->totkey > 1);
}
Ejemplo n.º 4
0
static void deformVertsEM(ModifierData *md, Object *ob,
                          struct BMEditMesh *UNUSED(editData),
                          DerivedMesh *derivedData,
                          float (*vertexCos)[3],
                          int numVerts)
{
	Key *key = BKE_key_from_object(ob);

	if (key && key->type == KEY_RELATIVE)
		deformVerts(md, ob, derivedData, vertexCos, numVerts, 0);
}
Ejemplo n.º 5
0
static Key *rna_ShapeKey_find_key(ID *id)
{
	switch (GS(id->name)) {
		case ID_CU: return ((Curve *)id)->key;
		case ID_KE: return (Key *)id;
		case ID_LT: return ((Lattice *)id)->key;
		case ID_ME: return ((Mesh *)id)->key;
		case ID_OB: return BKE_key_from_object((Object *)id);
		default: return NULL;
	}
}
Ejemplo n.º 6
0
static void ED_object_shape_key_add(bContext *C, Object *ob, const bool from_mix)
{
	KeyBlock *kb;
	if ((kb = BKE_object_shapekey_insert(ob, NULL, from_mix))) {
		Key *key = BKE_key_from_object(ob);
		/* for absolute shape keys, new keys may not be added last */
		ob->shapenr = BLI_findindex(&key->block, kb) + 1;

		WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
	}
}
void ControllerExporter::operator()(Object *ob)
{
	Object *ob_arm = bc_get_assigned_armature(ob);
	Key *key = BKE_key_from_object(ob);

	if (ob_arm) {
		export_skin_controller(ob, ob_arm);
	}
	if (key && this->export_settings->include_shapekeys) {
		export_morph_controller(ob, key);
	}
}
Ejemplo n.º 8
0
static void rna_Key_update_data(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
	Key *key = ptr->id.data;
	Object *ob;

	for (ob = bmain->object.first; ob; ob = ob->id.next) {
		if (BKE_key_from_object(ob) == key) {
			DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
			WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ob);
		}
	}
}
Ejemplo n.º 9
0
static bool object_shapekey_remove(Main *bmain, Object *ob)
{
	KeyBlock *kb;
	Key *key = BKE_key_from_object(ob);

	if (key == NULL) {
		return false;
	}

	kb = BLI_findlink(&key->block, ob->shapenr - 1);
	if (kb) {
		return BKE_object_shapekey_remove(bmain, ob, kb);
	}

	return false;
}
Ejemplo n.º 10
0
static void deformVerts(ModifierData *UNUSED(md), Object *ob,
                        DerivedMesh *UNUSED(derivedData),
                        float (*vertexCos)[3],
                        int numVerts,
                        ModifierApplyFlag UNUSED(flag))
{
	Key *key = BKE_key_from_object(ob);

	if (key && key->block.first) {
		int deformedVerts_tot;
		BKE_key_evaluate_object_ex(
		            ob, &deformedVerts_tot,
		            (float *)vertexCos, sizeof(*vertexCos) * numVerts);

	}
}
Ejemplo n.º 11
0
static int shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
	Object *ob = ED_object_context(C);
	Key *key = BKE_key_from_object(ob);
	KeyBlock *kb = BKE_keyblock_from_object(ob);

	if (!key || !kb)
		return OPERATOR_CANCELLED;
	
	for (kb = key->block.first; kb; kb = kb->next)
		kb->curval = 0.0f;

	DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
	WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
	
	return OPERATOR_FINISHED;
}
Ejemplo n.º 12
0
static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3],
                        int numVerts, ModifierApplyFlag UNUSED(flag))
{
	DerivedMesh *dm;
	ClothModifierData *clmd = (ClothModifierData *) md;
	
	/* check for alloc failing */
	if (!clmd->sim_parms || !clmd->coll_parms) {
		initData(md);

		if (!clmd->sim_parms || !clmd->coll_parms)
			return;
	}

	dm = get_dm(ob, NULL, derivedData, NULL, false, false);
	if (dm == derivedData)
		dm = CDDM_copy(dm);

	/* TODO(sergey): For now it actually duplicates logic from DerivedMesh.c
	 * and needs some more generic solution. But starting experimenting with
	 * this so close to the release is not that nice..
	 *
	 * Also hopefully new cloth system will arrive soon..
	 */
	if (derivedData == NULL && clmd->sim_parms->shapekey_rest) {
		KeyBlock *kb = BKE_keyblock_from_key(BKE_key_from_object(ob),
		                                     clmd->sim_parms->shapekey_rest);
		if (kb && kb->data != NULL) {
			float (*layerorco)[3];
			if (!(layerorco = DM_get_vert_data_layer(dm, CD_CLOTH_ORCO))) {
				DM_add_vert_layer(dm, CD_CLOTH_ORCO, CD_CALLOC, NULL);
				layerorco = DM_get_vert_data_layer(dm, CD_CLOTH_ORCO);
			}

			memcpy(layerorco, kb->data, sizeof(float) * 3 * numVerts);
		}
	}

	CDDM_apply_vert_coords(dm, vertexCos);

	DM_ensure_tessface(dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */

	clothModifier_do(clmd, md->scene, ob, dm, vertexCos);

	dm->release(dm);
}
Ejemplo n.º 13
0
static PointerRNA rna_Object_shape_key_add(
    Object *ob, bContext *C, ReportList *reports, const char *name, bool from_mix)
{
  Main *bmain = CTX_data_main(C);
  KeyBlock *kb = NULL;

  if ((kb = BKE_object_shapekey_insert(bmain, ob, name, from_mix))) {
    PointerRNA keyptr;

    RNA_pointer_create((ID *)BKE_key_from_object(ob), &RNA_ShapeKey, kb, &keyptr);
    WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);

    return keyptr;
  }
  else {
    BKE_reportf(reports, RPT_ERROR, "Object '%s' does not support shapes", ob->id.name + 2);
    return PointerRNA_NULL;
  }
}
void AnimationExporter::export_morph_animation(Object *ob)
{ 
	FCurve *fcu;
	char *transformName;
	Key *key = BKE_key_from_object(ob);
	if (!key) return;

	if (key->adt && key->adt->action) {
		fcu = (FCurve *)key->adt->action->curves.first;
		
		while (fcu) {
			transformName = extract_transform_name(fcu->rna_path);

			dae_animation(ob, fcu, transformName, true);
			
			fcu = fcu->next;
		}
	}

}
Ejemplo n.º 15
0
/* NOTE: This is to support old files from before Blender supported modifiers,
 * in some cases versioning code updates these so for new files this will
 * return an empty list. */
ModifierData *modifiers_getVirtualModifierList(Object *ob, VirtualModifierData *virtualModifierData)
{
	ModifierData *md;

	md = ob->modifiers.first;

	*virtualModifierData = virtualModifierCommonData;

	if (ob->parent) {
		if (ob->parent->type == OB_ARMATURE && ob->partype == PARSKEL) {
			virtualModifierData->amd.object = ob->parent;
			virtualModifierData->amd.modifier.next = md;
			virtualModifierData->amd.deformflag = ((bArmature *)(ob->parent->data))->deformflag;
			md = &virtualModifierData->amd.modifier;
		}
		else if (ob->parent->type == OB_CURVE && ob->partype == PARSKEL) {
			virtualModifierData->cmd.object = ob->parent;
			virtualModifierData->cmd.defaxis = ob->trackflag + 1;
			virtualModifierData->cmd.modifier.next = md;
			md = &virtualModifierData->cmd.modifier;
		}
		else if (ob->parent->type == OB_LATTICE && ob->partype == PARSKEL) {
			virtualModifierData->lmd.object = ob->parent;
			virtualModifierData->lmd.modifier.next = md;
			md = &virtualModifierData->lmd.modifier;
		}
	}

	/* shape key modifier, not yet for curves */
	if (ELEM(ob->type, OB_MESH, OB_LATTICE) && BKE_key_from_object(ob)) {
		if (ob->type == OB_MESH && (ob->shapeflag & OB_SHAPE_EDIT_MODE))
			virtualModifierData->smd.modifier.mode |= eModifierMode_Editmode | eModifierMode_OnCage;
		else
			virtualModifierData->smd.modifier.mode &= ~eModifierMode_Editmode | eModifierMode_OnCage;

		virtualModifierData->smd.modifier.next = md;
		md = &virtualModifierData->smd.modifier;
	}

	return md;
}
Ejemplo n.º 16
0
static void deformMatrices(ModifierData *md, Object *ob, DerivedMesh *derivedData,
                           float (*vertexCos)[3], float (*defMats)[3][3], int numVerts)
{
	Key *key = BKE_key_from_object(ob);
	KeyBlock *kb = BKE_keyblock_from_object(ob);
	float scale[3][3];

	(void)vertexCos; /* unused */

	if (kb && kb->totelem == numVerts && kb != key->refkey) {
		int a;

		if (ob->shapeflag & OB_SHAPE_LOCK) scale_m3_fl(scale, 1);
		else scale_m3_fl(scale, kb->curval);

		for (a = 0; a < numVerts; a++)
			copy_m3_m3(defMats[a], scale);
	}

	deformVerts(md, ob, derivedData, vertexCos, numVerts, 0);
}
Ejemplo n.º 17
0
static void deformMatricesEM(ModifierData *UNUSED(md), Object *ob,
                             struct BMEditMesh *UNUSED(editData),
                             DerivedMesh *UNUSED(derivedData),
                             float (*vertexCos)[3],
                             float (*defMats)[3][3],
                             int numVerts)
{
	Key *key = BKE_key_from_object(ob);
	KeyBlock *kb = BKE_keyblock_from_object(ob);
	float scale[3][3];

	(void)vertexCos; /* unused */

	if (kb && kb->totelem == numVerts && kb != key->refkey) {
		int a;
		scale_m3_fl(scale, kb->curval);

		for (a = 0; a < numVerts; a++)
			copy_m3_m3(defMats[a], scale);
	}
}
Ejemplo n.º 18
0
/* starting point and step size could be optional */
static int shape_key_retime_exec(bContext *C, wmOperator *UNUSED(op))
{
  Object *ob = ED_object_context(C);
  Key *key = BKE_key_from_object(ob);
  KeyBlock *kb = BKE_keyblock_from_object(ob);
  float cfra = 0.0f;

  if (!key || !kb) {
    return OPERATOR_CANCELLED;
  }

  for (kb = key->block.first; kb; kb = kb->next) {
    kb->pos = cfra;
    cfra += 0.1f;
  }

  DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
  WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);

  return OPERATOR_FINISHED;
}
Ejemplo n.º 19
0
/* Helper function to find the active AnimData block from the Action Editor context */
AnimData *ED_actedit_animdata_from_context(bContext *C)
{
	SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
	Object *ob = CTX_data_active_object(C);
	AnimData *adt = NULL;
	
	/* Get AnimData block to use */
	if (saction->mode == SACTCONT_ACTION) {
		/* Currently, "Action Editor" means object-level only... */
		if (ob) {
			adt = ob->adt;
		}
	}
	else if (saction->mode == SACTCONT_SHAPEKEY) {
		Key *key = BKE_key_from_object(ob);
		if (key) {
			adt = key->adt;
		}
	}
	
	return adt;
}
Ejemplo n.º 20
0
static void rna_Object_shape_key_remove(
        Object *ob, Main *bmain, ReportList *reports,
        PointerRNA *kb_ptr)
{
	KeyBlock *kb = kb_ptr->data;
	Key *key = BKE_key_from_object(ob);

	if ((key == NULL) || BLI_findindex(&key->block, kb) == -1) {
		BKE_reportf(reports, RPT_ERROR, "ShapeKey not found");
		return;
	}

	if (!BKE_object_shapekey_remove(bmain, ob, kb)) {
		BKE_reportf(reports, RPT_ERROR, "Could not remove ShapeKey");
		return;
	}

	DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
	WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);

	RNA_POINTER_INVALIDATE(kb_ptr);
}
bool AnimationExporter::hasAnimations(Scene *sce)
{
	LinkNode *node;

	for (node=this->export_settings->export_set; node; node=node->next) {
		Object *ob = (Object *)node->link;

		FCurve *fcu = 0;
		//Check for object transform animations
		if (ob->adt && ob->adt->action)
			fcu = (FCurve *)ob->adt->action->curves.first;
		//Check for Lamp parameter animations
		else if ( (ob->type == OB_LAMP) && ((Lamp *)ob->data)->adt && ((Lamp *)ob->data)->adt->action)
			fcu = (FCurve *)(((Lamp *)ob->data)->adt->action->curves.first);
		//Check for Camera parameter animations
		else if ( (ob->type == OB_CAMERA) && ((Camera *)ob->data)->adt && ((Camera *)ob->data)->adt->action)
			fcu = (FCurve *)(((Camera *)ob->data)->adt->action->curves.first);

		//Check Material Effect parameter animations.
		for (int a = 0; a < ob->totcol; a++) {
			Material *ma = give_current_material(ob, a + 1);
			if (!ma) continue;
			if (ma->adt && ma->adt->action) {
				fcu = (FCurve *)ma->adt->action->curves.first;
			}
		}

		//check shape key animation
		if (!fcu) {
			Key *key = BKE_key_from_object(ob);
			if (key && key->adt && key->adt->action)
				fcu = (FCurve *)key->adt->action->curves.first;
		}
		if (fcu)
			return true;
	}
	return false;
}
Ejemplo n.º 22
0
static bool ED_object_shape_key_remove_all(Main *bmain, Object *ob)
{
    Key *key;

    key = BKE_key_from_object(ob);
    if (key == NULL)
        return false;

    switch (GS(key->from->name)) {
    case ID_ME:
        ((Mesh *)key->from)->key    = NULL;
        break;
    case ID_CU:
        ((Curve *)key->from)->key   = NULL;
        break;
    case ID_LT:
        ((Lattice *)key->from)->key = NULL;
        break;
    }

    BKE_libblock_free_us(bmain, key);

    return true;
}
Ejemplo n.º 23
0
void GeometryExporter::operator()(Object *ob)
{ 
	// XXX don't use DerivedMesh, Mesh instead?
#if 0		
	DerivedMesh *dm = mesh_get_derived_final(mScene, ob, CD_MASK_BAREMESH);
#endif

	bool use_instantiation = this->export_settings->use_object_instantiation;
	Mesh *me = bc_get_mesh_copy( mScene, 
					ob,
					this->export_settings->export_mesh_type,
					this->export_settings->apply_modifiers,
					this->export_settings->triangulate);

	Mesh *mesh = (Mesh *) ob->data;
	me->flag = mesh->flag;

	std::string geom_id = get_geometry_id(ob, use_instantiation);
	std::vector<Normal> nor;
	std::vector<BCPolygonNormalsIndices> norind;

	// Skip if linked geometry was already exported from another reference
	if (use_instantiation && 
	    exportedGeometry.find(geom_id) != exportedGeometry.end())
	{
		return;
	}

	std::string geom_name = (use_instantiation) ? id_name(ob->data) : id_name(ob);

	exportedGeometry.insert(geom_id);

	bool has_color = (bool)CustomData_has_layer(&me->fdata, CD_MCOL);

	create_normals(nor, norind, me);

	// openMesh(geoId, geoName, meshId)
	openMesh(geom_id, geom_name);
	
	// writes <source> for vertex coords
	createVertsSource(geom_id, me);
	
	// writes <source> for normal coords
	createNormalsSource(geom_id, me, nor);

	bool has_uvs = (bool)CustomData_has_layer(&me->fdata, CD_MTFACE);
	
	// writes <source> for uv coords if mesh has uv coords
	if (has_uvs) {
		createTexcoordsSource(geom_id, me);
	}

	if (has_color) {
		createVertexColorSource(geom_id, me);
	}
	// <vertices>

	COLLADASW::Vertices verts(mSW);
	verts.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX));
	COLLADASW::InputList &input_list = verts.getInputList();
	COLLADASW::Input input(COLLADASW::InputSemantic::POSITION, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::POSITION));
	input_list.push_back(input);
	verts.add();

	createLooseEdgeList(ob, me, geom_id);

	// Only create Polylists if number of faces > 0
	if (me->totface > 0) {
		// XXX slow
		if (ob->totcol) {
			for (int a = 0; a < ob->totcol; a++) {
				createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind);
			}
		}
		else {
			createPolylist(0, has_uvs, has_color, ob, me, geom_id, norind);
		}
	}
	
	closeMesh();
	
	if (me->flag & ME_TWOSIDED) {
		mSW->appendTextBlock("<extra><technique profile=\"MAYA\"><double_sided>1</double_sided></technique></extra>");
	}

	closeGeometry();

	if (this->export_settings->include_shapekeys) {
		Key * key = BKE_key_from_object(ob);
		if (key) {
			KeyBlock * kb = (KeyBlock *)key->block.first;
			//skip the basis
			kb = kb->next;
			for (; kb; kb = kb->next) {
				BKE_keyblock_convert_to_mesh(kb, me);
				export_key_mesh(ob, me, kb);
			}
		}
	}

	BKE_libblock_free_us(G.main, me);

}
Ejemplo n.º 24
0
static bool object_shape_key_mirror(bContext *C, Object *ob,
                                    int *r_totmirr, int *r_totfail, bool use_topology)
{
	KeyBlock *kb;
	Key *key;
	int totmirr = 0, totfail = 0;

	*r_totmirr = *r_totfail = 0;

	key = BKE_key_from_object(ob);
	if (key == NULL)
		return 0;
	
	kb = BLI_findlink(&key->block, ob->shapenr - 1);

	if (kb) {
		char *tag_elem = MEM_callocN(sizeof(char) * kb->totelem, "shape_key_mirror");


		if (ob->type == OB_MESH) {
			Mesh *me = ob->data;
			MVert *mv;
			int i1, i2;
			float *fp1, *fp2;
			float tvec[3];

			ED_mesh_mirror_spatial_table(ob, NULL, NULL, 's');

			for (i1 = 0, mv = me->mvert; i1 < me->totvert; i1++, mv++) {
				i2 = mesh_get_x_mirror_vert(ob, i1, use_topology);
				if (i2 == i1) {
					fp1 = ((float *)kb->data) + i1 * 3;
					fp1[0] = -fp1[0];
					tag_elem[i1] = 1;
					totmirr++;
				}
				else if (i2 != -1) {
					if (tag_elem[i1] == 0 && tag_elem[i2] == 0) {
						fp1 = ((float *)kb->data) + i1 * 3;
						fp2 = ((float *)kb->data) + i2 * 3;

						copy_v3_v3(tvec,    fp1);
						copy_v3_v3(fp1, fp2);
						copy_v3_v3(fp2, tvec);

						/* flip x axis */
						fp1[0] = -fp1[0];
						fp2[0] = -fp2[0];
						totmirr++;
					}
					tag_elem[i1] = tag_elem[i2] = 1;
				}
				else {
					totfail++;
				}
			}

			ED_mesh_mirror_spatial_table(ob, NULL, NULL, 'e');
		}
		else if (ob->type == OB_LATTICE) {
			Lattice *lt = ob->data;
			int i1, i2;
			float *fp1, *fp2;
			int u, v, w;
			/* half but found up odd value */
			const int pntsu_half = (lt->pntsu / 2) + (lt->pntsu % 2);

			/* currently editmode isn't supported by mesh so
			 * ignore here for now too */

			/* if (lt->editlatt) lt = lt->editlatt->latt; */

			for (w = 0; w < lt->pntsw; w++) {
				for (v = 0; v < lt->pntsv; v++) {
					for (u = 0; u < pntsu_half; u++) {
						int u_inv = (lt->pntsu - 1) - u;
						float tvec[3];
						if (u == u_inv) {
							i1 = BKE_lattice_index_from_uvw(lt, u, v, w);
							fp1 = ((float *)kb->data) + i1 * 3;
							fp1[0] = -fp1[0];
							totmirr++;
						}
						else {
							i1 = BKE_lattice_index_from_uvw(lt, u, v, w);
							i2 = BKE_lattice_index_from_uvw(lt, u_inv, v, w);

							fp1 = ((float *)kb->data) + i1 * 3;
							fp2 = ((float *)kb->data) + i2 * 3;

							copy_v3_v3(tvec, fp1);
							copy_v3_v3(fp1, fp2);
							copy_v3_v3(fp2, tvec);
							fp1[0] = -fp1[0];
							fp2[0] = -fp2[0];
							totmirr++;
						}
					}
				}
			}
		}

		MEM_freeN(tag_elem);
	}
	
	*r_totmirr = totmirr;
	*r_totfail = totfail;

	DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
	WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);

	return 1;
}
Ejemplo n.º 25
0
static bool ED_object_shape_key_remove(Main *bmain, Object *ob)
{
    KeyBlock *kb, *rkb;
    Key *key;

    key = BKE_key_from_object(ob);
    if (key == NULL)
        return false;

    kb = BLI_findlink(&key->block, ob->shapenr - 1);

    if (kb) {
        for (rkb = key->block.first; rkb; rkb = rkb->next)
            if (rkb->relative == ob->shapenr - 1)
                rkb->relative = 0;

        BLI_remlink(&key->block, kb);
        key->totkey--;
        if (key->refkey == kb) {
            key->refkey = key->block.first;

            if (key->refkey) {
                /* apply new basis key on original data */
                switch (ob->type) {
                case OB_MESH:
                    BKE_key_convert_to_mesh(key->refkey, ob->data);
                    break;
                case OB_CURVE:
                case OB_SURF:
                    BKE_key_convert_to_curve(key->refkey, ob->data, BKE_curve_nurbs_get(ob->data));
                    break;
                case OB_LATTICE:
                    BKE_key_convert_to_lattice(key->refkey, ob->data);
                    break;
                }
            }
        }

        if (kb->data) MEM_freeN(kb->data);
        MEM_freeN(kb);

        if (ob->shapenr > 1) {
            ob->shapenr--;
        }
    }

    if (key->totkey == 0) {
        switch (GS(key->from->name)) {
        case ID_ME:
            ((Mesh *)key->from)->key    = NULL;
            break;
        case ID_CU:
            ((Curve *)key->from)->key   = NULL;
            break;
        case ID_LT:
            ((Lattice *)key->from)->key = NULL;
            break;
        }

        BKE_libblock_free_us(bmain, key);
    }

    return true;
}
Ejemplo n.º 26
0
static int sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoNode *unode)
{
	Scene *scene = CTX_data_scene(C);
	Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
	Object *ob = CTX_data_active_object(C);
	SculptSession *ss = ob->sculpt;
	MVert *mvert;
	int *index, i, j;
	
	if (unode->maxvert) {
		/* regular mesh restore */

		if (ss->kb && strcmp(ss->kb->name, unode->shapeName)) {
			/* shape key has been changed before calling undo operator */

			Key *key = BKE_key_from_object(ob);
			KeyBlock *kb = key ? BKE_keyblock_find_name(key, unode->shapeName) : NULL;

			if (kb) {
				ob->shapenr = BLI_findindex(&key->block, kb) + 1;

				sculpt_update_mesh_elements(scene, sd, ob, 0, FALSE);
				WM_event_add_notifier(C, NC_OBJECT | ND_DATA, ob);
			}
			else {
				/* key has been removed -- skip this undo node */
				return 0;
			}
		}

		index = unode->index;
		mvert = ss->mvert;

		if (ss->kb) {
			float (*vertCos)[3];
			vertCos = BKE_key_convert_to_vertcos(ob, ss->kb);

			for (i = 0; i < unode->totvert; i++) {
				if (ss->modifiers_active) {
					sculpt_undo_restore_deformed(ss, unode, i, index[i], vertCos[index[i]]);
				}
				else {
					if (unode->orig_co) swap_v3_v3(vertCos[index[i]], unode->orig_co[i]);
					else swap_v3_v3(vertCos[index[i]], unode->co[i]);
				}
			}

			/* propagate new coords to keyblock */
			sculpt_vertcos_to_key(ob, ss->kb, vertCos);

			/* pbvh uses it's own mvert array, so coords should be */
			/* propagated to pbvh here */
			BKE_pbvh_apply_vertCos(ss->pbvh, vertCos);

			MEM_freeN(vertCos);
		}
		else {
			for (i = 0; i < unode->totvert; i++) {
				if (ss->modifiers_active) {
					sculpt_undo_restore_deformed(ss, unode, i, index[i], mvert[index[i]].co);
				}
				else {
					if (unode->orig_co) swap_v3_v3(mvert[index[i]].co, unode->orig_co[i]);
					else swap_v3_v3(mvert[index[i]].co, unode->co[i]);
				}
				mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE;
			}
		}
	}
	else if (unode->maxgrid && dm->getGridData) {
		/* multires restore */
		CCGElem **grids, *grid;
		CCGKey key;
		float (*co)[3];
		int gridsize;

		grids = dm->getGridData(dm);
		gridsize = dm->getGridSize(dm);
		dm->getGridKey(dm, &key);

		co = unode->co;
		for (j = 0; j < unode->totgrid; j++) {
			grid = grids[unode->grids[j]];

			for (i = 0; i < gridsize * gridsize; i++, co++)
				swap_v3_v3(CCG_elem_offset_co(&key, grid, i), co[0]);
		}
	}

	return 1;
}
Ejemplo n.º 27
0
void BKE_object_handle_data_update(EvaluationContext *eval_ctx,
                                   Scene *scene,
                                   Object *ob)
{
	ID *data_id = (ID *)ob->data;
	AnimData *adt = BKE_animdata_from_id(data_id);
	Key *key;
	float ctime = BKE_scene_frame_get(scene);

	if (G.debug & G_DEBUG_DEPSGRAPH)
		printf("recalcdata %s\n", ob->id.name + 2);

	/* TODO(sergey): Only used by legacy depsgraph. */
	if (adt) {
		/* evaluate drivers - datalevel */
		/* XXX: for mesh types, should we push this to derivedmesh instead? */
		BKE_animsys_evaluate_animdata(scene, data_id, adt, ctime, ADT_RECALC_DRIVERS);
	}

	/* TODO(sergey): Only used by legacy depsgraph. */
	key = BKE_key_from_object(ob);
	if (key && key->block.first) {
		if (!(ob->shapeflag & OB_SHAPE_LOCK))
			BKE_animsys_evaluate_animdata(scene, &key->id, key->adt, ctime, ADT_RECALC_DRIVERS);
	}

	/* includes all keys and modifiers */
	switch (ob->type) {
		case OB_MESH:
		{
			BMEditMesh *em = (ob == scene->obedit) ? BKE_editmesh_from_object(ob) : NULL;
			uint64_t data_mask = scene->customdata_mask | CD_MASK_BAREMESH;
#ifdef WITH_FREESTYLE
			/* make sure Freestyle edge/face marks appear in DM for render (see T40315) */
			if (eval_ctx->mode != DAG_EVAL_VIEWPORT) {
				data_mask |= CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE;
			}
#endif
			if (em) {
				makeDerivedMesh(scene, ob, em,  data_mask, false); /* was CD_MASK_BAREMESH */
			}
			else {
				makeDerivedMesh(scene, ob, NULL, data_mask, false);
			}
			break;
		}
		case OB_ARMATURE:
			if (ob->id.lib && ob->proxy_from) {
				if (BKE_pose_copy_result(ob->pose, ob->proxy_from->pose) == false) {
					printf("Proxy copy error, lib Object: %s proxy Object: %s\n",
					       ob->id.name + 2, ob->proxy_from->id.name + 2);
				}
			}
			else {
				BKE_pose_where_is(scene, ob);
			}
			break;

		case OB_MBALL:
			BKE_displist_make_mball(eval_ctx, scene, ob);
			break;

		case OB_CURVE:
		case OB_SURF:
		case OB_FONT:
			BKE_displist_make_curveTypes(scene, ob, 0);
			break;

		case OB_LATTICE:
			BKE_lattice_modifiers_calc(scene, ob);
			break;

		case OB_EMPTY:
			if (ob->empty_drawtype == OB_EMPTY_IMAGE && ob->data)
				if (BKE_image_is_animated(ob->data))
					BKE_image_user_check_frame_calc(ob->iuser, (int)ctime, 0);
			break;
	}

	/* related materials */
	/* XXX: without depsgraph tagging, this will always need to be run, which will be slow!
	 * However, not doing anything (or trying to hack around this lack) is not an option
	 * anymore, especially due to Cycles [#31834]
	 */
	if (ob->totcol) {
		int a;
		if (ob->totcol != 0) {
			BLI_mutex_lock(&material_lock);
			for (a = 1; a <= ob->totcol; a++) {
				Material *ma = give_current_material(ob, a);
				if (ma) {
					/* recursively update drivers for this material */
					material_drivers_update(scene, ma, ctime);
				}
			}
			BLI_mutex_unlock(&material_lock);
		}
	}
	else if (ob->type == OB_LAMP)
		lamp_drivers_update(scene, ob->data, ctime);

	/* particles */
	if (ob != scene->obedit && ob->particlesystem.first) {
		ParticleSystem *tpsys, *psys;
		DerivedMesh *dm;
		ob->transflag &= ~OB_DUPLIPARTS;
		psys = ob->particlesystem.first;
		while (psys) {
			/* ensure this update always happens even if psys is disabled */
			if (psys->recalc & PSYS_RECALC_TYPE) {
				psys_changed_type(ob, psys);
			}

			if (psys_check_enabled(ob, psys)) {
				/* check use of dupli objects here */
				if (psys->part && (psys->part->draw_as == PART_DRAW_REND || eval_ctx->mode == DAG_EVAL_RENDER) &&
				    ((psys->part->ren_as == PART_DRAW_OB && psys->part->dup_ob) ||
				     (psys->part->ren_as == PART_DRAW_GR && psys->part->dup_group)))
				{
					ob->transflag |= OB_DUPLIPARTS;
				}

				particle_system_update(scene, ob, psys);
				psys = psys->next;
			}
			else if (psys->flag & PSYS_DELETE) {
				tpsys = psys->next;
				BLI_remlink(&ob->particlesystem, psys);
				psys_free(ob, psys);
				psys = tpsys;
			}
			else
				psys = psys->next;
		}

		if (eval_ctx->mode == DAG_EVAL_RENDER && ob->transflag & OB_DUPLIPARTS) {
			/* this is to make sure we get render level duplis in groups:
			 * the derivedmesh must be created before init_render_mesh,
			 * since object_duplilist does dupliparticles before that */
			CustomDataMask data_mask = CD_MASK_BAREMESH | CD_MASK_MFACE | CD_MASK_MTFACE | CD_MASK_MCOL;
			dm = mesh_create_derived_render(scene, ob, data_mask);
			dm->release(dm);

			for (psys = ob->particlesystem.first; psys; psys = psys->next)
				psys_get_modifier(ob, psys)->flag &= ~eParticleSystemFlag_psys_updated;
		}
	}

	/* quick cache removed */
}