Example #1
0
int id_unlink(ID *id, int test)
{
    Main *mainlib = G.main;
    ListBase *lb;

    switch (GS(id->name)) {
    case ID_TXT:
        if (test) return 1;
        BKE_text_unlink(mainlib, (Text *)id);
        break;
    case ID_GR:
        if (test) return 1;
        BKE_group_unlink((Group *)id);
        break;
    case ID_OB:
        if (test) return 1;
        BKE_object_unlink((Object *)id);
        break;
    }

    if (id->us == 0) {
        if (test) return 1;

        lb = which_libbase(mainlib, GS(id->name));
        BKE_libblock_free(lb, id);

        return 1;
    }

    return 0;
}
Example #2
0
bool id_unlink(ID *id, int test)
{
	Main *mainlib = G.main;
	short type = GS(id->name);

	switch (type) {
		case ID_TXT:
			if (test) return true;
			BKE_text_unlink(mainlib, (Text *)id);
			break;
		case ID_GR:
			if (test) return true;
			BKE_group_unlink((Group *)id);
			break;
		case ID_OB:
			if (test) return true;
			BKE_object_unlink((Object *)id);
			break;
	}

	if (id->us == 0) {
		if (test) return true;

		BKE_libblock_free(mainlib, id);

		return true;
	}

	return false;
}
Example #3
0
BL_ArmatureObject::~BL_ArmatureObject()
{
	BL_ArmatureConstraint* constraint;
	while ((constraint = m_controlledConstraints.Remove()) != NULL) {
		delete constraint;
	}
	BL_ArmatureChannel* channel;
	while ((channel = static_cast<BL_ArmatureChannel*>(m_poseChannels.Remove())) != NULL) {
		delete channel;
	}

	if (m_objArma) {
		BKE_libblock_free(G.main, m_objArma->data);
		BKE_libblock_free(G.main, m_objArma);
	}
}
Example #4
0
bSound *sound_new_limiter(struct Main *bmain, bSound *source, float start, float end)
{
	bSound *sound = NULL;

	char name[MAX_ID_NAME + 5];
	strcpy(name, "lim_");
	strcpy(name + 4, source->id.name);

	sound = BKE_libblock_alloc(bmain, ID_SO, name);

	sound->child_sound = source;
	sound->start = start;
	sound->end = end;
	sound->type = SOUND_TYPE_LIMITER;

	sound_load(bmain, sound);

	if (!sound->playback_handle)
	{
		BKE_libblock_free(bmain, sound);
		sound = NULL;
	}

	return sound;
}
Example #5
0
bSound *sound_new_file(struct Main *bmain, const char *filename)
{
	bSound *sound = NULL;

	char str[FILE_MAX];
	char *path;

	size_t len;

	BLI_strncpy(str, filename, sizeof(str));

	path = /*bmain ? bmain->name :*/ G.main->name;

	BLI_path_abs(str, path);

	len = strlen(filename);
	while (len > 0 && filename[len - 1] != '/' && filename[len - 1] != '\\')
		len--;

	sound = BKE_libblock_alloc(bmain, ID_SO, filename + len);
	BLI_strncpy(sound->name, filename, FILE_MAX);
	/* sound->type = SOUND_TYPE_FILE; */ /* XXX unused currently */

	sound_load(bmain, sound);

	if (!sound->playback_handle) {
		BKE_libblock_free(bmain, sound);
		sound = NULL;
	}

	return sound;
}
Example #6
0
void BKE_sound_delete(struct Main *bmain, bSound *sound)
{
	if (sound) {
		BKE_sound_free(sound);

		BKE_libblock_free(bmain, sound);
	}
}
Example #7
0
void sound_delete(struct Main *bmain, struct bSound *sound)
{
	if (sound) {
		BKE_sound_free(sound);

		BKE_libblock_free(&bmain->sound, sound);
	}
}
Example #8
0
/* memfile is the undo buffer */
int BKE_read_file_from_memfile(bContext *C, MemFile *memfile, ReportList *reports)
{
	BlendFileData *bfd;

	bfd = BLO_read_from_memfile(CTX_data_main(C), G.main->name, memfile, reports);
	if (bfd) {
		/* remove the unused screens and wm */
		while (bfd->main->wm.first)
			BKE_libblock_free(&bfd->main->wm, bfd->main->wm.first);
		while (bfd->main->screen.first)
			BKE_libblock_free(&bfd->main->screen, bfd->main->screen.first);
		
		setup_app_data(C, bfd, "<memory1>");
	}
	else
		BKE_reports_prepend(reports, "Loading failed: ");

	return (bfd ? 1 : 0);
}
Example #9
0
BlenderStrokeRenderer::~BlenderStrokeRenderer()
{
	if (0 != _textureManager) {
		delete _textureManager;
		_textureManager = NULL;
	}

	// The freestyle_scene object is not released here.  Instead,
	// the scene is released in free_all_freestyle_renders() in
	// source/blender/render/intern/source/pipeline.c, after the
	// compositor has finished.

	// release objects and data blocks
	for (Base *b = (Base *)freestyle_scene->base.first; b; b = b->next) {
		Object *ob = b->object;
		void *data = ob->data;
		char *name = ob->id.name;
#if 0
		if (G.debug & G_DEBUG_FREESTYLE) {
			cout << "removing " << name[0] << name[1] << ":" << (name+2) << endl;
		}
#endif
		switch (ob->type) {
		case OB_MESH:
			BKE_libblock_free(&freestyle_bmain->object, ob);
			BKE_libblock_free(&freestyle_bmain->mesh, data);
			break;
		case OB_CAMERA:
			BKE_libblock_free(&freestyle_bmain->object, ob);
			BKE_libblock_free(&freestyle_bmain->camera, data);
			freestyle_scene->camera = NULL;
			break;
		default:
			cerr << "Warning: unexpected object in the scene: " << name[0] << name[1] << ":" << (name + 2) << endl;
		}
	}
	BLI_freelistN(&freestyle_scene->base);

	// release material
	BKE_libblock_free(&freestyle_bmain->mat, material);
}
Example #10
0
/* this is event from ghost, or exit-blender op */
void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
{
    wmWindow *tmpwin;
    bool do_exit = false;

    /* first check if we have to quit (there are non-temp remaining windows) */
    for (tmpwin = wm->windows.first; tmpwin; tmpwin = tmpwin->next) {
        if (tmpwin == win)
            continue;
        if (tmpwin->screen->temp == 0)
            break;
    }

    if (tmpwin == NULL)
        do_exit = 1;

    if ((U.uiflag & USER_QUIT_PROMPT) && !wm->file_saved) {
        if (do_exit) {
            if (!GHOST_confirmQuit(win->ghostwin))
                return;
        }
    }

    /* let WM_exit do all freeing, for correct quit.blend save */
    if (do_exit) {
        WM_exit(C);
    }
    else {
        bScreen *screen = win->screen;

        BLI_remlink(&wm->windows, win);

        wm_draw_window_clear(win);

        CTX_wm_window_set(C, win);  /* needed by handlers */
        WM_event_remove_handlers(C, &win->handlers);
        WM_event_remove_handlers(C, &win->modalhandlers);

        /* for regular use this will _never_ be NULL,
         * however we may be freeing an improperly initialized window. */
        if (win->screen) {
            ED_screen_exit(C, win, win->screen);
        }

        wm_window_free(C, wm, win);

        /* if temp screen, delete it after window free (it stops jobs that can access it) */
        if (screen && screen->temp) {
            Main *bmain = CTX_data_main(C);
            BKE_libblock_free(bmain, screen);
        }
    }
}
Example #11
0
BL_Action::~BL_Action()
{
	if (m_blendpose)
		BKE_pose_free(m_blendpose);
	if (m_blendinpose)
		BKE_pose_free(m_blendinpose);
	ClearControllerList();

	if (m_tmpaction) {
		BKE_libblock_free(G.main, m_tmpaction);
		m_tmpaction = NULL;
	}
}
Example #12
0
void BKE_libblock_delete(Main *bmain, void *idv)
{
	ListBase *lbarray[MAX_LIBARRAY];
	int base_count, i;

	base_count = set_listbasepointers(bmain, lbarray);
	BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);

	/* First tag all datablocks directly from target lib.
	 * Note that we go forward here, since we want to check dependencies before users (e.g. meshes before objects).
	 * Avoids to have to loop twice. */
	for (i = 0; i < base_count; i++) {
		ListBase *lb = lbarray[i];
		ID *id;

		for (id = lb->first; id; id = id->next) {
			/* Note: in case we delete a library, we also delete all its datablocks! */
			if ((id == (ID *)idv) || (id->lib == (Library *)idv) || (id->tag & LIB_TAG_DOIT)) {
				id->tag |= LIB_TAG_DOIT;
				/* Will tag 'never NULL' users of this ID too.
				 * Note that we cannot use BKE_libblock_unlink() here, since it would ignore indirect (and proxy!)
				 * links, this can lead to nasty crashing here in second, actual deleting loop.
				 * Also, this will also flag users of deleted data that cannot be unlinked
				 * (object using deleted obdata, etc.), so that they also get deleted. */
				BKE_libblock_remap(bmain, id, NULL, ID_REMAP_FLAG_NEVER_NULL_USAGE | ID_REMAP_FORCE_NEVER_NULL_USAGE);
			}
		}
	}

	/* In usual reversed order, such that all usage of a given ID, even 'never NULL' ones, have been already cleared
	 * when we reach it (e.g. Objects being processed before meshes, they'll have already released their 'reference'
	 * over meshes when we come to freeing obdata). */
	for (i = base_count; i--; ) {
		ListBase *lb = lbarray[i];
		ID *id, *id_next;

		for (id = lb->first; id; id = id_next) {
			id_next = id->next;
			if (id->tag & LIB_TAG_DOIT) {
				if (id->us != 0) {
#ifdef DEBUG_PRINT
					printf("%s: deleting %s (%d)\n", __func__, id->name, id->us);
#endif
					BLI_assert(id->us == 0);
				}
				BKE_libblock_free(bmain, id);
			}
		}
	}
}
Example #13
0
/* memfile is the undo buffer */
bool BKE_blendfile_read_from_memfile(
        bContext *C, struct MemFile *memfile,
        ReportList *reports, int skip_flags)
{
	Main *bmain = CTX_data_main(C);
	BlendFileData *bfd;

	bfd = BLO_read_from_memfile(bmain, BKE_main_blendfile_path(bmain), memfile, reports, skip_flags);
	if (bfd) {
		/* remove the unused screens and wm */
		while (bfd->main->wm.first)
			BKE_libblock_free(bfd->main, bfd->main->wm.first);
		while (bfd->main->screen.first)
			BKE_libblock_free(bfd->main, bfd->main->screen.first);

		setup_app_data(C, bfd, "<memory1>", reports);
	}
	else {
		BKE_reports_prepend(reports, "Loading failed: ");
	}

	return (bfd != NULL);
}
Example #14
0
/* this is event from ghost, or exit-blender op */
void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
{
	wmWindow *tmpwin;
	bScreen *screen = win->screen;
	
	/* first check if we have any non-temp remaining windows */
	if ((U.uiflag & USER_QUIT_PROMPT) && !wm->file_saved) {
		if (wm->windows.first) {
			for (tmpwin = wm->windows.first; tmpwin; tmpwin = tmpwin->next) {
				if (tmpwin == win)
					continue;
				if (tmpwin->screen->temp == 0)
					break;
			}
			if (tmpwin == NULL) {
				if (!GHOST_confirmQuit(win->ghostwin))
					return;
			}
		}
	}

	BLI_remlink(&wm->windows, win);
	
	wm_draw_window_clear(win);
	CTX_wm_window_set(C, win);  /* needed by handlers */
	WM_event_remove_handlers(C, &win->handlers);
	WM_event_remove_handlers(C, &win->modalhandlers);
	ED_screen_exit(C, win, win->screen); 
	
	wm_window_free(C, wm, win);
	
	/* if temp screen, delete it after window free (it stops jobs that can access it) */
	if (screen->temp) {
		Main *bmain = CTX_data_main(C);
		BKE_libblock_free(&bmain->screen, screen);
	}
	
	/* check remaining windows */
	if (wm->windows.first) {
		for (win = wm->windows.first; win; win = win->next)
			if (win->screen->temp == 0)
				break;
		/* in this case we close all */
		if (win == NULL)
			WM_exit(C);
	}
	else
		WM_exit(C);
}
Example #15
0
void BKE_libblock_free_us(ListBase *lb, void *idv)      /* test users */
{
    ID *id = idv;

    id->us--;

    if (id->us < 0) {
        if (id->lib) printf("ERROR block %s %s users %d\n", id->lib->name, id->name, id->us);
        else printf("ERROR block %s users %d\n", id->name, id->us);
    }
    if (id->us == 0) {
        if (GS(id->name) == ID_OB) BKE_object_unlink((Object *)id);

        BKE_libblock_free(lb, id);
    }
}
Example #16
0
Object *DocumentImporter::create_lamp_object(COLLADAFW::InstanceLight *lamp, Scene *sce)
{
	const COLLADAFW::UniqueId& lamp_uid = lamp->getInstanciatedObjectId();
	if (uid_lamp_map.find(lamp_uid) == uid_lamp_map.end()) {
		fprintf(stderr, "Couldn't find lamp by UID.\n");
		return NULL;
	}

	Object *ob = bc_add_object(sce, OB_LAMP, NULL);
	Lamp *la = uid_lamp_map[lamp_uid];
	Lamp *old_lamp = (Lamp *)ob->data;
	ob->data = la;
	id_us_min(&old_lamp->id);
	if (old_lamp->id.us == 0)
		BKE_libblock_free(G.main, old_lamp);
	return ob;
}
Example #17
0
Object *DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera, Scene *sce)
{
	const COLLADAFW::UniqueId& cam_uid = camera->getInstanciatedObjectId();
	if (uid_camera_map.find(cam_uid) == uid_camera_map.end()) {
		// fprintf(stderr, "Couldn't find camera by UID.\n");
		return NULL;
	}

	Object *ob = bc_add_object(sce, OB_CAMERA, NULL);
	Camera *cam = uid_camera_map[cam_uid];
	Camera *old_cam = (Camera *)ob->data;
	ob->data = cam;
	id_us_min(&old_cam->id);
	if (old_cam->id.us == 0)
		BKE_libblock_free(G.main, old_cam);
	return ob;
}
Example #18
0
void free_main(Main *mainvar)
{
    /* also call when reading a file, erase all, etc */
    ListBase *lbarray[MAX_LIBARRAY];
    int a;

    a = set_listbasepointers(mainvar, lbarray);
    while (a--) {
        ListBase *lb = lbarray[a];
        ID *id;

        while ( (id = lb->first) ) {
            BKE_libblock_free(lb, id);
        }
    }

    MEM_freeN(mainvar);
}
Example #19
0
void BKE_scene_unlink(Main *bmain, Scene *sce, Scene *newsce)
{
	Scene *sce1;
	bScreen *sc;

	/* check all sets */
	for (sce1 = bmain->scene.first; sce1; sce1 = sce1->id.next)
		if (sce1->set == sce)
			sce1->set = NULL;
	
	/* check render layer nodes in other scenes */
	clear_scene_in_nodes(bmain, sce);
	
	/* al screens */
	for (sc = bmain->screen.first; sc; sc = sc->id.next)
		if (sc->scene == sce)
			sc->scene = newsce;

	BKE_libblock_free(&bmain->scene, sce);
}
Example #20
0
void BKE_libblock_free_us(Main *bmain, void *idv)      /* test users */
{
	ID *id = idv;
	
	id_us_min(id);

	/* XXX This is a temp (2.77) hack so that we keep same behavior as in 2.76 regarding groups when deleting an object.
	 *     Since only 'user_one' usage of objects is groups, and only 'real user' usage of objects is scenes,
	 *     removing that 'user_one' tag when there is no more real (scene) users of an object ensures it gets
	 *     fully unlinked.
	 *     Otherwise, there is no real way to get rid of an object anymore - better handling of this is TODO.
	 */
	if ((GS(id->name) == ID_OB) && (id->us == 1)) {
		id_us_clear_real(id);
	}

	if (id->us == 0) {
		BKE_libblock_unlink(bmain, id, false, false);
		
		BKE_libblock_free(bmain, id);
	}
}
Example #21
0
bSound *sound_new_buffer(struct Main *bmain, bSound *source)
{
	bSound *sound = NULL;

	char name[MAX_ID_NAME + 5];
	strcpy(name, "buf_");
	strcpy(name + 4, source->id.name);

	sound = BKE_libblock_alloc(bmain, ID_SO, name);

	sound->child_sound = source;
	sound->type = SOUND_TYPE_BUFFER;

	sound_load(bmain, sound);

	if (!sound->playback_handle)
	{
		BKE_libblock_free(bmain, sound);
		sound = NULL;
	}

	return sound;
}
Example #22
0
static int bake(
        Render *re, Main *bmain, Scene *scene, Object *ob_low, ListBase *selected_objects, ReportList *reports,
        const ScenePassType pass_type, const int margin,
        const BakeSaveMode save_mode, const bool is_clear, const bool is_split_materials,
        const bool is_automatic_name, const bool is_selected_to_active, const bool is_cage,
        const float cage_extrusion, const int normal_space, const BakeNormalSwizzle normal_swizzle[],
        const char *custom_cage, const char *filepath, const int width, const int height,
        const char *identifier, ScrArea *sa, const char *uv_layer)
{
	int op_result = OPERATOR_CANCELLED;
	bool ok = false;

	Object *ob_cage = NULL;

	BakeHighPolyData *highpoly = NULL;
	int tot_highpoly = 0;

	char restrict_flag_low = ob_low->restrictflag;
	char restrict_flag_cage = 0;

	Mesh *me_low = NULL;
	Mesh *me_cage = NULL;

	float *result = NULL;

	BakePixel *pixel_array_low = NULL;
	BakePixel *pixel_array_high = NULL;

	const bool is_save_internal = (save_mode == R_BAKE_SAVE_INTERNAL);
	const bool is_noncolor = is_noncolor_pass(pass_type);
	const int depth = RE_pass_depth(pass_type);

	BakeImages bake_images = {NULL};

	size_t num_pixels;
	int tot_materials;

	RE_bake_engine_set_engine_parameters(re, bmain, scene);

	if (!RE_bake_has_engine(re)) {
		BKE_report(reports, RPT_ERROR, "Current render engine does not support baking");
		goto cleanup;
	}

	tot_materials = ob_low->totcol;

	if (uv_layer && uv_layer[0] != '\0') {
		Mesh *me = (Mesh *)ob_low->data;
		if (CustomData_get_named_layer(&me->ldata, CD_MLOOPUV, uv_layer) == -1) {
			BKE_reportf(reports, RPT_ERROR,
			            "No UV layer named \"%s\" found in the object \"%s\"", uv_layer, ob_low->id.name + 2);
			goto cleanup;
		}
	}

	if (tot_materials == 0) {
		if (is_save_internal) {
			BKE_report(reports, RPT_ERROR,
			           "No active image found, add a material or bake to an external file");

			goto cleanup;
		}
		else if (is_split_materials) {
			BKE_report(reports, RPT_ERROR,
			           "No active image found, add a material or bake without the Split Materials option");

			goto cleanup;
		}
		else {
			/* baking externally without splitting materials */
			tot_materials = 1;
		}
	}

	/* we overallocate in case there is more materials than images */
	bake_images.data = MEM_mallocN(sizeof(BakeImage) * tot_materials, "bake images dimensions (width, height, offset)");
	bake_images.lookup = MEM_mallocN(sizeof(int) * tot_materials, "bake images lookup (from material to BakeImage)");

	build_image_lookup(bmain, ob_low, &bake_images);

	if (is_save_internal) {
		num_pixels = initialize_internal_images(&bake_images, reports);

		if (num_pixels == 0) {
			goto cleanup;
		}
	}
	else {
		/* when saving extenally always use the size specified in the UI */

		num_pixels = (size_t)width * (size_t)height * bake_images.size;

		for (int i = 0; i < bake_images.size; i++) {
			bake_images.data[i].width = width;
			bake_images.data[i].height = height;
			bake_images.data[i].offset = (is_split_materials ? num_pixels : 0);
			bake_images.data[i].image = NULL;
		}

		if (!is_split_materials) {
			/* saving a single image */
			for (int i = 0; i < tot_materials; i++) {
				bake_images.lookup[i] = 0;
			}
		}
	}

	if (is_selected_to_active) {
		CollectionPointerLink *link;
		tot_highpoly = 0;

		for (link = selected_objects->first; link; link = link->next) {
			Object *ob_iter = link->ptr.data;

			if (ob_iter == ob_low)
				continue;

			tot_highpoly ++;
		}

		if (is_cage && custom_cage[0] != '\0') {
			ob_cage = BLI_findstring(&bmain->object, custom_cage, offsetof(ID, name) + 2);

			if (ob_cage == NULL || ob_cage->type != OB_MESH) {
				BKE_report(reports, RPT_ERROR, "No valid cage object");
				goto cleanup;
			}
			else {
				restrict_flag_cage = ob_cage->restrictflag;
				ob_cage->restrictflag |= OB_RESTRICT_RENDER;
			}
		}
	}

	pixel_array_low = MEM_mallocN(sizeof(BakePixel) * num_pixels, "bake pixels low poly");
	pixel_array_high = MEM_mallocN(sizeof(BakePixel) * num_pixels, "bake pixels high poly");
	result = MEM_callocN(sizeof(float) * depth * num_pixels, "bake return pixels");

	/* get the mesh as it arrives in the renderer */
	me_low = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 0, 0);
	BKE_mesh_split_faces(me_low);

	/* populate the pixel array with the face data */
	if ((is_selected_to_active && (ob_cage == NULL) && is_cage) == false)
		RE_bake_pixels_populate(me_low, pixel_array_low, num_pixels, &bake_images, uv_layer);
	/* else populate the pixel array with the 'cage' mesh (the smooth version of the mesh)  */

	if (is_selected_to_active) {
		CollectionPointerLink *link;
		ModifierData *md, *nmd;
		ListBase modifiers_tmp, modifiers_original;
		int i = 0;

		/* prepare cage mesh */
		if (ob_cage) {
			me_cage = BKE_mesh_new_from_object(bmain, scene, ob_cage, 1, 2, 0, 0);
			BKE_mesh_split_faces(me_cage);
			if ((me_low->totpoly != me_cage->totpoly) || (me_low->totloop != me_cage->totloop)) {
				BKE_report(reports, RPT_ERROR,
				           "Invalid cage object, the cage mesh must have the same number "
				           "of faces as the active object");
				goto cleanup;
			}
		}
		else if (is_cage) {
			modifiers_original = ob_low->modifiers;
			BLI_listbase_clear(&modifiers_tmp);

			for (md = ob_low->modifiers.first; md; md = md->next) {
				/* Edge Split cannot be applied in the cage,
				 * the cage is supposed to have interpolated normals
				 * between the faces unless the geometry is physically
				 * split. So we create a copy of the low poly mesh without
				 * the eventual edge split.*/

				if (md->type == eModifierType_EdgeSplit)
					continue;

				nmd = modifier_new(md->type);
				BLI_strncpy(nmd->name, md->name, sizeof(nmd->name));
				modifier_copyData(md, nmd);
				BLI_addtail(&modifiers_tmp, nmd);
			}

			/* temporarily replace the modifiers */
			ob_low->modifiers = modifiers_tmp;

			/* get the cage mesh as it arrives in the renderer */
			me_cage = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 0, 0);
			BKE_mesh_split_faces(me_cage);
			RE_bake_pixels_populate(me_cage, pixel_array_low, num_pixels, &bake_images, uv_layer);
		}

		highpoly = MEM_callocN(sizeof(BakeHighPolyData) * tot_highpoly, "bake high poly objects");

		/* populate highpoly array */
		for (link = selected_objects->first; link; link = link->next) {
			TriangulateModifierData *tmd;
			Object *ob_iter = link->ptr.data;

			if (ob_iter == ob_low)
				continue;

			/* initialize highpoly_data */
			highpoly[i].ob = ob_iter;
			highpoly[i].restrict_flag = ob_iter->restrictflag;

			/* triangulating so BVH returns the primitive_id that will be used for rendering */
			highpoly[i].tri_mod = ED_object_modifier_add(
			        reports, bmain, scene, highpoly[i].ob,
			        "TmpTriangulate", eModifierType_Triangulate);
			tmd = (TriangulateModifierData *)highpoly[i].tri_mod;
			tmd->quad_method = MOD_TRIANGULATE_QUAD_FIXED;
			tmd->ngon_method = MOD_TRIANGULATE_NGON_EARCLIP;

			highpoly[i].me = BKE_mesh_new_from_object(bmain, scene, highpoly[i].ob, 1, 2, 0, 0);
			highpoly[i].ob->restrictflag &= ~OB_RESTRICT_RENDER;
			BKE_mesh_split_faces(highpoly[i].me);

			/* lowpoly to highpoly transformation matrix */
			copy_m4_m4(highpoly[i].obmat, highpoly[i].ob->obmat);
			invert_m4_m4(highpoly[i].imat, highpoly[i].obmat);

			highpoly[i].is_flip_object = is_negative_m4(highpoly[i].ob->obmat);

			i++;
		}

		BLI_assert(i == tot_highpoly);

		ob_low->restrictflag |= OB_RESTRICT_RENDER;

		/* populate the pixel arrays with the corresponding face data for each high poly object */
		if (!RE_bake_pixels_populate_from_objects(
		            me_low, pixel_array_low, pixel_array_high, highpoly, tot_highpoly, num_pixels, ob_cage != NULL,
		            cage_extrusion, ob_low->obmat, (ob_cage ? ob_cage->obmat : ob_low->obmat), me_cage))
		{
			BKE_report(reports, RPT_ERROR, "Error handling selected objects");
			goto cage_cleanup;
		}

		/* the baking itself */
		for (i = 0; i < tot_highpoly; i++) {
			ok = RE_bake_engine(re, highpoly[i].ob, i, pixel_array_high,
			                    num_pixels, depth, pass_type, result);
			if (!ok) {
				BKE_reportf(reports, RPT_ERROR, "Error baking from object \"%s\"", highpoly[i].ob->id.name + 2);
				goto cage_cleanup;
			}
		}

