Пример #1
0
static void load_frame_image_sequence(VoxelData *vd, Tex *tex)
{
	ImBuf *ibuf;
	Image *ima = tex->ima;
	ImageUser *tiuser = &tex->iuser;
	ImageUser iuser = *(tiuser);
	int x=0, y=0, z=0;
	float *rf;

	if (!ima || !tiuser) return;
	if (iuser.frames == 0) return;
	
	ima->source = IMA_SRC_SEQUENCE;
	iuser.framenr = 1 + iuser.offset;

	/* find the first valid ibuf and use it to initialise the resolution of the data set */
	/* need to do this in advance so we know how much memory to allocate */
	ibuf= BKE_image_get_ibuf(ima, &iuser);
	while (!ibuf && (iuser.framenr < iuser.frames)) {
		iuser.framenr++;
		ibuf= BKE_image_get_ibuf(ima, &iuser);
	}
	if (!ibuf) return;
	if (!ibuf->rect_float) IMB_float_from_rect(ibuf);
	
	vd->flag |= TEX_VD_STILL;
	vd->resol[0] = ibuf->x;
	vd->resol[1] = ibuf->y;
	vd->resol[2] = iuser.frames;
	vd->dataset = MEM_mapallocN(sizeof(float)*vd_resol_size(vd), "voxel dataset");
	
	for (z=0; z < iuser.frames; z++)
	{	
		/* get a new ibuf for each frame */
		if (z > 0) {
			iuser.framenr++;
			ibuf= BKE_image_get_ibuf(ima, &iuser);
			if (!ibuf) break;
			if (!ibuf->rect_float) IMB_float_from_rect(ibuf);
		}
		rf = ibuf->rect_float;
		
		for (y=0; y < ibuf->y; y++)
		{
			for (x=0; x < ibuf->x; x++)
			{
				/* currently averaged to monchrome */
				vd->dataset[ V_I(x, y, z, vd->resol) ] = (rf[0] + rf[1] + rf[2])*0.333f;
				rf +=4;
			}
		}
		
		BKE_image_free_anim_ibufs(ima, iuser.framenr);
	}
	
	vd->ok = 1;
	return;
}
Пример #2
0
static unsigned char *get_alpha_clone_image(Scene *scene, int *width, int *height)
{
	Brush *brush = paint_brush(&scene->toolsettings->imapaint.paint);
	ImBuf *ibuf;
	unsigned int size, alpha;
	unsigned char *rect, *cp;

	if(!brush || !brush->clone.image)
		return NULL;
	
	ibuf= BKE_image_get_ibuf(brush->clone.image, NULL);

	if(!ibuf || !ibuf->rect)
		return NULL;

	rect= MEM_dupallocN(ibuf->rect);
	if(!rect)
		return NULL;

	*width= ibuf->x;
	*height= ibuf->y;

	size= (*width)*(*height);
	alpha= (unsigned char)255*brush->clone.alpha;
	cp= rect;

	while(size-- > 0) {
		cp[3]= alpha;
		cp += 4;
	}

	return rect;
}
Пример #3
0
static void bake_images(MultiresBakeRender *bkr)
{
	LinkData *link;

	for(link= bkr->image.first; link; link= link->next) {
		Image *ima= (Image*)link->data;
		ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);

		if(ibuf->x>0 && ibuf->y>0) {
			ibuf->userdata= MEM_callocN(ibuf->y*ibuf->x, "MultiresBake imbuf mask");

			switch(bkr->mode) {
				case RE_BAKE_NORMALS:
					do_multires_bake(bkr, ima, apply_tangmat_callback, init_normal_data, NULL, free_normal_data);
					break;
				case RE_BAKE_DISPLACEMENT:
					do_multires_bake(bkr, ima, apply_heights_callback, init_heights_data,
					                 apply_heights_data, free_heights_data);
					break;
			}
		}

		ima->id.flag|= LIB_DOIT;
	}
}
Пример #4
0
void BL_Texture::SplitEnvMap(EnvMap *map)
{
    if (!map || !map->ima || (map->ima && !map->ima->ok)) return;
    ImBuf *ibuf= BKE_image_get_ibuf(map->ima, NULL);
    if (ibuf)
        my_envmap_split_ima(map, ibuf);
}
Пример #5
0
static void apply_heights_data(void *bake_data)
{
	MHeightBakeData *height_data= (MHeightBakeData*)bake_data;
	ImBuf *ibuf= BKE_image_get_ibuf(height_data->ima, NULL);
	int x, y, i;
	float height, *heights= height_data->heights;
	float min= height_data->height_min, max= height_data->height_max;

	for(x= 0; x<ibuf->x; x++) {
		for(y =0; y<ibuf->y; y++) {
			i= ibuf->x*y + x;

			if(((char*)ibuf->userdata)[i] != FILTER_MASK_USED)
				continue;

			if(ibuf->rect_float) {
				float *rrgbf= ibuf->rect_float + i*4;

				if(max-min > 1e-5f) height= (heights[i]-min)/(max-min);
				else height= 0;

				rrgbf[0]=rrgbf[1]=rrgbf[2]= height;
			} else {
				char *rrgb= (char*)ibuf->rect + i*4;

				if(max-min > 1e-5f) height= (heights[i]-min)/(max-min);
				else height= 0;

				rrgb[0]=rrgb[1]=rrgb[2]= FTOCHAR(height);
			}
		}
	}

	ibuf->userflags= IB_RECT_INVALID;
}
Пример #6
0
static void *init_heights_data(MultiresBakeRender *bkr, Image *ima)
{
	MHeightBakeData *height_data;
	ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
	DerivedMesh *lodm= bkr->lores_dm;

	height_data= MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData");

	height_data->ima= ima;
	height_data->heights= MEM_callocN(sizeof(float)*ibuf->x*ibuf->y, "MultiresBake heights");
	height_data->height_max= -FLT_MAX;
	height_data->height_min= FLT_MAX;

	if(!bkr->use_lores_mesh) {
		SubsurfModifierData smd= {{NULL}};
		int ss_lvl= bkr->tot_lvl - bkr->lvl;

		CLAMP(ss_lvl, 0, 6);

		smd.levels= smd.renderLevels= ss_lvl;
		smd.flags|= eSubsurfModifierFlag_SubsurfUv;

		if(bkr->simple)
			smd.subdivType= ME_SIMPLE_SUBSURF;

		height_data->ssdm= subsurf_make_derived_from_derived(bkr->lores_dm, &smd, 0, NULL, 0, 0, 0);
	}

	height_data->origindex= lodm->getFaceDataArray(lodm, CD_ORIGINDEX);

	return (void*)height_data;
}
Пример #7
0
bool BL_Texture::InitFromImage(int unit,  Image *img, bool mipmap)
{

    ImBuf *ibuf;
    if (!img || img->ok==0)
    {
        mOk = false;
        return mOk;
    }

    ibuf= BKE_image_get_ibuf(img, NULL);
    if (ibuf==NULL)
    {
        img->ok = 0;
        mOk = false;
        return mOk;
    }


    mTexture = img->bindcode;
    mType = GL_TEXTURE_2D;
    mUnit = unit;

    ActivateUnit(mUnit);

    if (mTexture != 0) {
        glBindTexture(GL_TEXTURE_2D, mTexture );
        Validate();
        return mOk;
    }

    // look for an existing gl image
    BL_TextureMap::iterator mapLook = g_textureManager.find(img->id.name);
    if (mapLook != g_textureManager.end())
    {
        if (mapLook->second.gl_texture != 0)
        {
            mTexture = mapLook->second.gl_texture;
            glBindTexture(GL_TEXTURE_2D, mTexture);
            mOk = IsValid();
            return mOk;
        }
    }

    mNeedsDeleted = 1;
    glGenTextures(1, (GLuint*)&mTexture);
    InitGLTex(ibuf->rect, ibuf->x, ibuf->y, mipmap);

    // track created units
    BL_TextureObject obj;
    obj.gl_texture = mTexture;
    obj.ref_buffer = img;
    g_textureManager.insert(std::pair<char*, BL_TextureObject>((char*)img->id.name, obj));


    glDisable(GL_TEXTURE_2D);
    ActivateUnit(0);
    Validate();
    return mOk;
}
Пример #8
0
static void rna_Image_save(Image *image, ReportList *reports)
{
	ImBuf *ibuf= BKE_image_get_ibuf(image, NULL);
	if(ibuf) {
		char filename[FILE_MAXDIR + FILE_MAXFILE];
		BLI_strncpy(filename, image->name, sizeof(filename));
		BLI_path_abs(filename, G.main->name);

		if(image->packedfile) {
			if (writePackedFile(reports, image->name, image->packedfile, 0) != RET_OK) {
				BKE_reportf(reports, RPT_ERROR, "Image \"%s\" could saved packed file to \"%s\"", image->id.name+2, image->name);
			}
		}
		else if (IMB_saveiff(ibuf, filename, ibuf->flags)) {
			image->type= IMA_TYPE_IMAGE;

			if(image->source==IMA_SRC_GENERATED)
				image->source= IMA_SRC_FILE;

			ibuf->userflags &= ~IB_BITMAPDIRTY;
		}
		else {
			BKE_reportf(reports, RPT_ERROR, "Image \"%s\" could not be saved to \"%s\"", image->id.name+2, image->name);
		}
	}
	else {
		BKE_reportf(reports, RPT_ERROR, "Image \"%s\" does not have any image data", image->id.name+2);
	}
}
Пример #9
0
static void finish_images(MultiresBakeRender *bkr)
{
	LinkData *link;

	for(link= bkr->image.first; link; link= link->next) {
		Image *ima= (Image*)link->data;
		ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);

		if(ibuf->x<=0 || ibuf->y<=0)
			continue;

		RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, bkr->bake_filter);

		ibuf->userflags|= IB_BITMAPDIRTY;

		if(ibuf->rect_float)
			ibuf->userflags|= IB_RECT_INVALID;

		if(ibuf->mipmap[0]) {
			ibuf->userflags|= IB_MIPMAP_INVALID;
			imb_freemipmapImBuf(ibuf);
		}

		if(ibuf->userdata) {
			MEM_freeN(ibuf->userdata);
			ibuf->userdata= NULL;
		}
	}
}
Пример #10
0
/* note: this function is used for multilayer too, to ensure uniform 
   handling with BKE_image_get_ibuf() */
