예제 #1
0
static int ptcache_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
	PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
	Scene *scene= CTX_data_scene(C);
	Object *ob= ptr.id.data;
	PointCache *cache= ptr.data;
	PTCacheID *pid;
	ListBase pidlist;

	BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR);
	
	for(pid=pidlist.first; pid; pid=pid->next) {
		if(pid->cache == cache) {
			if(pid->ptcaches->first == pid->ptcaches->last)
				continue; /* don't delete last cache */

			BLI_remlink(pid->ptcaches, pid->cache);
			BKE_ptcache_free(pid->cache);
			*(pid->cache_ptr) = pid->ptcaches->first;

			break;
		}
	}

	BLI_freelistN(&pidlist);
	
	WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);

	return OPERATOR_FINISHED;
}
예제 #2
0
static int ptcache_add_new_exec(bContext *C, wmOperator *UNUSED(op))
{
	Scene *scene = CTX_data_scene(C);
	PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
	Object *ob= ptr.id.data;
	PointCache *cache= ptr.data;
	PTCacheID *pid;
	ListBase pidlist;

	BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR);
	
	for(pid=pidlist.first; pid; pid=pid->next) {
		if(pid->cache == cache) {
			*(pid->cache_ptr) = BKE_ptcache_add(pid->ptcaches);
			break;
		}
	}

	BLI_freelistN(&pidlist);

	WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
	WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);

	return OPERATOR_FINISHED;
}
예제 #3
0
static PTCacheBaker *ptcache_baker_create(bContext *C, wmOperator *op, bool all)
{
	PTCacheBaker *baker = MEM_callocN(sizeof(PTCacheBaker), "PTCacheBaker");

	baker->main = CTX_data_main(C);
	baker->scene = CTX_data_scene(C);
	baker->bake = RNA_boolean_get(op->ptr, "bake");
	baker->render = 0;
	baker->anim_init = 0;
	baker->quick_step = 1;

	if (!all) {
		PointerRNA ptr = CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
		Object *ob = ptr.id.data;
		PointCache *cache = ptr.data;

		ListBase pidlist;
		BKE_ptcache_ids_from_object(&pidlist, ob, baker->scene, MAX_DUPLI_RECUR);

		for (PTCacheID *pid = pidlist.first; pid; pid = pid->next) {
			if (pid->cache == cache) {
				baker->pid = *pid;
				break;
			}
		}

		BLI_freelistN(&pidlist);
	}

	return baker;
}
static int ptcache_bake_exec(bContext *C, wmOperator *op)
{
    Main *bmain = CTX_data_main(C);
    Scene *scene = CTX_data_scene(C);
    wmWindow *win = G.background ? NULL : CTX_wm_window(C);
    PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
    Object *ob= ptr.id.data;
    PointCache *cache= ptr.data;
    PTCacheBaker baker;
    PTCacheID *pid;
    ListBase pidlist;

    BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR);

    for (pid=pidlist.first; pid; pid=pid->next) {
        if (pid->cache == cache)
            break;
    }

    baker.main = bmain;
    baker.scene = scene;
    baker.pid = pid;
    baker.bake = RNA_boolean_get(op->ptr, "bake");
    baker.render = 0;
    baker.anim_init = 0;
    baker.quick_step = 1;
    baker.break_test = cache_break_test;
    baker.break_data = NULL;

    /* Disabled for now as this doesn't work properly,
     * and pointcache baking will be reimplemented with
     * the job system soon anyways. */
    if (win) {
        baker.progressbar = (void (*)(void *, int))WM_cursor_time;
        baker.progressend = (void (*)(void *))WM_cursor_modal_restore;
        baker.progresscontext = win;
    }
    else {
        printf("\n"); /* empty first line before console reports */
        baker.progressbar = bake_console_progress;
        baker.progressend = bake_console_progress_end;
        baker.progresscontext = NULL;
    }

    BKE_ptcache_bake(&baker);

    BLI_freelistN(&pidlist);

    WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
    WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);

    return OPERATOR_FINISHED;
}
예제 #5
0
static int ptcache_free_bake_all_exec(bContext *C, wmOperator *UNUSED(op))
{
	Scene *scene= CTX_data_scene(C);
	Base *base;
	PTCacheID *pid;
	ListBase pidlist;

	for(base=scene->base.first; base; base= base->next) {
		BKE_ptcache_ids_from_object(&pidlist, base->object, scene, MAX_DUPLI_RECUR);

		for(pid=pidlist.first; pid; pid=pid->next) {
			pid->cache->flag &= ~PTCACHE_BAKED;
		}
		
		BLI_freelistN(&pidlist);
		
		WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, base->object);
	}

	WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);

	return OPERATOR_FINISHED;
}
예제 #6
0
static void time_draw_cache(Main *bmain, SpaceTime *stime, Object *ob, Scene *scene)
{
	PTCacheID *pid;
	ListBase pidlist;
	SpaceTimeCache *stc = stime->caches.first;
	const float cache_draw_height = (4.0f * UI_DPI_FAC * U.pixelsize);
	float yoffs = 0.f;

	if (!(stime->cache_display & TIME_CACHE_DISPLAY) || (!ob))
		return;

	BKE_ptcache_ids_from_object(bmain, &pidlist, ob, scene, 0);

	/* iterate over pointcaches on the active object,
	 * add spacetimecache and vertex array for each */
	for (pid = pidlist.first; pid; pid = pid->next) {
		float col[4], *fp;
		int i, sta = pid->cache->startframe, end = pid->cache->endframe;
		int len = (end - sta + 1) * 4;

		switch (pid->type) {
			case PTCACHE_TYPE_SOFTBODY:
				if (!(stime->cache_display & TIME_CACHE_SOFTBODY)) continue;
				break;
			case PTCACHE_TYPE_PARTICLES:
				if (!(stime->cache_display & TIME_CACHE_PARTICLES)) continue;
				break;
			case PTCACHE_TYPE_CLOTH:
				if (!(stime->cache_display & TIME_CACHE_CLOTH)) continue;
				break;
			case PTCACHE_TYPE_SMOKE_DOMAIN:
			case PTCACHE_TYPE_SMOKE_HIGHRES:
				if (!(stime->cache_display & TIME_CACHE_SMOKE)) continue;
				break;
			case PTCACHE_TYPE_DYNAMICPAINT:
				if (!(stime->cache_display & TIME_CACHE_DYNAMICPAINT)) continue;
				break;
			case PTCACHE_TYPE_RIGIDBODY:
				if (!(stime->cache_display & TIME_CACHE_RIGIDBODY)) continue;
				break;
		}

		if (pid->cache->cached_frames == NULL)
			continue;

		/* make sure we have stc with correct array length */
		if (stc == NULL || MEM_allocN_len(stc->array) != len * 2 * sizeof(float)) {
			if (stc) {
				MEM_freeN(stc->array);
			}
			else {
				stc = MEM_callocN(sizeof(SpaceTimeCache), "spacetimecache");
				BLI_addtail(&stime->caches, stc);
			}

			stc->array = MEM_callocN(len * 2 * sizeof(float), "SpaceTimeCache array");
		}

		/* fill the vertex array with a quad for each cached frame */
		for (i = sta, fp = stc->array; i <= end; i++) {
			if (pid->cache->cached_frames[i - sta]) {
				fp[0] = (float)i - 0.5f;
				fp[1] = 0.0;
				fp += 2;

				fp[0] = (float)i - 0.5f;
				fp[1] = 1.0;
				fp += 2;

				fp[0] = (float)i + 0.5f;
				fp[1] = 1.0;
				fp += 2;

				fp[0] = (float)i + 0.5f;
				fp[1] = 0.0;
				fp += 2;
			}
		}

		glPushMatrix();
		glTranslatef(0.0, (float)V2D_SCROLL_HEIGHT + yoffs, 0.0);
		glScalef(1.0, cache_draw_height, 0.0);

		switch (pid->type) {
			case PTCACHE_TYPE_SOFTBODY:
				col[0] = 1.0;   col[1] = 0.4;   col[2] = 0.02;
				col[3] = 0.1;
				break;
			case PTCACHE_TYPE_PARTICLES:
				col[0] = 1.0;   col[1] = 0.1;   col[2] = 0.02;
				col[3] = 0.1;
				break;
			case PTCACHE_TYPE_CLOTH:
				col[0] = 0.1;   col[1] = 0.1;   col[2] = 0.75;
				col[3] = 0.1;
				break;
			case PTCACHE_TYPE_SMOKE_DOMAIN:
			case PTCACHE_TYPE_SMOKE_HIGHRES:
				col[0] = 0.2;   col[1] = 0.2;   col[2] = 0.2;
				col[3] = 0.1;
				break;
			case PTCACHE_TYPE_DYNAMICPAINT:
				col[0] = 1.0;   col[1] = 0.1;   col[2] = 0.75;
				col[3] = 0.1;
				break;
			case PTCACHE_TYPE_RIGIDBODY:
				col[0] = 1.0;   col[1] = 0.6;   col[2] = 0.0;
				col[3] = 0.1;
				break;
			default:
				col[0] = 1.0;   col[1] = 0.0;   col[2] = 1.0;
				col[3] = 0.1;
				BLI_assert(0);
				break;
		}
		glColor4fv(col);

		glEnable(GL_BLEND);

		glRectf((float)sta, 0.0, (float)end, 1.0);

		col[3] = 0.4f;
		if (pid->cache->flag & PTCACHE_BAKED) {
			col[0] -= 0.4f; col[1] -= 0.4f; col[2] -= 0.4f;
		}
		else if (pid->cache->flag & PTCACHE_OUTDATED) {
			col[0] += 0.4f; col[1] += 0.4f; col[2] += 0.4f;
		}
		glColor4fv(col);

		glEnableClientState(GL_VERTEX_ARRAY);
		glVertexPointer(2, GL_FLOAT, 0, stc->array);
		glDrawArrays(GL_QUADS, 0, (fp - stc->array) / 2);
		glDisableClientState(GL_VERTEX_ARRAY);

		glDisable(GL_BLEND);

		glPopMatrix();

		yoffs += cache_draw_height;

		stc = stc->next;
	}

	BLI_freelistN(&pidlist);

	/* free excessive caches */
	while (stc) {
		SpaceTimeCache *tmp = stc->next;
		BLI_remlink(&stime->caches, stc);
		MEM_freeN(stc->array);
		MEM_freeN(stc);
		stc = tmp;
	}
}
예제 #7
0
void ED_object_exit_editmode(bContext *C, int flag)
{
	/* Note! only in exceptional cases should 'EM_DO_UNDO' NOT be in the flag */

	Scene *scene= CTX_data_scene(C);
	Object *obedit= CTX_data_edit_object(C);
	int freedata = flag & EM_FREEDATA;
	
	if (obedit==NULL) return;
	
	if (flag & EM_WAITCURSOR) waitcursor(1);
	if (obedit->type==OB_MESH) {
		Mesh *me= obedit->data;
		
//		if (EM_texFaceCheck())
		
		if (me->edit_btmesh->bm->totvert>MESH_MAX_VERTS) {
			error("Too many vertices");
			return;
		}
		
		EDBM_mesh_load(obedit);
		
		if (freedata) {
			EDBM_mesh_free(me->edit_btmesh);
			MEM_freeN(me->edit_btmesh);
			me->edit_btmesh= NULL;
		}
		if (obedit->restore_mode & OB_MODE_WEIGHT_PAINT) {
			mesh_octree_table(NULL, NULL, NULL, 'e');
			mesh_mirrtopo_table(NULL, 'e');
		}
	}
	else if (obedit->type==OB_ARMATURE) {	
		ED_armature_from_edit(obedit);
		if (freedata)
			ED_armature_edit_free(obedit);
	}
	else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
		load_editNurb(obedit);
		if (freedata) free_editNurb(obedit);
	}
	else if (obedit->type==OB_FONT && freedata) {
		load_editText(obedit);
		if (freedata) free_editText(obedit);
	}
	else if (obedit->type==OB_LATTICE) {
		load_editLatt(obedit);
		if (freedata) free_editLatt(obedit);
	}
	else if (obedit->type==OB_MBALL) {
		load_editMball(obedit);
		if (freedata) free_editMball(obedit);
	}

	/* freedata only 0 now on file saves and render */
	if (freedata) {
		ListBase pidlist;
		PTCacheID *pid;

		/* for example; displist make is different in editmode */
		scene->obedit= NULL; // XXX for context

		/* flag object caches as outdated */
		BKE_ptcache_ids_from_object(&pidlist, obedit, NULL, 0);
		for (pid=pidlist.first; pid; pid=pid->next) {
			if (pid->type != PTCACHE_TYPE_PARTICLES) /* particles don't need reset on geometry change */
				pid->cache->flag |= PTCACHE_OUTDATED;
		}
		BLI_freelistN(&pidlist);
		
		BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_OUTDATED);

		/* also flush ob recalc, doesn't take much overhead, but used for particles */
		DAG_id_tag_update(&obedit->id, OB_RECALC_OB|OB_RECALC_DATA);
	
		if (flag & EM_DO_UNDO)
			ED_undo_push(C, "Editmode");
	
		if (flag & EM_WAITCURSOR) waitcursor(0);
	
		WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, scene);

		obedit->mode &= ~OB_MODE_EDIT;
	}
}