static int knifeproject_exec(bContext *C, wmOperator *op)
{
	ARegion *ar = CTX_wm_region(C);
	Scene *scene = CTX_data_scene(C);
	Object *obedit = CTX_data_edit_object(C);
	BMEditMesh *em = BKE_editmesh_from_object(obedit);
	const bool cut_through = RNA_boolean_get(op->ptr, "cut_through");

	LinkNode *polys = NULL;

	CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
	{
		if (ob != obedit) {
			polys = knifeproject_poly_from_object(ar, scene, ob, polys);
		}
	}
	CTX_DATA_END;

	if (polys) {
		EDBM_mesh_knife(C, polys, true, cut_through);

		/* select only tagged faces */
		BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);

		/* not essential, but switch out of vertex mode since the
		 * selected regions wont be nicely isolated after flushing.
		 * note: call after de-select to avoid selection flushing */
		EDBM_selectmode_disable(scene, em, SCE_SELECT_VERTEX, SCE_SELECT_EDGE);

		BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, false, BM_ELEM_TAG);

		BM_mesh_select_mode_flush(em->bm);

		BLI_linklist_freeN(polys);

		return OPERATOR_FINISHED;
	}
	else {
		BKE_report(op->reports, RPT_ERROR, "No other selected objects found to use for projection");
		return OPERATOR_CANCELLED;
	}
}
Ejemplo n.º 2
0
void ED_object_enter_editmode(bContext *C, int flag)
{
	Scene *scene= CTX_data_scene(C);
	Base *base= NULL;
	Object *ob;
	ScrArea *sa= CTX_wm_area(C);
	View3D *v3d= NULL;
	int ok= 0;
	
	if (scene->id.lib) return;
	
	if (sa && sa->spacetype==SPACE_VIEW3D)
		v3d= sa->spacedata.first;
	
	if ((flag & EM_IGNORE_LAYER)==0) {
		base= CTX_data_active_base(C); /* active layer checked here for view3d */

		if (base==NULL) return;
		else if (v3d && (base->lay & v3d->lay)==0) return;
		else if (!v3d && (base->lay & scene->lay)==0) return;
	}
	else {
		base= scene->basact;
	}

	if (ELEM3(NULL, base, base->object, base->object->data)) return;

	ob = base->object;
	
	if (object_data_is_libdata(ob)) {
		error_libdata();
		return;
	}
	
	if (flag & EM_WAITCURSOR) waitcursor(1);

	ob->restore_mode = ob->mode;

	/* note, when switching scenes the object can have editmode data but
	 * not be scene->obedit: bug 22954, this avoids calling self eternally */
	if ((ob->restore_mode & OB_MODE_EDIT)==0)
		ED_object_toggle_modes(C, ob->mode);

	ob->mode= OB_MODE_EDIT;
	
	if (ob->type==OB_MESH) {
		BMEditMesh *em;
		ok= 1;
		scene->obedit = ob;  /* context sees this */

		EDBM_mesh_make(CTX_data_tool_settings(C), scene, ob);

		em = BMEdit_FromObject(ob);
		if (LIKELY(em)) {
			/* order doesn't matter */
			EDBM_mesh_normals_update(em);
			BMEdit_RecalcTessellation(em);
			
			BM_mesh_select_mode_flush(em->bm);
		}

		WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_MESH, scene);
	}
	else if (ob->type==OB_ARMATURE) {
		bArmature *arm= base->object->data;
		if (!arm) return;
		/*
		 * The function object_data_is_libdata make a problem here, the
		 * check for ob->proxy return 0 and let blender enter to edit mode
		 * this causes a crash when you try leave the edit mode.
		 * The problem is that i can't remove the ob->proxy check from
		 * object_data_is_libdata that prevent the bugfix #6614, so
		 * i add this little hack here.
		 */
		if (arm->id.lib) {
			error_libdata();
			return;
		}
		ok=1;
		scene->obedit= ob;
		ED_armature_to_edit(ob);
		/* to ensure all goes in restposition and without striding */
		DAG_id_tag_update(&ob->id, OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME); // XXX: should this be OB_RECALC_DATA?

		WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_ARMATURE, scene);
	}
	else if (ob->type==OB_FONT) {
		scene->obedit= ob; // XXX for context
		ok= 1;
		make_editText(ob);

		WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_TEXT, scene);
	}
	else if (ob->type==OB_MBALL) {
		scene->obedit= ob; // XXX for context
		ok= 1;
		make_editMball(ob);

		WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_MBALL, scene);
	}
	else if (ob->type==OB_LATTICE) {
		scene->obedit= ob; // XXX for context
		ok= 1;
		make_editLatt(ob);
		
		WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_LATTICE, scene);
	}
	else if (ob->type==OB_SURF || ob->type==OB_CURVE) {
		ok= 1;
		scene->obedit= ob; // XXX for context
		make_editNurb(ob);
		
		WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_CURVE, scene);
	}
	
	if (ok) {
		DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
	}
	else {
		scene->obedit= NULL; // XXX for context
		ob->mode &= ~OB_MODE_EDIT;
		WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, scene);
	}
	
	if (flag & EM_DO_UNDO) ED_undo_push(C, "Enter Editmode");
	if (flag & EM_WAITCURSOR) waitcursor(0);
}