static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *iuser)
{
	ImBuf *ibuf;
	CompBuf *stackbuf;
	int type;

	float *rect;
	int alloc= FALSE;

	ibuf= BKE_image_get_ibuf(ima, iuser);
	if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) {
		return NULL;
	}

	if (ibuf->rect_float == NULL) {
		IMB_float_from_rect(ibuf);
	}

	/* now we need a float buffer from the image with matching color management */
	/* XXX weak code, multilayer is excluded from this */
	rect= ibuf->rect_float;
	
	/* done coercing into the correct color management */


	type= ibuf->channels;
	
	if(rd->scemode & R_COMP_CROP) {
		stackbuf= get_cropped_compbuf(&rd->disprect, rect, ibuf->x, ibuf->y, type);
		if(alloc)
			MEM_freeN(rect);
	}
	else {
		/* we put imbuf copy on stack, cbuf knows rect is from other ibuf when freed! */
		stackbuf= alloc_compbuf(ibuf->x, ibuf->y, type, FALSE);
		stackbuf->rect= rect;
		stackbuf->malloc= alloc;
	}
	
	/*code to respect the premul flag of images; I'm
	  not sure if this is a good idea for multilayer images,
	  since it never worked before for them.
	if (type==CB_RGBA && ima->flag & IMA_DO_PREMUL) {
		//premul the image
		int i;
		float *pixel = stackbuf->rect;
		
		for (i=0; i<stackbuf->x*stackbuf->y; i++, pixel += 4) {
			pixel[0] *= pixel[3];
			pixel[1] *= pixel[3];
			pixel[2] *= pixel[3];
		}
	}
	*/
	return stackbuf;
}
Пример #11
0
static void rna_Image_update(Image *image, ReportList *reports)
{
	ImBuf *ibuf= BKE_image_get_ibuf(image, NULL);

	if(ibuf == NULL) {
		BKE_reportf(reports, RPT_ERROR, "Image \"%s\" does not have any image data", image->id.name+2);
		return;
	}

	IMB_rect_from_float(ibuf);
}
Пример #12
0
/* MultiresBake callback for normals' baking
   general idea:
     - find coord and normal of point with specified UV in hi-res mesh
     - multiply it by tangmat
     - vector in color space would be norm(vec) /2 + (0.5, 0.5, 0.5) */