cage_cleanup:
		/* reverting data back */
		if ((ob_cage == NULL) && is_cage) {
			ob_low->modifiers = modifiers_original;

			while ((md = BLI_pophead(&modifiers_tmp))) {
				modifier_free(md);
			}
		}

		if (!ok) {
			goto cleanup;
		}
	}
	else {
		/* make sure low poly renders */
		ob_low->restrictflag &= ~OB_RESTRICT_RENDER;

		if (RE_bake_has_engine(re)) {
			ok = RE_bake_engine(re, ob_low, 0, pixel_array_low, num_pixels, depth, pass_type, result);
		}
		else {
			BKE_report(reports, RPT_ERROR, "Current render engine does not support baking");
			goto cleanup;
		}
	}

	/* normal space conversion
	 * the normals are expected to be in world space, +X +Y +Z */
	if (ok && pass_type == SCE_PASS_NORMAL) {
		switch (normal_space) {
			case R_BAKE_SPACE_WORLD:
			{
				/* Cycles internal format */
				if ((normal_swizzle[0] == R_BAKE_POSX) &&
				    (normal_swizzle[1] == R_BAKE_POSY) &&
				    (normal_swizzle[2] == R_BAKE_POSZ))
				{
					break;
				}
				else {
					RE_bake_normal_world_to_world(pixel_array_low, num_pixels,  depth, result, normal_swizzle);
				}
				break;
			}
			case R_BAKE_SPACE_OBJECT:
			{
				RE_bake_normal_world_to_object(pixel_array_low, num_pixels, depth, result, ob_low, normal_swizzle);
				break;
			}
			case R_BAKE_SPACE_TANGENT:
			{
				if (is_selected_to_active) {
					RE_bake_normal_world_to_tangent(pixel_array_low, num_pixels, depth, result, me_low, normal_swizzle, ob_low->obmat);
				}
				else {
					/* from multiresolution */
					Mesh *me_nores = NULL;
					ModifierData *md = NULL;
					int mode;

					md = modifiers_findByType(ob_low, eModifierType_Multires);

					if (md) {
						mode = md->mode;
						md->mode &= ~eModifierMode_Render;
					}

					me_nores = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 0, 0);
					BKE_mesh_split_faces(me_nores);
					RE_bake_pixels_populate(me_nores, pixel_array_low, num_pixels, &bake_images, uv_layer);

					RE_bake_normal_world_to_tangent(pixel_array_low, num_pixels, depth, result, me_nores, normal_swizzle, ob_low->obmat);
					BKE_libblock_free(bmain, me_nores);

					if (md)
						md->mode = mode;
				}
				break;
			}
			default:
				break;
		}
	}

	if (!ok) {
		BKE_reportf(reports, RPT_ERROR, "Problem baking object \"%s\"", ob_low->id.name + 2);
		op_result = OPERATOR_CANCELLED;
	}
	else {
		/* save the results */
		for (int i = 0; i < bake_images.size; i++) {
			BakeImage *bk_image = &bake_images.data[i];

			if (is_save_internal) {
				ok = write_internal_bake_pixels(
				         bk_image->image,
				         pixel_array_low + bk_image->offset,
				         result + bk_image->offset * depth,
				         bk_image->width, bk_image->height,
				         margin, is_clear, is_noncolor);

				/* might be read by UI to set active image for display */
				bake_update_image(sa, bk_image->image);

				if (!ok) {
					BKE_reportf(reports, RPT_ERROR,
					           "Problem saving the bake map internally for object \"%s\"", ob_low->id.name + 2);
					op_result = OPERATOR_CANCELLED;
				}
				else {
					BKE_report(reports, RPT_INFO,
					           "Baking map saved to internal image, save it externally or pack it");
					op_result = OPERATOR_FINISHED;
				}
			}
			/* save externally */
			else {
				BakeData *bake = &scene->r.bake;
				char name[FILE_MAX];

				BKE_image_path_from_imtype(name, filepath, bmain->name, 0, bake->im_format.imtype, true, false, NULL);

				if (is_automatic_name) {
					BLI_path_suffix(name, FILE_MAX, ob_low->id.name + 2, "_");
					BLI_path_suffix(name, FILE_MAX, identifier, "_");
				}

				if (is_split_materials) {
					if (bk_image->image) {
						BLI_path_suffix(name, FILE_MAX, bk_image->image->id.name + 2, "_");
					}
					else {
						if (ob_low->mat[i]) {
							BLI_path_suffix(name, FILE_MAX, ob_low->mat[i]->id.name + 2, "_");
						}
						else if (me_low->mat[i]) {
							BLI_path_suffix(name, FILE_MAX, me_low->mat[i]->id.name + 2, "_");
						}
						else {
							/* if everything else fails, use the material index */
							char tmp[4];
							sprintf(tmp, "%d", i % 1000);
							BLI_path_suffix(name, FILE_MAX, tmp, "_");
						}
					}
				}

				/* save it externally */
				ok = write_external_bake_pixels(
				        name,
				        pixel_array_low + bk_image->offset,
				        result + bk_image->offset * depth,
				        bk_image->width, bk_image->height,
				        margin, &bake->im_format, is_noncolor);

				if (!ok) {
					BKE_reportf(reports, RPT_ERROR, "Problem saving baked map in \"%s\"", name);
					op_result = OPERATOR_CANCELLED;
				}
				else {
					BKE_reportf(reports, RPT_INFO, "Baking map written to \"%s\"", name);
					op_result = OPERATOR_FINISHED;
				}

				if (!is_split_materials) {
					break;
				}
			}
		}
	}

	if (is_save_internal)
		refresh_images(&bake_images);

