コード例 #1
0
static int get_next_bake_face(BakeShade *bs)
{
	ObjectRen *obr;
	VlakRen *vlr;
	MTFace *tface;
	static int v = 0, vdone = false;
	static ObjectInstanceRen *obi = NULL;

	if (bs == NULL) {
		vlr = NULL;
		v = vdone = false;
		obi = R.instancetable.first;
		return 0;
	}
	
	BLI_lock_thread(LOCK_CUSTOM1);

	for (; obi; obi = obi->next, v = 0) {
		obr = obi->obr;

		for (; v < obr->totvlak; v++) {
			vlr = RE_findOrAddVlak(obr, v);

			if ((bs->actob && bs->actob == obr->ob) || (!bs->actob && (obr->ob->flag & SELECT))) {
				if (R.r.bake_flag & R_BAKE_VCOL) {
					/* Gather face data for vertex color bake */
					Mesh *me;
					int *origindex, vcollayer;
					CustomDataLayer *cdl;

					if (obr->ob->type != OB_MESH)
						continue;
					me = obr->ob->data;

					origindex = RE_vlakren_get_origindex(obr, vlr, 0);
					if (origindex == NULL)
						continue;
					if (*origindex >= me->totpoly) {
						/* Small hack for Array modifier, which gives false
						 * original indices - z0r */
						continue;
					}
#if 0
					/* Only shade selected faces. */
					if ((me->mface[*origindex].flag & ME_FACE_SEL) == 0)
						continue;
#endif

					vcollayer = CustomData_get_render_layer_index(&me->ldata, CD_MLOOPCOL);
					if (vcollayer == -1)
						continue;

					cdl = &me->ldata.layers[vcollayer];
					bs->mpoly = me->mpoly + *origindex;
					bs->vcol = ((MLoopCol *)cdl->data) + bs->mpoly->loopstart;
					bs->mloop = me->mloop + bs->mpoly->loopstart;

					/* Tag mesh for reevaluation. */
					me->id.flag |= LIB_DOIT;
				}
				else {
					Image *ima = NULL;
					ImBuf *ibuf = NULL;
					const float vec_alpha[4] = {0.0f, 0.0f, 0.0f, 0.0f};
					const float vec_solid[4] = {0.0f, 0.0f, 0.0f, 1.0f};
					const float nor_alpha[4] = {0.5f, 0.5f, 1.0f, 0.0f};
					const float nor_solid[4] = {0.5f, 0.5f, 1.0f, 1.0f};
					const float disp_alpha[4] = {0.5f, 0.5f, 0.5f, 0.0f};
					const float disp_solid[4] = {0.5f, 0.5f, 0.5f, 1.0f};

					tface = RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);

					if (!tface || !tface->tpage)
						continue;

					ima = tface->tpage;
					ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL, IMA_IBUF_IMA);

					if (ibuf == NULL)
						continue;

					if (ibuf->rect == NULL && ibuf->rect_float == NULL) {
						BKE_image_release_ibuf(ima, ibuf, NULL);
						continue;
					}

					if (ibuf->rect_float && !(ibuf->channels == 0 || ibuf->channels == 4)) {
						BKE_image_release_ibuf(ima, ibuf, NULL);
						continue;
					}
					
					if (ima->flag & IMA_USED_FOR_RENDER) {
						ima->id.flag &= ~LIB_DOIT;
						BKE_image_release_ibuf(ima, ibuf, NULL);
						continue;
					}
					
					/* find the image for the first time? */
					if (ima->id.flag & LIB_DOIT) {
						ima->id.flag &= ~LIB_DOIT;
						
						/* we either fill in float or char, this ensures things go fine */
						if (ibuf->rect_float)
							imb_freerectImBuf(ibuf);
						/* clear image */
						if (R.r.bake_flag & R_BAKE_CLEAR) {
							if (R.r.bake_mode == RE_BAKE_NORMALS && R.r.bake_normal_space == R_BAKE_SPACE_TANGENT)
								IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid);
							else if (ELEM(R.r.bake_mode, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE))
								IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? disp_alpha : disp_solid);
							else
								IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
						}
						/* might be read by UI to set active image for display */
						R.bakebuf = ima;
					}

					/* Tag image for redraw. */
					ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
					BKE_image_release_ibuf(ima, ibuf, NULL);
				}

				bs->obi = obi;
				bs->vlr = vlr;
				bs->vdone++;  /* only for error message if nothing was rendered */
				v++;
				BLI_unlock_thread(LOCK_CUSTOM1);
				return 1;
			}
		}
	}
	
	BLI_unlock_thread(LOCK_CUSTOM1);
	return 0;
}
コード例 #2
0
ファイル: bake.c プロジェクト: mistajuliax/OctaneBlender
/* already have tested for tface and ima and zspan */
static void shade_tface(BakeShade *bs)
{
	VlakRen *vlr = bs->vlr;
	ObjectInstanceRen *obi = bs->obi;
	ObjectRen *obr = obi->obr;
	MTFace *tface = RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
	Image *ima = tface->tpage;
	float vec[4][2];
	int a, i1, i2, i3;
	
	/* check valid zspan */
	if (ima != bs->ima) {
		BKE_image_release_ibuf(bs->ima, bs->ibuf, NULL);

		bs->ima = ima;
		bs->ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
		/* note, these calls only free/fill contents of zspan struct, not zspan itself */
		zbuf_free_span(bs->zspan);
		zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y, R.clipcrop);
	}

	bs->rectx = bs->ibuf->x;
	bs->recty = bs->ibuf->y;
	bs->rect = bs->ibuf->rect;
	bs->rect_colorspace = bs->ibuf->rect_colorspace;
	bs->rect_float = bs->ibuf->rect_float;
	bs->vcol = NULL;
	bs->quad = 0;
	bs->rect_mask = NULL;
	bs->displacement_buffer = NULL;

	if (bs->use_mask || bs->use_displacement_buffer) {
		BakeImBufuserData *userdata = bs->ibuf->userdata;
		if (userdata == NULL) {
			BLI_lock_thread(LOCK_CUSTOM1);
			userdata = bs->ibuf->userdata;
			if (userdata == NULL) /* since the thread was locked, its possible another thread alloced the value */
				userdata = MEM_callocN(sizeof(BakeImBufuserData), "BakeImBufuserData");

			if (bs->use_mask) {
				if (userdata->mask_buffer == NULL) {
					userdata->mask_buffer = MEM_callocN(sizeof(char) * bs->rectx * bs->recty, "BakeMask");
				}
			}

			if (bs->use_displacement_buffer) {
				if (userdata->displacement_buffer == NULL) {
					userdata->displacement_buffer = MEM_callocN(sizeof(float) * bs->rectx * bs->recty, "BakeDisp");
				}
			}

			bs->ibuf->userdata = userdata;

			BLI_unlock_thread(LOCK_CUSTOM1);
		}

		bs->rect_mask = userdata->mask_buffer;
		bs->displacement_buffer = userdata->displacement_buffer;
	}
	
	/* get pixel level vertex coordinates */
	for (a = 0; a < 4; a++) {
		/* Note, workaround for pixel aligned UVs which are common and can screw up our intersection tests
		 * where a pixel gets in between 2 faces or the middle of a quad,
		 * camera aligned quads also have this problem but they are less common.
		 * Add a small offset to the UVs, fixes bug #18685 - Campbell */
		vec[a][0] = tface->uv[a][0] * (float)bs->rectx - (0.5f + 0.001f);
		vec[a][1] = tface->uv[a][1] * (float)bs->recty - (0.5f + 0.002f);
	}

	/* UV indices have to be corrected for possible quad->tria splits */
	i1 = 0; i2 = 1; i3 = 2;
	vlr_set_uv_indices(vlr, &i1, &i2, &i3);
	bake_set_vlr_dxyco(bs, vec[i1], vec[i2], vec[i3]);
	zspan_scanconvert(bs->zspan, bs, vec[i1], vec[i2], vec[i3], do_bake_shade);
	
	if (vlr->v4) {
		bs->quad = 1;
		bake_set_vlr_dxyco(bs, vec[0], vec[2], vec[3]);
		zspan_scanconvert(bs->zspan, bs, vec[0], vec[2], vec[3], do_bake_shade);
	}
}