static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *UNUSED(bake_data),
                                   const int face_index, const int lvl, const float st[2],
                                   float tangmat[3][3], const int x, const int y)
{
	MTFace *mtface= CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
	MFace mface;
	Image *ima= mtface[face_index].tpage;
	ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
	float uv[2], *st0, *st1, *st2, *st3;
	int pixel= ibuf->x*y + x;
	float n[3], vec[3], tmp[3]= {0.5, 0.5, 0.5};

	lores_dm->getFace(lores_dm, face_index, &mface);

	st0= mtface[face_index].uv[0];
	st1= mtface[face_index].uv[1];
	st2= mtface[face_index].uv[2];

	if(mface.v4) {
		st3= mtface[face_index].uv[3];
		resolve_quad_uv(uv, st, st0, st1, st2, st3);
	} else
		resolve_tri_uv(uv, st, st0, st1, st2);

	CLAMP(uv[0], 0.0f, 1.0f);
	CLAMP(uv[1], 0.0f, 1.0f);

	get_ccgdm_data(lores_dm, hires_dm, lvl, face_index, uv[0], uv[1], NULL, n);

	mul_v3_m3v3(vec, tangmat, n);
	normalize_v3(vec);
	mul_v3_fl(vec, 0.5);
	add_v3_v3(vec, tmp);

	if(ibuf->rect_float) {
		float *rrgbf= ibuf->rect_float + pixel*4;
		rrgbf[0]= vec[0];
		rrgbf[1]= vec[1];
		rrgbf[2]= vec[2];
		rrgbf[3]= 1.0f;

		ibuf->userflags= IB_RECT_INVALID;
	} else {
		char *rrgb= (char*)ibuf->rect + pixel*4;
		rrgb[0]= FTOCHAR(vec[0]);
		rrgb[1]= FTOCHAR(vec[1]);
		rrgb[2]= FTOCHAR(vec[2]);
		rrgb[3]= 255;
	}
}
Пример #13
0
static void rna_Image_pack(Image *image, ReportList *reports, int as_png)
{
	ImBuf *ibuf = BKE_image_get_ibuf(image, NULL);

	if (!as_png && (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))) {
		BKE_reportf(reports, RPT_ERROR, "Can't pack edited image from disk, only as internal PNG");
	}
	else {
		if(as_png) {
			BKE_image_memorypack(image);
		}
		else {
			image->packedfile= newPackedFile(reports, image->name);
		}
	}
}
Пример #14
0
static CompBuf *node_composit_get_zimage(bNode *node, RenderData *rd)
{
	ImBuf *ibuf= BKE_image_get_ibuf((Image *)node->id, node->storage);
	CompBuf *zbuf= NULL;
	
	if(ibuf && ibuf->zbuf_float) {
		if(rd->scemode & R_COMP_CROP) {
			zbuf= get_cropped_compbuf(&rd->disprect, ibuf->zbuf_float, ibuf->x, ibuf->y, CB_VAL);
		}
		else {
			zbuf= alloc_compbuf(ibuf->x, ibuf->y, CB_VAL, 0);
			zbuf->rect= ibuf->zbuf_float;
		}
	}
	return zbuf;
}
Пример #15
0
/* TODO: should probably be unified with BrushPainter stuff? */
unsigned int *brush_gen_texture_cache(Brush *br, int half_side)
{
	unsigned int *texcache = NULL;
	MTex *mtex = &br->mtex;
	TexResult texres= {0};
	int hasrgb, ix, iy;
	int side = half_side * 2;
	
	if(mtex->tex) {
		float x, y, step = 2.0 / side, co[3];

		texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache");

		BKE_image_get_ibuf(mtex->tex->ima, NULL);
		
		/*do normalized cannonical view coords for texture*/
		for (y=-1.0, iy=0; iy<side; iy++, y += step) {
			for (x=-1.0, ix=0; ix<side; ix++, x += step) {
				co[0]= x;
				co[1]= y;
				co[2]= 0.0f;
				
				/* This is copied from displace modifier code */
				hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres);
			
				/* if the texture gave an RGB value, we assume it didn't give a valid
				 * intensity, so calculate one (formula from do_material_tex).
				 * if the texture didn't give an RGB value, copy the intensity across
				 */
				if(hasrgb & TEX_RGB)
					texres.tin = (0.35f * texres.tr + 0.45f *
								  texres.tg + 0.2f * texres.tb);

				texres.tin = texres.tin * 255.0f;
				((char*)texcache)[(iy*side+ix)*4] = (char)texres.tin;
				((char*)texcache)[(iy*side+ix)*4+1] = (char)texres.tin;
				((char*)texcache)[(iy*side+ix)*4+2] = (char)texres.tin;
				((char*)texcache)[(iy*side+ix)*4+3] = (char)texres.tin;
			}
		}
	}

	return texcache;
}
Пример #16
0
static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **UNUSED(in), short UNUSED(thread))
{
	float x = p->co[0];
	float y = p->co[1];
	Image *ima= (Image *)node->id;
	ImageUser *iuser= (ImageUser *)node->storage;
	
	if( ima ) {
		ImBuf *ibuf = BKE_image_get_ibuf(ima, iuser);
		if( ibuf ) {
			float xsize, ysize;
			float xoff, yoff;
			int px, py;
			
			float *result;

			xsize = ibuf->x / 2;
			ysize = ibuf->y / 2;
			xoff = yoff = -1;
					
			px = (int)( (x-xoff) * xsize );
			py = (int)( (y-yoff) * ysize );
		
			if( (!xsize) || (!ysize) ) return;
			
			if( !ibuf->rect_float ) {
				BLI_lock_thread(LOCK_IMAGE);
				if( !ibuf->rect_float )
					IMB_float_from_rect(ibuf);
				BLI_unlock_thread(LOCK_IMAGE);
			}
			
			while( px < 0 ) px += ibuf->x;
			while( py < 0 ) py += ibuf->y;
			while( px >= ibuf->x ) px -= ibuf->x;
			while( py >= ibuf->y ) py -= ibuf->y;
			
			result = ibuf->rect_float + py*ibuf->x*4 + px*4;
			QUATCOPY( out, result );
		}
	}
}
Пример #17
0
static int rna_Image_gl_load(Image *image, ReportList *reports, int filter, int mag)
{
	ImBuf *ibuf;
	unsigned int *bind = &image->bindcode;
	int error = GL_NO_ERROR;

	if(*bind)
		return error;

	ibuf= BKE_image_get_ibuf(image, NULL);

	if(ibuf == NULL || ibuf->rect == NULL ) {
		BKE_reportf(reports, RPT_ERROR, "Image \"%s\" does not have any image data", image->id.name+2);
		return (int)GL_INVALID_OPERATION;
	}

	/* could be made into a function? */
	glGenTextures(1, (GLuint*)bind);
	glBindTexture(GL_TEXTURE_2D, *bind);

	if (filter != GL_NEAREST && filter != GL_LINEAR)
		error = (int)gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_INT, ibuf->rect);

	if (!error) {
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, image->tpageflag & IMA_CLAMP_U ? GL_CLAMP : GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, image->tpageflag & IMA_CLAMP_V ? GL_CLAMP : GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLint)filter);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLint)mag);
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ibuf->x, ibuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); 
		error = (int)glGetError();
	}

	if (error) {
		glDeleteTextures(1, (GLuint*)bind);
		image->bindcode = 0;
	}

	return error;
}
Пример #18
0
static int pack_all_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
{
	Main *bmain= CTX_data_main(C);
	Image *ima;
	ImBuf *ibuf;

	// first check for dirty images
	for(ima=bmain->image.first; ima; ima=ima->id.next) {
		if(ima->ibufs.first) { /* XXX FIX */
			ibuf= BKE_image_get_ibuf(ima, NULL);
			
			if(ibuf && (ibuf->userflags & IB_BITMAPDIRTY))
				break;
		}
	}

	if(ima) {
		uiPupMenuOkee(C, "FILE_OT_pack_all", "Some images are painted on. These changes will be lost. Continue?");
		return OPERATOR_CANCELLED;
	}

	return pack_all_exec(C, op);
}
Пример #19
0
static void icon_preview_startjob(void *customdata, short *stop, short *do_update)
{
	ShaderPreview *sp= customdata;
	ID *id= sp->id;
	short idtype= GS(id->name);

	if(idtype == ID_IM) {
		Image *ima= (Image*)id;
		ImBuf *ibuf= NULL;
		ImageUser iuser= {NULL};

		/* ima->ok is zero when Image cannot load */
		if(ima==NULL || ima->ok==0)
			return;

		/* setup dummy image user */
		iuser.ok= iuser.framenr= 1;
		iuser.scene= sp->scene;
		
		/* elubie: this needs to be changed: here image is always loaded if not
		   already there. Very expensive for large images. Need to find a way to 
		   only get existing ibuf */
		ibuf = BKE_image_get_ibuf(ima, &iuser);
		if(ibuf==NULL || ibuf->rect==NULL)
			return;
		
		icon_copy_rect(ibuf, sp->sizex, sp->sizey, sp->pr_rect);

		*do_update= 1;
	}
	else if(idtype == ID_BR) {
		Brush *br= (Brush*)id;

		br->icon_imbuf= get_brush_icon(br);

		memset(sp->pr_rect, 0x888888, sp->sizex*sp->sizey*sizeof(unsigned int));

		if(!(br->icon_imbuf) || !(br->icon_imbuf->rect))
			return;

		icon_copy_rect(br->icon_imbuf, sp->sizex, sp->sizey, sp->pr_rect);

		*do_update= 1;
	}
	else {
		/* re-use shader job */
		shader_preview_startjob(customdata, stop, do_update);

		/* world is rendered with alpha=0, so it wasn't displayed 
		   this could be render option for sky to, for later */
		if(idtype == ID_WO) {
			set_alpha((char*)sp->pr_rect, sp->sizex, sp->sizey, 255);
		}
		else if(idtype == ID_MA) {
			Material* ma = (Material*)id;

			if(ma->material_type == MA_TYPE_HALO)
				set_alpha((char*)sp->pr_rect, sp->sizex, sp->sizey, 255);
		}
	}
}
Пример #20
0
static int rna_Image_file_format_get(PointerRNA *ptr)
{
	Image *image= (Image*)ptr->data;
	ImBuf *ibuf= BKE_image_get_ibuf(image, NULL);
	return BKE_ftype_to_imtype(ibuf ? ibuf->ftype : 0);
}
Пример #21
0
/* note: this function is used for multilayer too, to ensure uniform 
   handling with BKE_image_get_ibuf() */