cleanup:

	if (highpoly) {
		int i;
		for (i = 0; i < tot_highpoly; i++) {
			highpoly[i].ob->restrictflag = highpoly[i].restrict_flag;

			if (highpoly[i].tri_mod)
				ED_object_modifier_remove(reports, bmain, highpoly[i].ob, highpoly[i].tri_mod);

			if (highpoly[i].me)
				BKE_libblock_free(bmain, highpoly[i].me);
		}
		MEM_freeN(highpoly);
	}

	ob_low->restrictflag = restrict_flag_low;

	if (ob_cage)
		ob_cage->restrictflag = restrict_flag_cage;

	if (pixel_array_low)
		MEM_freeN(pixel_array_low);

	if (pixel_array_high)
		MEM_freeN(pixel_array_high);

	if (bake_images.data)
		MEM_freeN(bake_images.data);

	if (bake_images.lookup)
		MEM_freeN(bake_images.lookup);

	if (result)
		MEM_freeN(result);

	if (me_low)
		BKE_libblock_free(bmain, me_low);

	if (me_cage)
		BKE_libblock_free(bmain, me_cage);

	return op_result;
}
Example #23
0
/* returns 1 if its OK */
static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
{
	bNodeLink *link, *linkn, *tlink;
	bNode *node, *nextnode;
	bNodeTree *ngroup, *wgroup;
	ListBase anim_basepaths = {NULL, NULL};
	
	ngroup = (bNodeTree *)gnode->id;
	
	/* clear new pointers, set in copytree */
	for (node = ntree->nodes.first; node; node = node->next)
		node->new_node = NULL;
	
	/* wgroup is a temporary copy of the NodeTree we're merging in
	 * - all of wgroup's nodes are transferred across to their new home
	 * - ngroup (i.e. the source NodeTree) is left unscathed
	 * - temp copy. don't change ID usercount
	 */
	wgroup = ntreeCopyTree_ex(ngroup, FALSE);
	
	/* Add the nodes into the ntree */
	for (node = wgroup->nodes.first; node; node = nextnode) {
		nextnode = node->next;
		
		/* Remove interface nodes.
		 * This also removes remaining links to and from interface nodes.
		 */
		if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) {
			nodeFreeNode(wgroup, node);
			continue;
		}
		
		/* keep track of this node's RNA "base" path (the part of the path identifying the node) 
		 * if the old nodetree has animation data which potentially covers this node
		 */
		if (wgroup->adt) {
			PointerRNA ptr;
			char *path;
			
			RNA_pointer_create(&wgroup->id, &RNA_Node, node, &ptr);
			path = RNA_path_from_ID_to_struct(&ptr);
			
			if (path)
				BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
		}
		
		/* migrate node */
		BLI_remlink(&wgroup->nodes, node);
		BLI_addtail(&ntree->nodes, node);
		
		/* ensure unique node name in the node tree */
		nodeUniqueName(ntree, node);
		
		if (!node->parent) {
			node->locx += gnode->locx;
			node->locy += gnode->locy;
		}
		
		node->flag |= NODE_SELECT;
	}
	
	/* Add internal links to the ntree */
	for (link = wgroup->links.first; link; link = linkn) {
		linkn = link->next;
		BLI_remlink(&wgroup->links, link);
		BLI_addtail(&ntree->links, link);
	}
	
	/* and copy across the animation,
	 * note that the animation data's action can be NULL here */
	if (wgroup->adt) {
		LinkData *ld, *ldn = NULL;
		bAction *waction;
		
		/* firstly, wgroup needs to temporary dummy action that can be destroyed, as it shares copies */
		waction = wgroup->adt->action = BKE_action_copy(wgroup->adt->action);
		
		/* now perform the moving */
		BKE_animdata_separate_by_basepath(&wgroup->id, &ntree->id, &anim_basepaths);
		
		/* paths + their wrappers need to be freed */
		for (ld = anim_basepaths.first; ld; ld = ldn) {
			ldn = ld->next;
			
			MEM_freeN(ld->data);
			BLI_freelinkN(&anim_basepaths, ld);
		}
		
		/* free temp action too */
		if (waction) {
			BKE_libblock_free(&G.main->action, waction);
		}
	}
	
	/* free the group tree (takes care of user count) */
	BKE_libblock_free(&G.main->nodetree, wgroup);
	
	/* restore external links to and from the gnode */
	/* note: the nodes have been copied to intermediate wgroup first (so need to use new_node),
	 *       then transferred to ntree (new_node pointers remain valid).
	 */
	
	/* input links */
	for (link = ngroup->links.first; link; link = link->next) {
		if (link->fromnode->type == NODE_GROUP_INPUT) {
			const char *identifier = link->fromsock->identifier;
			int num_external_links = 0;
			
			/* find external links to this input */
			for (tlink = ntree->links.first; tlink; tlink = tlink->next) {
				if (tlink->tonode == gnode && STREQ(tlink->tosock->identifier, identifier)) {
					nodeAddLink(ntree, tlink->fromnode, tlink->fromsock, link->tonode->new_node, link->tosock->new_sock);
					++num_external_links;
				}
			}
			
			/* if group output is not externally linked,
			 * convert the constant input value to ensure somewhat consistent behavior */
			if (num_external_links == 0) {
				/* XXX TODO bNodeSocket *sock = node_group_find_input_socket(gnode, identifier);
				BLI_assert(sock);*/
				
				/* XXX TODO nodeSocketCopy(ntree, link->tosock->new_sock, link->tonode->new_node, ntree, sock, gnode);*/
			}
		}
	}
	
	/* output links */
	for (link = ntree->links.first; link; link = link->next) {
		if (link->fromnode == gnode) {
			const char *identifier = link->fromsock->identifier;
			int num_internal_links = 0;
			
			/* find internal links to this output */
			for (tlink = ngroup->links.first; tlink; tlink = tlink->next) {
				/* only use active output node */
				if (tlink->tonode->type == NODE_GROUP_OUTPUT && (tlink->tonode->flag & NODE_DO_OUTPUT)) {
					if (STREQ(tlink->tosock->identifier, identifier)) {
						nodeAddLink(ntree, tlink->fromnode->new_node, tlink->fromsock->new_sock, link->tonode, link->tosock);
						++num_internal_links;
					}
				}
			}
			
			/* if group output is not internally linked,
			 * convert the constant output value to ensure somewhat consistent behavior */
			if (num_internal_links == 0) {
				/* XXX TODO bNodeSocket *sock = node_group_find_output_socket(gnode, identifier);
				BLI_assert(sock);*/
				
				/* XXX TODO nodeSocketCopy(ntree, link->tosock, link->tonode, ntree, sock, gnode); */
			}
		}
	}
	
	/* delete the group instance */
	nodeFreeNode(ntree, gnode);
	
	ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
	
	return 1;
}
Example #24
0
/**
 * Update defaults in startup.blend, without having to save and embed the file.
 * This function can be emptied each time the startup.blend is updated. */