static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *iuser)
{
	ImBuf *ibuf;
	CompBuf *stackbuf;
	int type;
	
	ibuf= BKE_image_get_ibuf(ima, iuser);
	if(ibuf==NULL)
		return NULL;
	
	if (rd->color_mgt_flag & R_COLOR_MANAGEMENT) {
		if (ibuf->profile == IB_PROFILE_NONE) {
			/* if float buffer already exists = already linear */
			/* else ... */
			if (ibuf->rect_float == NULL) {
				imb_freerectfloatImBuf(ibuf);
				ibuf->profile = IB_PROFILE_SRGB;
				IMB_float_from_rect(ibuf);
			} else {
				ibuf->profile = IB_PROFILE_LINEAR_RGB;
			}
		}
	} else {
		if (ibuf->profile == IB_PROFILE_SRGB) {
			if (ibuf->rect_float != NULL) {
				imb_freerectfloatImBuf(ibuf);
			}
			ibuf->profile = IB_PROFILE_NONE;
			IMB_float_from_rect(ibuf);
		}
	}
	
	if (ibuf->rect_float == NULL) {
		IMB_float_from_rect(ibuf);
	}

	type= ibuf->channels;
	
	if(rd->scemode & R_COMP_CROP) {
		stackbuf= get_cropped_compbuf(&rd->disprect, ibuf->rect_float, ibuf->x, ibuf->y, type);
	}
	else {
		/* we put imbuf copy on stack, cbuf knows rect is from other ibuf when freed! */
		stackbuf= alloc_compbuf(ibuf->x, ibuf->y, type, 0);
		stackbuf->rect= ibuf->rect_float;
	}
	
	/*code to respect the premul flag of images; I'm
	  not sure if this is a good idea for multilayer images,
	  since it never worked before for them.
	if (type==CB_RGBA && ima->flag & IMA_DO_PREMUL) {
		//premul the image
		int i;
		float *pixel = stackbuf->rect;
		
		for (i=0; i<stackbuf->x*stackbuf->y; i++, pixel += 4) {
			pixel[0] *= pixel[3];
			pixel[1] *= pixel[3];
			pixel[2] *= pixel[3];
		}
	}
	*/
	return stackbuf;
};
Пример #22
0
static void node_composit_exec_splitviewer(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
	/* image assigned to output */
	/* stack order input sockets: image image */
	
	if(in[0]->data==NULL || in[1]->data==NULL)
		return;
	
	if(node->id && (node->flag & NODE_DO_OUTPUT)) {	/* only one works on out */
		Image *ima= (Image *)node->id;
		RenderData *rd= data;
		ImBuf *ibuf;
		CompBuf *cbuf, *buf1, *buf2, *mask;
		int x, y;
		float offset;
		
		buf1= typecheck_compbuf(in[0]->data, CB_RGBA);
		buf2= typecheck_compbuf(in[1]->data, CB_RGBA);
		
		BKE_image_user_calc_imanr(node->storage, rd->cfra, 0);
		
		/* always returns for viewer image, but we check nevertheless */
		ibuf= BKE_image_get_ibuf(ima, node->storage);
		if(ibuf==NULL) {
			printf("node_composit_exec_viewer error\n");
			return;
		}
		
		/* free all in ibuf */
		imb_freerectImBuf(ibuf);
		imb_freerectfloatImBuf(ibuf);
		IMB_freezbuffloatImBuf(ibuf);
		
		/* make ibuf, and connect to ima */
		ibuf->x= buf1->x;
		ibuf->y= buf1->y;
		imb_addrectfloatImBuf(ibuf);
		
		ima->ok= IMA_OK_LOADED;

		/* output buf */
		cbuf= alloc_compbuf(buf1->x, buf1->y, CB_RGBA, 0);	/* no alloc*/
		cbuf->rect= ibuf->rect_float;
		
		/* mask buf */
		mask= alloc_compbuf(buf1->x, buf1->y, CB_VAL, 1);
		
		
		/* Check which offset mode is selected and limit offset if needed */
		if(node->custom2 == 0) {
			offset = buf1->x / 100.0f * node->custom1;
			CLAMP(offset, 0, buf1->x);
		}
		else {
			offset = buf1->y / 100.0f * node->custom1;
			CLAMP(offset, 0, buf1->y);
		}
		
		if(node->custom2 == 0) {
			for(y=0; y<buf1->y; y++) {
				float *fac= mask->rect + y*buf1->x;
				for(x=offset; x>0; x--, fac++)
					*fac= 1.0f;
			}
		}
		else {
			for(y=0; y<offset; y++) {
				float *fac= mask->rect + y*buf1->x;
				for(x=buf1->x; x>0; x--, fac++)
					*fac= 1.0f;
			}
		}
		
		composit3_pixel_processor(node, cbuf, buf1, in[0]->vec, buf2, in[1]->vec, mask, NULL, do_copy_split_rgba, CB_RGBA, CB_RGBA, CB_VAL);
		
		generate_preview(data, node, cbuf);
		free_compbuf(cbuf);
		free_compbuf(mask);
		
		if(in[0]->data != buf1) 
			free_compbuf(buf1);
		if(in[1]->data != buf2) 
			free_compbuf(buf2);
	}
}
Пример #23
0
static void do_multires_bake(MultiresBakeRender *bkr, Image* ima, MPassKnownData passKnownData,
                             MInitBakeData initBakeData, MApplyBakeData applyBakeData, MFreeBakeData freeBakeData)
{
	DerivedMesh *dm= bkr->lores_dm;
	ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
	const int lvl= bkr->lvl;
	const int tot_face= dm->getNumFaces(dm);
	MVert *mvert= dm->getVertArray(dm);
	MFace *mface= dm->getFaceArray(dm);
	MTFace *mtface= dm->getFaceDataArray(dm, CD_MTFACE);
	float *pvtangent= NULL;

	if(CustomData_get_layer_index(&dm->faceData, CD_TANGENT) == -1)
		DM_add_tangent_layer(dm);

	pvtangent= DM_get_face_data_layer(dm, CD_TANGENT);

	if(tot_face > 0) {  /* sanity check */
		int f= 0;
		MBakeRast bake_rast;
		MResolvePixelData data={NULL};

		data.mface= mface;
		data.mvert= mvert;
		data.mtface= mtface;
		data.pvtangent= pvtangent;
		data.precomputed_normals= dm->getFaceDataArray(dm, CD_NORMAL);	/* don't strictly need this */
		data.w= ibuf->x;
		data.h= ibuf->y;
		data.lores_dm= dm;
		data.hires_dm= bkr->hires_dm;
		data.lvl= lvl;
		data.pass_data= passKnownData;

		if(initBakeData)
			data.bake_data= initBakeData(bkr, ima);

		init_bake_rast(&bake_rast, ibuf, &data, flush_pixel);

		for(f= 0; f<tot_face; f++) {
			MTFace *mtfate= &mtface[f];
			int verts[3][2], nr_tris, t;

			if(multiresbake_test_break(bkr))
				break;

			if(mtfate->tpage!=ima)
				continue;

			data.face_index= f;

			/* might support other forms of diagonal splits later on such as
			   split by shortest diagonal.*/
			verts[0][0]=0;
			verts[1][0]=1;
			verts[2][0]=2;

			verts[0][1]=0;
			verts[1][1]=2;
			verts[2][1]=3;

			nr_tris= mface[f].v4!=0 ? 2 : 1;
			for(t= 0; t<nr_tris; t++) {
				data.i0= verts[0][t];
				data.i1= verts[1][t];
				data.i2 =verts[2][t];

				bake_rasterize(&bake_rast, mtfate->uv[data.i0], mtfate->uv[data.i1], mtfate->uv[data.i2]);
			}

			bkr->baked_faces++;

			if(bkr->do_update)
				*bkr->do_update= 1;

			if(bkr->progress)
				*bkr->progress= ((float)bkr->baked_objects + (float)bkr->baked_faces / tot_face) / bkr->tot_obj;
		}

		if(applyBakeData)
			applyBakeData(data.bake_data);

		if(freeBakeData)
			freeBakeData(data.bake_data);
	}
}
Пример #24
0
/* MultiresBake callback for heights baking
   general idea:
     - find coord of point with specified UV in hi-res mesh (let's call it p1)
     - find coord of point and normal with specified UV in lo-res mesh (or subdivided lo-res
       mesh to make texture smoother) let's call this point p0 and n.
     - height wound be dot(n, p1-p0) */
static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
                                   const int face_index, const int lvl, const float st[2],
                                   float UNUSED(tangmat[3][3]), const int x, const int y)
{
	MTFace *mtface= CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
	MFace mface;
	Image *ima= mtface[face_index].tpage;
	ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
	MHeightBakeData *height_data= (MHeightBakeData*)bake_data;
	float uv[2], *st0, *st1, *st2, *st3;
	int pixel= ibuf->x*y + x;
	float vec[3], p0[3], p1[3], n[3], len;

	lores_dm->getFace(lores_dm, face_index, &mface);

	st0= mtface[face_index].uv[0];
	st1= mtface[face_index].uv[1];
	st2= mtface[face_index].uv[2];

	if(mface.v4) {
		st3= mtface[face_index].uv[3];
		resolve_quad_uv(uv, st, st0, st1, st2, st3);
	} else
		resolve_tri_uv(uv, st, st0, st1, st2);

	CLAMP(uv[0], 0.0f, 1.0f);
	CLAMP(uv[1], 0.0f, 1.0f);

	get_ccgdm_data(lores_dm, hires_dm, height_data->origindex, lvl, face_index, uv[0], uv[1], p1, 0);

	if(height_data->ssdm) {
		get_ccgdm_data(lores_dm, height_data->ssdm, height_data->origindex, 0, face_index, uv[0], uv[1], p0, n);
	} else {
		lores_dm->getFace(lores_dm, face_index, &mface);

		if(mface.v4) {
			interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 1, p0);
			interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 0, n);
		} else {
			interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 1, p0);
			interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 0, n);
		}
	}

	sub_v3_v3v3(vec, p1, p0);
	len= dot_v3v3(n, vec);

	height_data->heights[pixel]= len;
	if(len<height_data->height_min) height_data->height_min= len;
	if(len>height_data->height_max) height_data->height_max= len;

	if(ibuf->rect_float) {
		float *rrgbf= ibuf->rect_float + pixel*4;
		rrgbf[3]= 1.0f;

		ibuf->userflags= IB_RECT_INVALID;
	} else {
		char *rrgb= (char*)ibuf->rect + pixel*4;
		rrgb[3]= 255;
	}
}
Пример #25
0
bool BL_Texture::InitCubeMap(int unit,  EnvMap *cubemap)
{
    if (!GLEW_ARB_texture_cube_map)
    {
        spit("cubemaps not supported");
        mOk = false;
        return mOk;
    }
    else if (!cubemap || cubemap->ima->ok==0)
    {
        mOk = false;
        return mOk;
    }

    ImBuf *ibuf= BKE_image_get_ibuf(cubemap->ima, NULL);
    if (ibuf==0)
    {
        cubemap->ima->ok = 0;
        mOk = false;
        return mOk;
    }

    mNeedsDeleted =	1;
    mType = GL_TEXTURE_CUBE_MAP_ARB;
    mTexture = 0;
    mUnit = unit;

    ActivateUnit(mUnit);

    BL_TextureMap::iterator mapLook = g_textureManager.find(cubemap->ima->id.name);
    if (mapLook != g_textureManager.end())
    {
        if (mapLook->second.gl_texture != 0 && mapLook->second.ref_buffer == cubemap->ima)
        {
            mTexture = mapLook->second.gl_texture;
            glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mTexture);
            mOk = IsValid();
            return mOk;
        }
    }


    glGenTextures(1, (GLuint*)&mTexture);
    glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mTexture);


    // track created units
    BL_TextureObject obj;
    obj.gl_texture = mTexture;
    obj.ref_buffer = cubemap->ima;
    g_textureManager.insert(std::pair<char*, BL_TextureObject>((char*)cubemap->ima->id.name, obj));


    bool needs_split = false;
    if (!cubemap->cube[0])
    {
        needs_split = true;
        spit ("Re-Generating texture buffer");
    }

    if (needs_split)
        my_envmap_split_ima(cubemap, ibuf);


    if (!is_pow2(cubemap->cube[0]->x) || !is_pow2(cubemap->cube[0]->y))
    {
        spit("invalid envmap size please render with CubeRes @ power of two");

        my_free_envmapdata(cubemap);
        mOk = false;
        return mOk;
    }