void BLO_update_defaults_startup_blend(Main *bmain)
{
	for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
		scene->r.im_format.planes = R_IMF_PLANES_RGBA;
		scene->r.im_format.compress = 15;

		for (SceneRenderLayer *srl = scene->r.layers.first; srl; srl = srl->next) {
			srl->freestyleConfig.sphere_radius = 0.1f;
			srl->pass_alpha_threshold = 0.5f;
		}

		if (scene->toolsettings) {
			ToolSettings *ts = scene->toolsettings;

			if (ts->sculpt) {
				Sculpt *sculpt = ts->sculpt;
				sculpt->paint.symmetry_flags |= PAINT_SYMM_X;
				sculpt->flags |= SCULPT_DYNTOPO_COLLAPSE;
				sculpt->detail_size = 12;
			}
			
			if (ts->gp_sculpt.brush[0].size == 0) {
				GP_BrushEdit_Settings *gset = &ts->gp_sculpt;
				GP_EditBrush_Data *brush;
				
				brush = &gset->brush[GP_EDITBRUSH_TYPE_SMOOTH];
				brush->size = 25;
				brush->strength = 0.3f;
				brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF | GP_EDITBRUSH_FLAG_SMOOTH_PRESSURE;
				
				brush = &gset->brush[GP_EDITBRUSH_TYPE_THICKNESS];
				brush->size = 25;
				brush->strength = 0.5f;
				brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF;
				
				brush = &gset->brush[GP_EDITBRUSH_TYPE_STRENGTH];
				brush->size = 25;
				brush->strength = 0.5f;
				brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF;

				brush = &gset->brush[GP_EDITBRUSH_TYPE_GRAB];
				brush->size = 50;
				brush->strength = 0.3f;
				brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF;
				
				brush = &gset->brush[GP_EDITBRUSH_TYPE_PUSH];
				brush->size = 25;
				brush->strength = 0.3f;
				brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF;
				
				brush = &gset->brush[GP_EDITBRUSH_TYPE_TWIST];
				brush->size = 50;
				brush->strength = 0.3f; // XXX?
				brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF;
				
				brush = &gset->brush[GP_EDITBRUSH_TYPE_PINCH];
				brush->size = 50;
				brush->strength = 0.5f; // XXX?
				brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF;
				
				brush = &gset->brush[GP_EDITBRUSH_TYPE_RANDOMIZE];
				brush->size = 25;
				brush->strength = 0.5f;
				brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF;
			}
			
			ts->gpencil_v3d_align = GP_PROJECT_VIEWSPACE;
			ts->gpencil_v2d_align = GP_PROJECT_VIEWSPACE;
			ts->gpencil_seq_align = GP_PROJECT_VIEWSPACE;
			ts->gpencil_ima_align = GP_PROJECT_VIEWSPACE;

			ParticleEditSettings *pset = &ts->particle;
			for (int a = 0; a < PE_TOT_BRUSH; a++) {
				pset->brush[a].strength = 0.5f;
			}
			pset->brush[PE_BRUSH_CUT].strength = 1.0f;
		}

		scene->gm.lodflag |= SCE_LOD_USE_HYST;
		scene->gm.scehysteresis = 10;

		scene->r.ffcodecdata.audio_mixrate = 48000;
	}

	for (FreestyleLineStyle *linestyle = bmain->linestyle.first; linestyle; linestyle = linestyle->id.next) {
		linestyle->flag = LS_SAME_OBJECT | LS_NO_SORTING | LS_TEXTURE;
		linestyle->sort_key = LS_SORT_KEY_DISTANCE_FROM_CAMERA;
		linestyle->integration_type = LS_INTEGRATION_MEAN;
		linestyle->texstep = 1.0;
		linestyle->chain_count = 10;
	}

	for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
		ScrArea *area;
		for (area = screen->areabase.first; area; area = area->next) {
			SpaceLink *space_link;
			ARegion *ar;

			for (space_link = area->spacedata.first; space_link; space_link = space_link->next) {
				if (space_link->spacetype == SPACE_CLIP) {
					SpaceClip *space_clip = (SpaceClip *) space_link;
					space_clip->flag &= ~SC_MANUAL_CALIBRATION;
				}
			}

			for (ar = area->regionbase.first; ar; ar = ar->next) {
				/* Remove all stored panels, we want to use defaults (order, open/closed) as defined by UI code here! */
				BLI_freelistN(&ar->panels);

				/* some toolbars have been saved as initialized,
				 * we don't want them to have odd zoom-level or scrolling set, see: T47047 */
				if (ELEM(ar->regiontype, RGN_TYPE_UI, RGN_TYPE_TOOLS, RGN_TYPE_TOOL_PROPS)) {
					ar->v2d.flag &= ~V2D_IS_INITIALISED;
				}
			}
		}
	}

	for (Mesh *me = bmain->mesh.first; me; me = me->id.next) {
		me->smoothresh = DEG2RADF(180.0f);
		me->flag &= ~ME_TWOSIDED;
	}

	for (Material *mat = bmain->mat.first; mat; mat = mat->id.next) {
		mat->line_col[0] = mat->line_col[1] = mat->line_col[2] = 0.0f;
		mat->line_col[3] = 1.0f;
	}

	{
		Object *ob;

		ob = (Object *)BKE_libblock_find_name_ex(bmain, ID_OB, "Camera");
		if (ob) {
			ob->rot[1] = 0.0f;
		}
	}

	{
		Brush *br;

		br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Fill");
		if (!br) {
			br = BKE_brush_add(bmain, "Fill", OB_MODE_TEXTURE_PAINT);
			br->imagepaint_tool = PAINT_TOOL_FILL;
			br->ob_mode = OB_MODE_TEXTURE_PAINT;
		}

		br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Mask");
		if (br) {
			br->imagepaint_tool = PAINT_TOOL_MASK;
			br->ob_mode |= OB_MODE_TEXTURE_PAINT;
		}

		/* remove polish brush (flatten/contrast does the same) */
		br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Polish");
		if (br) {
			BKE_libblock_free(bmain, br);
		}

		/* remove brush brush (huh?) from some modes (draw brushes do the same) */
		br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Brush");
		if (br) {
			BKE_libblock_free(bmain, br);
		}

		/* remove draw brush from texpaint (draw brushes do the same) */
		br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Draw");
		if (br) {
			br->ob_mode &= ~OB_MODE_TEXTURE_PAINT;
		}

		/* rename twist brush to rotate brush to match rotate tool */
		br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Twist");
		if (br) {
			BKE_libblock_rename(bmain, &br->id, "Rotate");
		}

		/* use original normal for grab brush (otherwise flickers with normal weighting). */
		br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Grab");
		if (br) {
			br->flag |= BRUSH_ORIGINAL_NORMAL;
		}

		/* increase strength, better for smoothing method */
		br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Blur");
		if (br) {
			br->alpha = 1.0f;
		}

		br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Flatten/Contrast");
		if (br) {
			br->flag |= BRUSH_ACCUMULATE;
		}
	}
}
/**
 * Update defaults in startup.blend, without having to save and embed the file.
 * This function can be emptied each time the startup.blend is updated. */