#define SetCubeMapFace(face, num)   \
	glTexImage2D(face, 0,GL_RGBA,	\
	cubemap->cube[num]->x,          \
	cubemap->cube[num]->y,          \
	0, GL_RGBA, GL_UNSIGNED_BYTE,   \
	cubemap->cube[num]->rect)

    SetCubeMapFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 5);
    SetCubeMapFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, 3);
    SetCubeMapFace(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, 0);
    SetCubeMapFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, 1);
    SetCubeMapFace(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, 2);
    SetCubeMapFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, 4);

    glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S,	 GL_CLAMP_TO_EDGE );
    glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T,	 GL_CLAMP_TO_EDGE );
    if(GLEW_VERSION_1_2)
        glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R,	 GL_CLAMP_TO_EDGE );

    if (needs_split)
        my_free_envmapdata(cubemap);



    glDisable(GL_TEXTURE_CUBE_MAP_ARB);
    ActivateUnit(0);

    mOk = IsValid();
    return mOk;
}
Пример #26
0
static int multiresbake_check(bContext *C, wmOperator *op)
{
	Scene *scene= CTX_data_scene(C);
	Object *ob;
	Mesh *me;
	MultiresModifierData *mmd;
	int ok= 1, a;

	CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
		ob= base->object;

		if(ob->type != OB_MESH) {
			BKE_report(op->reports, RPT_ERROR, "Basking of multires data only works with active object which is a mesh");

			ok= 0;
			break;
		}

		me= (Mesh*)ob->data;
		mmd= get_multires_modifier(scene, ob, 0);

		/* Multi-resolution should be and be last in the stack */
		if(ok && mmd) {
			ModifierData *md;

			ok= mmd->totlvl>0;

			for(md = (ModifierData*)mmd->modifier.next; md && ok; md = md->next) {
				if (modifier_isEnabled(scene, md, eModifierMode_Realtime)) {
					ok= 0;
				}
			}
		} else ok= 0;

		if(!ok) {
			BKE_report(op->reports, RPT_ERROR, "Multires data baking requires multi-resolution object");

			break;
		}

		if(!me->mtface) {
			BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking");

			ok= 0;
		} else {
			a= me->totface;
			while (ok && a--) {
				Image *ima= me->mtface[a].tpage;

				if(!ima) {
					BKE_report(op->reports, RPT_ERROR, "You should have active texture to use multires baker");

					ok= 0;
				} else {
					ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);

					if(!ibuf) {
						BKE_report(op->reports, RPT_ERROR, "Baking should happend to image with image buffer");

						ok= 0;
					} else {
						if(ibuf->rect==NULL && ibuf->rect_float==NULL)
							ok= 0;

						if(ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4))
							ok= 0;

						if(!ok)
							BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type");
					}
				}
			}
		}

		if(!ok)
			break;
	}
Пример #27
0
static void node_composit_exec_image(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out)
{
	
	/* image assigned to output */
	/* stack order input sockets: col, alpha */
	if(node->id) {
		RenderData *rd= data;
		Image *ima= (Image *)node->id;
		ImageUser *iuser= (ImageUser *)node->storage;
		CompBuf *stackbuf= NULL;
		
		/* first set the right frame number in iuser */
		BKE_image_user_calc_frame(iuser, rd->cfra, 0);
		
		/* force a load, we assume iuser index will be set OK anyway */
		if(ima->type==IMA_TYPE_MULTILAYER)
			BKE_image_get_ibuf(ima, iuser);
		
		if(ima->type==IMA_TYPE_MULTILAYER && ima->rr) {
			RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer);
			
			if(rl) {
				out[0]->data= stackbuf= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_COMBINED);
				
				/* go over all layers */
				outputs_multilayer_get(rd, rl, out, ima, iuser);
			}
		}
		else {
			stackbuf= node_composit_get_image(rd, ima, iuser);

			if (stackbuf) {
				/*respect image premul option*/
				if (stackbuf->type==CB_RGBA && ima->flag & IMA_DO_PREMUL) {
					int i;
					float *pixel;
			
					/*first duplicate stackbuf->rect, since it's just a pointer
					  to the source imbuf, and we don't want to change that.*/
					stackbuf->rect = MEM_dupallocN(stackbuf->rect);
					
					/* since stackbuf now has allocated memory, rather than just a pointer,
					 * mark it as allocated so it can be freed properly */
					stackbuf->malloc=1;
					
					/*premul the image*/
					pixel = stackbuf->rect;
					for (i=0; i<stackbuf->x*stackbuf->y; i++, pixel += 4) {
						pixel[0] *= pixel[3];
						pixel[1] *= pixel[3];
						pixel[2] *= pixel[3];
					}
				}
			
				/* put image on stack */	
				out[0]->data= stackbuf;
			
				if(out[2]->hasoutput)
					out[2]->data= node_composit_get_zimage(node, rd);
			}
		}
		
		/* alpha and preview for both types */
		if(stackbuf) {
			if(out[1]->hasoutput)
				out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A);

			generate_preview(data, node, stackbuf);
		}
	}	
}