void BLO_update_defaults_startup_blend(Main *bmain)
{
	Scene *scene;
	SceneRenderLayer *srl;
	FreestyleLineStyle *linestyle;
	Mesh *me;
	Material *mat;

	for (scene = bmain->scene.first; scene; scene = scene->id.next) {
		scene->r.im_format.planes = R_IMF_PLANES_RGBA;
		scene->r.im_format.compress = 15;

		for (srl = scene->r.layers.first; srl; srl = srl->next) {
			srl->freestyleConfig.sphere_radius = 0.1f;
			srl->pass_alpha_threshold = 0.5f;
		}

		if (scene->toolsettings) {
			ToolSettings *ts = scene->toolsettings;

			if (ts->sculpt) {
				Sculpt *sculpt = ts->sculpt;
				sculpt->paint.symmetry_flags |= PAINT_SYMM_X;
				sculpt->flags |= SCULPT_DYNTOPO_COLLAPSE;
				sculpt->detail_size = 12;
			}
		}

		scene->gm.lodflag |= SCE_LOD_USE_HYST;
		scene->gm.scehysteresis = 10;
	}

	for (linestyle = bmain->linestyle.first; linestyle; linestyle = linestyle->id.next) {
		linestyle->flag = LS_SAME_OBJECT | LS_NO_SORTING | LS_TEXTURE;
		linestyle->sort_key = LS_SORT_KEY_DISTANCE_FROM_CAMERA;
		linestyle->integration_type = LS_INTEGRATION_MEAN;
		linestyle->texstep = 1.0;
		linestyle->chain_count = 10;
	}

	{
		bScreen *screen;

		for (screen = bmain->screen.first; screen; screen = screen->id.next) {
			ScrArea *area;
			for (area = screen->areabase.first; area; area = area->next) {
				SpaceLink *space_link;
				ARegion *ar;

				for (space_link = area->spacedata.first; space_link; space_link = space_link->next) {
					if (space_link->spacetype == SPACE_CLIP) {
						SpaceClip *space_clip = (SpaceClip *) space_link;
						space_clip->flag &= ~SC_MANUAL_CALIBRATION;
					}
				}

				for (ar = area->regionbase.first; ar; ar = ar->next) {
					/* Remove all stored panels, we want to use defaults (order, open/closed) as defined by UI code here! */
					BLI_freelistN(&ar->panels);

					/* simple fix for 3d view properties scrollbar being not set to top */
					if (ar->regiontype == RGN_TYPE_UI) {
						ar->v2d.cur.ymax = ar->v2d.tot.ymax;
						ar->v2d.cur.ymin = ar->v2d.cur.ymax - ar->winy;
					}
				}
			}
		}
	}

	for (me = bmain->mesh.first; me; me = me->id.next) {
		me->smoothresh = DEG2RADF(180.0f);
		me->flag &= ~ME_TWOSIDED;
	}

	for (mat = bmain->mat.first; mat; mat = mat->id.next) {
		mat->line_col[0] = mat->line_col[1] = mat->line_col[2] = 0.0f;
		mat->line_col[3] = 1.0f;
	}

	{
		Brush *br;

		br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Fill");
		if (!br) {
			br = BKE_brush_add(bmain, "Fill");
			br->imagepaint_tool = PAINT_TOOL_FILL;
			br->ob_mode = OB_MODE_TEXTURE_PAINT;
		}

		br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Mask");
		if (br) {
			br->imagepaint_tool = PAINT_TOOL_MASK;
			br->ob_mode |= OB_MODE_TEXTURE_PAINT;
		}

		/* remove polish brush (flatten/contrast does the same) */
		br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Polish");
		if (br) {
			BKE_libblock_free(bmain, br);
		}

		/* remove brush brush (huh?) from some modes (draw brushes do the same) */
		br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Brush");
		if (br) {
			BKE_libblock_free(bmain, br);
		}

		/* remove draw brush from texpaint (draw brushes do the same) */
		br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Draw");
		if (br) {
			br->ob_mode &= ~OB_MODE_TEXTURE_PAINT;
		}
	}
}
Example #26
0
bool BL_Action::Play(const std::string& name,
					float start,
					float end,
					short priority,
					float blendin,
					short play_mode,
					float layer_weight,
					short ipo_flags,
					float playback_speed,
					short blend_mode)
{

	// Only start playing a new action if we're done, or if
	// the new action has a higher priority
	if (!IsDone() && priority > m_priority)
		return false;
	m_priority = priority;
	bAction* prev_action = m_action;

	KX_Scene* kxscene = m_obj->GetScene();

	// First try to load the action
	m_action = (bAction*)kxscene->GetLogicManager()->GetActionByName(name);
	if (!m_action)
	{
		CM_Error("failed to load action: " << name);
		m_done = true;
		return false;
	}

	// If we have the same settings, don't play again
	// This is to resolve potential issues with pulses on sensors such as the ones
	// reported in bug #29412. The fix is here so it works for both logic bricks and Python.
	// However, this may eventually lead to issues where a user wants to override an already
	// playing action with the same action and settings. If this becomes an issue,
	// then this fix may have to be re-evaluated.
	if (!IsDone() && m_action == prev_action && m_startframe == start && m_endframe == end
			&& m_priority == priority && m_speed == playback_speed)
		return false;

	// Keep a copy of the action for threading purposes
	if (m_tmpaction) {
		BKE_libblock_free(G.main, m_tmpaction);
		m_tmpaction = NULL;
	}
	m_tmpaction = BKE_action_copy(G.main, m_action);

	// First get rid of any old controllers
	ClearControllerList();

	// Create an SG_Controller
	SG_Controller *sg_contr = BL_CreateIPO(m_action, m_obj, kxscene->GetSceneConverter());
	m_sg_contr_list.push_back(sg_contr);
	m_obj->GetSGNode()->AddSGController(sg_contr);
	sg_contr->SetObject(m_obj->GetSGNode());

	// World
	sg_contr = BL_CreateWorldIPO(m_action, kxscene->GetBlenderScene()->world, kxscene->GetSceneConverter());
	if (sg_contr) {
		m_sg_contr_list.push_back(sg_contr);
		m_obj->GetSGNode()->AddSGController(sg_contr);
		sg_contr->SetObject(m_obj->GetSGNode());
	}

	// Try obcolor
	sg_contr = BL_CreateObColorIPO(m_action, m_obj, kxscene->GetSceneConverter());
	if (sg_contr) {
		m_sg_contr_list.push_back(sg_contr);
		m_obj->GetSGNode()->AddSGController(sg_contr);
		sg_contr->SetObject(m_obj->GetSGNode());
	}

	// Now try materials
	for (int matidx = 1; matidx <= m_obj->GetBlenderObject()->totcol; ++matidx) {
		Material *mat = give_current_material(m_obj->GetBlenderObject(), matidx);
		if (!mat) {
			continue;
		}

		KX_BlenderSceneConverter *converter = kxscene->GetSceneConverter();
		RAS_IPolyMaterial *polymat = converter->FindCachedPolyMaterial(kxscene, mat);
		if (!polymat) {
			continue;
		}

		sg_contr = BL_CreateMaterialIpo(m_action, mat, polymat, m_obj, converter);
		if (sg_contr) {
			m_sg_contr_list.push_back(sg_contr);
			m_obj->GetSGNode()->AddSGController(sg_contr);
			sg_contr->SetObject(m_obj->GetSGNode());
		}
	}

	// Extra controllers
	if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_LIGHT)
	{
		sg_contr = BL_CreateLampIPO(m_action, m_obj, kxscene->GetSceneConverter());
		m_sg_contr_list.push_back(sg_contr);
		m_obj->GetSGNode()->AddSGController(sg_contr);
		sg_contr->SetObject(m_obj->GetSGNode());
	}
	else if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_CAMERA)
	{
		sg_contr = BL_CreateCameraIPO(m_action, m_obj, kxscene->GetSceneConverter());
		m_sg_contr_list.push_back(sg_contr);
		m_obj->GetSGNode()->AddSGController(sg_contr);
		sg_contr->SetObject(m_obj->GetSGNode());
	}
	
	m_ipo_flags = ipo_flags;
	InitIPO();

	// Setup blendin shapes/poses
	if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
	{
		BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj;
		obj->GetPose(&m_blendinpose);
	}
	else
	{
		BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj;
		BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer());
		
		if (shape_deformer && shape_deformer->GetKey())
		{
			obj->GetShape(m_blendinshape);

			// Now that we have the previous blend shape saved, we can clear out the key to avoid any
			// further interference.
			KeyBlock *kb;
			for (kb=(KeyBlock *)shape_deformer->GetKey()->block.first; kb; kb=(KeyBlock *)kb->next)
				kb->curval = 0.f;
		}
	}

	// Now that we have an action, we have something we can play
	m_starttime = KX_GetActiveEngine()->GetFrameTime() - kxscene->getSuspendedDelta();
	m_startframe = m_localframe = start;
	m_endframe = end;
	m_blendin = blendin;
	m_playmode = play_mode;
	m_blendmode = blend_mode;
	m_blendframe = 0.f;
	m_blendstart = 0.f;
	m_speed = playback_speed;
	m_layer_weight = layer_weight;
	
	m_done = false;
	m_appliedToObject = false;

	m_prevUpdate = -1.0f;

	return true;
}
Example #27
0
void free_main(Main *mainvar)
{
	/* also call when reading a file, erase all, etc */
	ListBase *lbarray[MAX_LIBARRAY];
	int a;

	a = set_listbasepointers(mainvar, lbarray);
	while (a--) {
		ListBase *lb = lbarray[a];
		ID *id;
		
		while ( (id = lb->first) ) {
#if 1
			BKE_libblock_free(lb, id);
#else
			/* errors freeing ID's can be hard to track down,
			 * enable this so valgrind will give the line number in its error log */
			switch (a) {
				case   0: BKE_libblock_free(lb, id); break;
				case   1: BKE_libblock_free(lb, id); break;
				case   2: BKE_libblock_free(lb, id); break;
				case   3: BKE_libblock_free(lb, id); break;
				case   4: BKE_libblock_free(lb, id); break;
				case   5: BKE_libblock_free(lb, id); break;
				case   6: BKE_libblock_free(lb, id); break;
				case   7: BKE_libblock_free(lb, id); break;
				case   8: BKE_libblock_free(lb, id); break;
				case   9: BKE_libblock_free(lb, id); break;
				case  10: BKE_libblock_free(lb, id); break;
				case  11: BKE_libblock_free(lb, id); break;
				case  12: BKE_libblock_free(lb, id); break;
				case  13: BKE_libblock_free(lb, id); break;
				case  14: BKE_libblock_free(lb, id); break;
				case  15: BKE_libblock_free(lb, id); break;
				case  16: BKE_libblock_free(lb, id); break;
				case  17: BKE_libblock_free(lb, id); break;
				case  18: BKE_libblock_free(lb, id); break;
				case  19: BKE_libblock_free(lb, id); break;
				case  20: BKE_libblock_free(lb, id); break;
				case  21: BKE_libblock_free(lb, id); break;
				case  22: BKE_libblock_free(lb, id); break;
				case  23: BKE_libblock_free(lb, id); break;
				case  24: BKE_libblock_free(lb, id); break;
				case  25: BKE_libblock_free(lb, id); break;
				case  26: BKE_libblock_free(lb, id); break;
				case  27: BKE_libblock_free(lb, id); break;
				case  28: BKE_libblock_free(lb, id); break;
				case  29: BKE_libblock_free(lb, id); break;
				case  30: BKE_libblock_free(lb, id); break;
				case  31: BKE_libblock_free(lb, id); break;
				case  32: BKE_libblock_free(lb, id); break;
				default:
					BLI_assert(0);
					break;
			}
#endif
		}
	}

	MEM_freeN(mainvar);
}
Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom,
                                         bool isController,
                                         std::map<COLLADAFW::UniqueId, Material *>& uid_material_map,
                                         std::map<Material *, TexIndexTextureArrayMap>& material_texture_mapping_map)
{
	const COLLADAFW::UniqueId *geom_uid = &geom->getInstanciatedObjectId();
	
	// check if node instanciates controller or geometry
	if (isController) {
		
		geom_uid = armature_importer->get_geometry_uid(*geom_uid);
		
		if (!geom_uid) {
			fprintf(stderr, "Couldn't find a mesh UID by controller's UID.\n");
			return NULL;
		}
	}
	else {
		
		if (uid_mesh_map.find(*geom_uid) == uid_mesh_map.end()) {
			// this could happen if a mesh was not created
			// (e.g. if it contains unsupported geometry)
			fprintf(stderr, "Couldn't find a mesh by UID.\n");
			return NULL;
		}
	}
	if (!uid_mesh_map[*geom_uid]) return NULL;
	
	// name Object
	const std::string& id = node->getName().size() ? node->getName() : node->getOriginalId();
	const char *name = (id.length()) ? id.c_str() : NULL;
	
	// add object
	Object *ob = bc_add_object(scene, OB_MESH, name);
	bc_set_mark(ob); // used later for material assignement optimization


	// store object pointer for ArmatureImporter
	uid_object_map[*geom_uid] = ob;
	imported_objects.push_back(ob);
	
	// replace ob->data freeing the old one
	Mesh *old_mesh = (Mesh *)ob->data;
	Mesh *new_mesh = uid_mesh_map[*geom_uid];

	BKE_mesh_assign_object(ob, new_mesh);
	BKE_mesh_calc_normals(new_mesh);

	if (old_mesh->id.us == 0) BKE_libblock_free(G.main, old_mesh);
	
	char layername[100];
	layername[0] = '\0';
	MTFace *texture_face = NULL;
	
	COLLADAFW::MaterialBindingArray& mat_array =
	    geom->getMaterialBindings();
	
	// loop through geom's materials
	for (unsigned int i = 0; i < mat_array.getCount(); i++) {
		
		if (mat_array[i].getReferencedMaterial().isValid()) {
			texture_face = assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid,
			                                       layername, texture_face,
			                                       material_texture_mapping_map, i);
		}
		else {
			fprintf(stderr, "invalid referenced material for %s\n", mat_array[i].getName().c_str());
		}
	}

	return ob;
}