Remove TexFace, per-face images

TexFace complicates the now more popular shading pipeline by having
per-face images, see: T51382 for details.

To keep the ability to select a per-material edit-image
(used with UV-mapping workflow), the material now stores an image
which will be set when changing images in edit-mode.

This is used as a bake-target when not using Cycles too.
This commit is contained in:
Campbell Barton 2017-05-24 23:14:32 +10:00
parent 707340edd7
commit 7a9ad029dd
Notes: blender-bot 2023-02-14 07:00:24 +01:00
Referenced by issue #51382, Proposal for removing TexFace in 2.8x
47 changed files with 281 additions and 1222 deletions

View File

@ -989,7 +989,6 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
split = layout.split()
col = split.column()
col.prop(md, "use_image_override")
col.prop(md, "projector_count", text="Projectors")
for proj in md.projectors:
col.prop(proj, "object", text="")

View File

@ -794,11 +794,6 @@ class MATERIAL_PT_options(MaterialButtonsPanel, Panel):
row.prop(mat, "use_light_group_local", text="Local")
col = split.column()
col.prop(mat, "use_face_texture")
sub = col.column()
sub.active = mat.use_face_texture
sub.prop(mat, "use_face_texture_alpha")
col.separator()
col.prop(mat, "use_vertex_color_paint")
col.prop(mat, "use_vertex_color_light")
col.prop(mat, "use_object_color")
@ -806,6 +801,9 @@ class MATERIAL_PT_options(MaterialButtonsPanel, Panel):
if simple_material(base_mat):
col.prop(mat, "pass_index")
col.label("Edit Image")
col.template_ID(mat, "edit_image")
class MATERIAL_PT_shadow(MaterialButtonsPanel, Panel):
bl_label = "Shadow"

View File

@ -86,6 +86,10 @@ short BKE_object_material_slot_find_index(struct Object *ob, struct Material *ma
bool BKE_object_material_slot_add(struct Object *ob);
bool BKE_object_material_slot_remove(struct Object *ob);
struct Image *BKE_object_material_edit_image_get(struct Object *ob, short mat_nr);
struct Image **BKE_object_material_edit_image_get_array(struct Object *ob);
bool BKE_object_material_edit_image_set(struct Object *ob, short mat_nr, struct Image *image);
void BKE_texpaint_slot_refresh_cache(struct Scene *scene, struct Material *ma);
void BKE_texpaint_slots_refresh_object(struct Scene *scene, struct Object *ob);
@ -114,9 +118,6 @@ void free_matcopybuf(void);
void copy_matcopybuf(struct Material *ma);
void paste_matcopybuf(struct Material *ma);
/* handle backward compatibility for tface/materials called from doversion */
int do_version_tface(struct Main *main);
#ifdef __cplusplus
}
#endif

View File

@ -419,7 +419,7 @@ static void layerSwap_tface(void *data, const int *corner_indices)
static void layerDefault_tface(void *data, int count)
{
static MTFace default_tf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}, NULL,
static MTFace default_tf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}},
0, 0, TF_DYNAMIC | TF_CONVERTED, 0, 0};
MTFace *tf = (MTFace *)data;
int i;

View File

@ -643,31 +643,6 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
for (i = 0; i < mesh->totcol; i++) {
CALLBACK_INVOKE(mesh->mat[i], IDWALK_CB_USER);
}
/* XXX Really not happy with this - probably texface should rather use some kind of
* 'texture slots' and just set indices in each poly/face item - would also save some memory.
* Maybe a nice TODO for blender2.8? */
if (mesh->mtface || mesh->mtpoly) {
for (i = 0; i < mesh->pdata.totlayer; i++) {
if (mesh->pdata.layers[i].type == CD_MTEXPOLY) {
MTexPoly *txface = (MTexPoly *)mesh->pdata.layers[i].data;
for (int j = 0; j < mesh->totpoly; j++, txface++) {
CALLBACK_INVOKE(txface->tpage, IDWALK_CB_USER_ONE);
}
}
}
for (i = 0; i < mesh->fdata.totlayer; i++) {
if (mesh->fdata.layers[i].type == CD_MTFACE) {
MTFace *tface = (MTFace *)mesh->fdata.layers[i].data;
for (int j = 0; j < mesh->totface; j++, tface++) {
CALLBACK_INVOKE(tface->tpage, IDWALK_CB_USER_ONE);
}
}
}
}
break;
}
@ -710,6 +685,7 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
library_foreach_ID_as_subdata_link((ID **)&material->nodetree, callback, user_data, flag, &data);
}
CALLBACK_INVOKE(material->group, IDWALK_CB_USER);
CALLBACK_INVOKE(material->edit_image, IDWALK_CB_USER);
break;
}

View File

@ -229,6 +229,7 @@ Material *BKE_material_copy(Main *bmain, Material *ma)
man = BKE_libblock_copy(bmain, &ma->id);
id_lib_extern((ID *)man->group);
id_lib_extern((ID *)man->edit_image);
for (a = 0; a < MAX_MTEX; a++) {
if (ma->mtex[a]) {
@ -944,7 +945,7 @@ static void do_init_render_material(Material *ma, int r_mode, float *amb)
if (needtang) ma->mode |= MA_NORMAP_TANG;
else ma->mode &= ~MA_NORMAP_TANG;
if (ma->mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE)) {
if (ma->mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) {
needuv = 1;
if (r_mode & R_OSA) ma->texco |= TEXCO_OSA; /* for texfaces */
}
@ -1767,501 +1768,30 @@ void paste_matcopybuf(Material *ma)
ma->nodetree = ntreeCopyTree_ex(matcopybuf.nodetree, G.main, false);
}
/*********************** texface to material convert functions **********************/
/* encode all the TF information into a single int */
static int encode_tfaceflag(MTFace *tf, int convertall)
struct Image *BKE_object_material_edit_image_get(Object *ob, short mat_nr)
{
/* calculate the flag */
int flag = tf->mode;
Material *ma = give_current_material(ob, mat_nr + 1);
return ma ? ma->edit_image : NULL;
}
/* options that change the material offline render */
if (!convertall) {
flag &= ~TF_OBCOL;
struct Image **BKE_object_material_edit_image_get_array(Object *ob)
{
Image **image_array = MEM_mallocN(sizeof(Material *) * ob->totcol, __func__);
for (int i = 0; i < ob->totcol; i++) {
image_array[i] = BKE_object_material_edit_image_get(ob, i);
}
/* clean flags that are not being converted */
flag &= ~TF_TEX;
flag &= ~TF_SHAREDVERT;
flag &= ~TF_SHAREDCOL;
flag &= ~TF_CONVERTED;
/* light tface flag is ignored in GLSL mode */
flag &= ~TF_LIGHT;
/* 15 is how big the flag can be - hardcoded here and in decode_tfaceflag() */
flag |= tf->transp << 15;
/* increase 1 so flag 0 is different than no flag yet */
return flag + 1;
return image_array;
}
/* set the material options based in the tface flag */
static void decode_tfaceflag(Material *ma, int flag, int convertall)
bool BKE_object_material_edit_image_set(Object *ob, short mat_nr, Image *image)
{
int alphablend;
GameSettings *game = &ma->game;
/* flag is shifted in 1 to make 0 != no flag yet (see encode_tfaceflag) */
flag -= 1;
alphablend = flag >> 15; /* encoded in the encode_tfaceflag function */
(*game).flag = 0;
/* General Material Options */
if ((flag & TF_DYNAMIC) == 0) (*game).flag |= GEMAT_NOPHYSICS;
/* Material Offline Rendering Properties */
if (convertall) {
if (flag & TF_OBCOL) ma->shade_flag |= MA_OBCOLOR;
Material *ma = give_current_material(ob, mat_nr + 1);
if (ma) {
/* both may be NULL */
id_us_min((ID *)ma->edit_image);
ma->edit_image = image;
id_us_plus((ID *)ma->edit_image);
return true;
}
/* Special Face Properties */
if ((flag & TF_TWOSIDE) == 0) (*game).flag |= GEMAT_BACKCULL;
if (flag & TF_INVISIBLE) (*game).flag |= GEMAT_INVISIBLE;
if (flag & TF_BMFONT) (*game).flag |= GEMAT_TEXT;
/* Face Orientation */
if (flag & TF_BILLBOARD) (*game).face_orientation |= GEMAT_HALO;
else if (flag & TF_BILLBOARD2) (*game).face_orientation |= GEMAT_BILLBOARD;
else if (flag & TF_SHADOW) (*game).face_orientation |= GEMAT_SHADOW;
/* Alpha Blend */
if (flag & TF_ALPHASORT && ELEM(alphablend, TF_ALPHA, TF_ADD)) (*game).alpha_blend = GEMAT_ALPHA_SORT;
else if (alphablend & TF_ALPHA) (*game).alpha_blend = GEMAT_ALPHA;
else if (alphablend & TF_ADD) (*game).alpha_blend = GEMAT_ADD;
else if (alphablend & TF_CLIP) (*game).alpha_blend = GEMAT_CLIP;
return false;
}
/* boolean check to see if the mesh needs a material */
static int check_tfaceneedmaterial(int flag)
{
/* check if the flags we have are not deprecated != than default material options
* also if only flags are visible and collision see if all objects using this mesh have this option in physics */
/* flag is shifted in 1 to make 0 != no flag yet (see encode_tfaceflag) */
flag -= 1;
/* deprecated flags */
flag &= ~TF_OBCOL;
flag &= ~TF_SHAREDVERT;
flag &= ~TF_SHAREDCOL;
/* light tface flag is ignored in GLSL mode */
flag &= ~TF_LIGHT;
/* automatic detected if tex image has alpha */
flag &= ~(TF_ALPHA << 15);
/* automatic detected if using texture */
flag &= ~TF_TEX;
/* settings for the default NoMaterial */
if (flag == TF_DYNAMIC)
return 0;
else
return 1;
}
/* return number of digits of an integer */
/* XXX to be optmized or replaced by an equivalent blender internal function */
static int integer_getdigits(int number)
{
int i = 0;
if (number == 0) return 1;
while (number != 0) {
number = (int)(number / 10);
i++;
}
return i;
}
static void calculate_tface_materialname(char *matname, char *newname, int flag)
{
/* if flag has only light and collision and material matches those values
* you can do strcpy(name, mat_name);
* otherwise do: */
int digits = integer_getdigits(flag);
/* clamp the old name, remove the MA prefix and add the .TF.flag suffix
* e.g. matname = "MALoooooooooooooongName"; newname = "Loooooooooooooon.TF.2" */
BLI_snprintf(newname, MAX_ID_NAME, "%.*s.TF.%0*d", MAX_ID_NAME - (digits + 5), matname, digits, flag);
}
/* returns -1 if no match */
static short mesh_getmaterialnumber(Mesh *me, Material *ma)
{
short a;
for (a = 0; a < me->totcol; a++) {
if (me->mat[a] == ma) {
return a;
}
}
return -1;
}
/* append material */
static short mesh_addmaterial(Mesh *me, Material *ma)
{
BKE_material_append_id(G.main, &me->id, NULL);
me->mat[me->totcol - 1] = ma;
id_us_plus(&ma->id);
return me->totcol - 1;
}
static void set_facetexture_flags(Material *ma, Image *image)
{
if (image) {
ma->mode |= MA_FACETEXTURE;
/* we could check if the texture has alpha, but then more meshes sharing the same
* material may need it. Let's make it simple. */
if (BKE_image_has_alpha(image))
ma->mode |= MA_FACETEXTURE_ALPHA;
}
}
/* returns material number */
static short convert_tfacenomaterial(Main *main, Mesh *me, MTFace *tf, int flag)
{
Material *ma;
char idname[MAX_ID_NAME];
short mat_nr = -1;
/* new material, the name uses the flag*/
BLI_snprintf(idname, sizeof(idname), "MAMaterial.TF.%0*d", integer_getdigits(flag), flag);
if ((ma = BLI_findstring(&main->mat, idname + 2, offsetof(ID, name) + 2))) {
mat_nr = mesh_getmaterialnumber(me, ma);
/* assign the material to the mesh */
if (mat_nr == -1) mat_nr = mesh_addmaterial(me, ma);
/* if needed set "Face Textures [Alpha]" Material options */
set_facetexture_flags(ma, tf->tpage);
}
/* create a new material */
else {
ma = BKE_material_add(main, idname + 2);
if (ma) {
printf("TexFace Convert: Material \"%s\" created.\n", idname + 2);
mat_nr = mesh_addmaterial(me, ma);
/* if needed set "Face Textures [Alpha]" Material options */
set_facetexture_flags(ma, tf->tpage);
decode_tfaceflag(ma, flag, 1);
/* the final decoding will happen after, outside the main loop
* for now store the flag into the material and change light/tex/collision
* store the flag as a negative number */
ma->game.flag = -flag;
id_us_min((ID *)ma);
}
else {
printf("Error: Unable to create Material \"%s\" for Mesh \"%s\".", idname + 2, me->id.name + 2);
}
}
/* set as converted, no need to go bad to this face */
tf->mode |= TF_CONVERTED;
return mat_nr;
}
/* Function to fully convert materials */
static void convert_tfacematerial(Main *main, Material *ma)
{
Mesh *me;
Material *mat_new;
MFace *mf;
MTFace *tf;
int flag, index;
int a;
short mat_nr;
CustomDataLayer *cdl;
char idname[MAX_ID_NAME];
for (me = main->mesh.first; me; me = me->id.next) {
/* check if this mesh uses this material */
for (a = 0; a < me->totcol; a++)
if (me->mat[a] == ma) break;
/* no material found */
if (a == me->totcol) continue;
/* get the active tface layer */
index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
cdl = (index == -1) ? NULL : &me->fdata.layers[index];
if (!cdl) continue;
/* loop over all the faces and stop at the ones that use the material*/
for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
if (me->mat[mf->mat_nr] != ma) continue;
/* texface data for this face */
tf = ((MTFace *)cdl->data) + a;
flag = encode_tfaceflag(tf, 1);
/* the name of the new material */
calculate_tface_materialname(ma->id.name, (char *)&idname, flag);
if ((mat_new = BLI_findstring(&main->mat, idname + 2, offsetof(ID, name) + 2))) {
/* material already existent, see if the mesh has it */
mat_nr = mesh_getmaterialnumber(me, mat_new);
/* material is not in the mesh, add it */
if (mat_nr == -1) mat_nr = mesh_addmaterial(me, mat_new);
}
/* create a new material */
else {
mat_new = BKE_material_copy(main, ma);
if (mat_new) {
/* rename the material*/
BLI_strncpy(mat_new->id.name, idname, sizeof(mat_new->id.name));
id_us_min((ID *)mat_new);
mat_nr = mesh_addmaterial(me, mat_new);
decode_tfaceflag(mat_new, flag, 1);
}
else {
printf("Error: Unable to create Material \"%s\" for Mesh \"%s.", idname + 2, me->id.name + 2);
mat_nr = mf->mat_nr;
continue;
}
}
/* if the material has a texture but no texture channel
* set "Face Textures [Alpha]" Material options
* actually we need to run it always, because of old behavior
* of using face texture if any texture channel was present (multitex) */
//if ((!mat_new->mtex[0]) && (!mat_new->mtex[0]->tex))
set_facetexture_flags(mat_new, tf->tpage);
/* set the material number to the face*/
mf->mat_nr = mat_nr;
}
/* remove material from mesh */
for (a = 0; a < me->totcol; ) {
if (me->mat[a] == ma) {
BKE_material_pop_id(main, &me->id, a, true);
}
else {
a++;
}
}
}
}
#define MAT_BGE_DISPUTED -99999
int do_version_tface(Main *main)
{
Mesh *me;
Material *ma;
MFace *mf;
MTFace *tf;
CustomDataLayer *cdl;
int a;
int flag;
int index;
/* Operator in help menu has been removed for 2.7x */
int fileload = 1;
/* sometimes mesh has no materials but will need a new one. In those
* cases we need to ignore the mf->mat_nr and only look at the face
* mode because it can be zero as uninitialized or the 1st created material
*/
int nomaterialslots;
/* alert to user to check the console */
int nowarning = 1;
/* mark all the materials to conversion with a flag
* if there is tface create a complete flag for that storing in flag
* if there is tface and flag > 0: creates a new flag based on this face
* if flags are different set flag to -1
*/
/* 1st part: marking mesh materials to update */
for (me = main->mesh.first; me; me = me->id.next) {
if (ID_IS_LINKED_DATABLOCK(me)) continue;
/* get the active tface layer */
index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
cdl = (index == -1) ? NULL : &me->fdata.layers[index];
if (!cdl) continue;
nomaterialslots = (me->totcol == 0 ? 1 : 0);
/* loop over all the faces*/
for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
/* texface data for this face */
tf = ((MTFace *)cdl->data) + a;
/* conversion should happen only once */
if (fileload)
tf->mode &= ~TF_CONVERTED;
else {
if ((tf->mode & TF_CONVERTED)) continue;
else tf->mode |= TF_CONVERTED;
}
/* no material slots */
if (nomaterialslots) {
flag = encode_tfaceflag(tf, 1);
/* create/find a new material and assign to the face */
if (check_tfaceneedmaterial(flag)) {
mf->mat_nr = convert_tfacenomaterial(main, me, tf, flag);
}
/* else mark them as no-material to be reverted to 0 later */
else {
mf->mat_nr = -1;
}
}
else if (mf->mat_nr < me->totcol) {
ma = me->mat[mf->mat_nr];
/* no material create one if necessary */
if (!ma) {
/* find a new material and assign to the face */
flag = encode_tfaceflag(tf, 1);
/* create/find a new material and assign to the face */
if (check_tfaceneedmaterial(flag))
mf->mat_nr = convert_tfacenomaterial(main, me, tf, flag);
continue;
}
/* we can't read from this if it comes from a library,
* at doversion time: direct_link might not have happened on it,
* so ma->mtex is not pointing to valid memory yet.
* later we could, but it's better not */
else if (ID_IS_LINKED_DATABLOCK(ma))
continue;
/* material already marked as disputed */
else if (ma->game.flag == MAT_BGE_DISPUTED)
continue;
/* found a material */
else {
flag = encode_tfaceflag(tf, ((fileload) ? 0 : 1));
/* first time changing this material */
if (ma->game.flag == 0)
ma->game.flag = -flag;
/* mark material as disputed */
else if (ma->game.flag != -flag) {
ma->game.flag = MAT_BGE_DISPUTED;
continue;
}
/* material ok so far */
else {
ma->game.flag = -flag;
/* some people uses multitexture with TexFace by creating a texture
* channel which not necessarily the tf->tpage image. But the game engine
* was enabling it. Now it's required to set "Face Texture [Alpha] in the
* material settings. */
if (!fileload)
set_facetexture_flags(ma, tf->tpage);
}
}
}
else {
continue;
}
}
/* if we didn't have material slot and now we do, we need to
* make sure the materials are correct */
if (nomaterialslots) {
if (me->totcol > 0) {
for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
if (mf->mat_nr == -1) {
/* texface data for this face */
tf = ((MTFace *)cdl->data) + a;
mf->mat_nr = convert_tfacenomaterial(main, me, tf, encode_tfaceflag(tf, 1));
}
}
}
else {
for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
mf->mat_nr = 0;
}
}
}
}
/* 2nd part - conversion */
/* skip library files */
/* we shouldn't loop through the materials created in the loop. make the loop stop at its original length) */
for (ma = main->mat.first, a = 0; ma; ma = ma->id.next, a++) {
if (ID_IS_LINKED_DATABLOCK(ma)) continue;
/* disputed material */
if (ma->game.flag == MAT_BGE_DISPUTED) {
ma->game.flag = 0;
if (fileload) {
printf("Warning: material \"%s\" skipped.\n", ma->id.name + 2);
nowarning = 0;
}
else {
convert_tfacematerial(main, ma);
}
continue;
}
/* no conflicts in this material - 90% of cases
* convert from tface system to material */
else if (ma->game.flag < 0) {
decode_tfaceflag(ma, -(ma->game.flag), 1);
/* material is good make sure all faces using
* this material are set to converted */
if (fileload) {
for (me = main->mesh.first; me; me = me->id.next) {
/* check if this mesh uses this material */
for (a = 0; a < me->totcol; a++)
if (me->mat[a] == ma) break;
/* no material found */
if (a == me->totcol) continue;
/* get the active tface layer */
index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
cdl = (index == -1) ? NULL : &me->fdata.layers[index];
if (!cdl) continue;
/* loop over all the faces and stop at the ones that use the material*/
for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
if (me->mat[mf->mat_nr] == ma) {
/* texface data for this face */
tf = ((MTFace *)cdl->data) + a;
tf->mode |= TF_CONVERTED;
}
}
}
}
}
/* material is not used by faces with texface
* set the default flag - do it only once */
else {
if (fileload) {
ma->game.flag = GEMAT_BACKCULL;
}
}
}
return nowarning;
}

View File

@ -241,7 +241,6 @@ typedef struct OldNewMap {
/* local prototypes */
static void *read_struct(FileData *fd, BHead *bh, const char *blockname);
static void direct_link_modifiers(FileData *fd, ListBase *lb);
static void convert_tface_mt(FileData *fd, Main *main);
static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name);
static BHead *find_bhead_from_idname(FileData *fd, const char *idname);
@ -4380,49 +4379,6 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
/* ************ READ MESH ***************** */
static void lib_link_mtface(FileData *fd, Mesh *me, MTFace *mtface, int totface)
{
MTFace *tf= mtface;
int i;
/* Add pseudo-references (not fake users!) to images used by texface. A
* little bogus; it would be better if each mesh consistently added one ref
* to each image it used. - z0r */
for (i = 0; i < totface; i++, tf++) {
tf->tpage = newlibadr_real_us(fd, me->id.lib, tf->tpage);
}
}
static void lib_link_customdata_mtface(FileData *fd, Mesh *me, CustomData *fdata, int totface)
{
int i;
for (i = 0; i < fdata->totlayer; i++) {
CustomDataLayer *layer = &fdata->layers[i];
if (layer->type == CD_MTFACE)
lib_link_mtface(fd, me, layer->data, totface);
}
}
static void lib_link_customdata_mtpoly(FileData *fd, Mesh *me, CustomData *pdata, int totface)
{
int i;
for (i=0; i < pdata->totlayer; i++) {
CustomDataLayer *layer = &pdata->layers[i];
if (layer->type == CD_MTEXPOLY) {
MTexPoly *tf= layer->data;
int j;
for (j = 0; j < totface; j++, tf++) {
tf->tpage = newlibadr_real_us(fd, me->id.lib, tf->tpage);
}
}
}
}
static void lib_link_mesh(FileData *fd, Main *main)
{
Mesh *me;
@ -4449,19 +4405,9 @@ static void lib_link_mesh(FileData *fd, Main *main)
me->ipo = newlibadr_us(fd, me->id.lib, me->ipo); // XXX: deprecated: old anim sys
me->key = newlibadr_us(fd, me->id.lib, me->key);
me->texcomesh = newlibadr_us(fd, me->id.lib, me->texcomesh);
lib_link_customdata_mtface(fd, me, &me->fdata, me->totface);
lib_link_customdata_mtpoly(fd, me, &me->pdata, me->totpoly);
if (me->mr && me->mr->levels.first) {
lib_link_customdata_mtface(fd, me, &me->mr->fdata,
((MultiresLevel*)me->mr->levels.first)->totface);
}
}
}
/* convert texface options to material */
convert_tface_mt(fd, main);
for (me = main->mesh.first; me; me = me->id.next) {
if (me->id.tag & LIB_TAG_NEED_LINK) {
/*check if we need to convert mfaces to mpolys*/
@ -8523,26 +8469,6 @@ static void link_global(FileData *fd, BlendFileData *bfd)
}
}
static void convert_tface_mt(FileData *fd, Main *main)
{
Main *gmain;
/* this is a delayed do_version (so it can create new materials) */
if (main->versionfile < 259 || (main->versionfile == 259 && main->subversionfile < 3)) {
//XXX hack, material.c uses G.main all over the place, instead of main
// temporarily set G.main to the current main
gmain = G.main;
G.main = main;
if (!(do_version_tface(main))) {
BKE_report(fd->reports, RPT_WARNING, "Texface conversion problem (see error in console)");
}
//XXX hack, material.c uses G.main allover the place, instead of main
G.main = gmain;
}
}
/* initialize userdef with non-UI dependency stuff */
/* other initializers (such as theme color defaults) go to resources.c */
static void do_versions_userdef(FileData *fd, BlendFileData *bfd)
@ -9354,6 +9280,10 @@ static void expand_material(FileData *fd, Main *mainvar, Material *ma)
if (ma->group)
expand_doit(fd, mainvar, ma->group);
if (ma->edit_image) {
expand_doit(fd, mainvar, ma->edit_image);
}
}
static void expand_lamp(FileData *fd, Main *mainvar, Lamp *la)
@ -9443,9 +9373,7 @@ static void expand_curve(FileData *fd, Main *mainvar, Curve *cu)
static void expand_mesh(FileData *fd, Main *mainvar, Mesh *me)
{
CustomDataLayer *layer;
TFace *tf;
int a, i;
int a;
if (me->adt)
expand_animdata(fd, mainvar, me->adt);
@ -9456,46 +9384,6 @@ static void expand_mesh(FileData *fd, Main *mainvar, Mesh *me)
expand_doit(fd, mainvar, me->key);
expand_doit(fd, mainvar, me->texcomesh);
if (me->tface) {
tf = me->tface;
for (i=0; i<me->totface; i++, tf++) {
if (tf->tpage)
expand_doit(fd, mainvar, tf->tpage);
}
}
if (me->mface && !me->mpoly) {
MTFace *mtf;
for (a = 0; a < me->fdata.totlayer; a++) {
layer = &me->fdata.layers[a];
if (layer->type == CD_MTFACE) {
mtf = (MTFace *) layer->data;
for (i = 0; i < me->totface; i++, mtf++) {
if (mtf->tpage)
expand_doit(fd, mainvar, mtf->tpage);
}
}
}
}
else {
MTexPoly *mtp;
for (a = 0; a < me->pdata.totlayer; a++) {
layer = &me->pdata.layers[a];
if (layer->type == CD_MTEXPOLY) {
mtp = (MTexPoly *) layer->data;
for (i = 0; i < me->totpoly; i++, mtp++) {
if (mtp->tpage)
expand_doit(fd, mainvar, mtp->tpage);
}
}
}
}
}
/* temp struct used to transport needed info to expand_constraint_cb() */

View File

@ -408,7 +408,6 @@ static void customdata_version_242(Mesh *me)
mtf->unwrap = tf->unwrap;
mtf->mode = tf->mode;
mtf->tile = tf->tile;
mtf->tpage = tf->tpage;
mtf->transp = tf->transp;
}

View File

@ -77,7 +77,6 @@ enum {
/* similar face selection slot values */
enum {
SIMFACE_MATERIAL = 201,
SIMFACE_IMAGE,
SIMFACE_AREA,
SIMFACE_SIDES,
SIMFACE_PERIMETER,

View File

@ -145,7 +145,7 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
* Save us some computation burden: In case of perimeter/area/coplanar selection we compute
* only once.
*/
if (type == SIMFACE_PERIMETER || type == SIMFACE_AREA || type == SIMFACE_COPLANAR || type == SIMFACE_IMAGE) {
if (type == SIMFACE_PERIMETER || type == SIMFACE_AREA || type == SIMFACE_COPLANAR) {
for (i = 0; i < num_total; i++) {
switch (type) {
case SIMFACE_PERIMETER:
@ -164,14 +164,6 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
case SIMFACE_AREA:
f_ext[i].area = BM_face_calc_area(f_ext[i].f);
break;
case SIMFACE_IMAGE:
f_ext[i].t = NULL;
if (CustomData_has_layer(&(bm->pdata), CD_MTEXPOLY)) {
MTexPoly *mtpoly = CustomData_bmesh_get(&bm->pdata, f_ext[i].f->head.data, CD_MTEXPOLY);
f_ext[i].t = mtpoly->tpage;
}
break;
}
}
}
@ -191,13 +183,6 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
}
break;
case SIMFACE_IMAGE:
if (f_ext[i].t == f_ext[indices[idx]].t) {
BMO_face_flag_enable(bm, fm, FACE_MARK);
cont = false;
}
break;
case SIMFACE_NORMAL:
angle = angle_normalized_v3v3(fs->no, fm->no); /* if the angle between the normals -> 0 */
if (angle <= thresh_radians) {

View File

@ -311,58 +311,6 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
}
}
int active_uv_layer = -1;
std::set<Image *> uv_textures;
if (ob->type == OB_MESH && ob->totcol && this->export_settings->include_uv_textures) {
bool active_uv_only = this->export_settings->active_uv_only;
Mesh *me = (Mesh *) ob->data;
active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY);
BKE_mesh_tessface_ensure(me);
for (int i = 0; i < me->pdata.totlayer; i++) {
if (!active_uv_only || active_uv_layer == i)
{
if (me->pdata.layers[i].type == CD_MTEXPOLY) {
MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data;
MPoly *mpoly = me->mpoly;
for (int j = 0; j < me->totpoly; j++, mpoly++, txface++) {
Material *mat = give_current_material(ob, mpoly->mat_nr + 1);
if (mat != ma)
continue;
Image *ima = txface->tpage;
if (ima == NULL)
continue;
bool not_in_list = uv_textures.find(ima)==uv_textures.end();
if (not_in_list) {
std::string name = id_name(ima);
std::string key(name);
key = translate_id(key);
// create only one <sampler>/<surface> pair for each unique image
if (im_samp_map.find(key) == im_samp_map.end()) {
//<newparam> <sampler> <source>
COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D,
key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX,
key + COLLADASW::Sampler::SURFACE_SID_SUFFIX);
sampler.setImageId(key);
samplers[a] = sampler;
samp_surf[b] = &samplers[a];
im_samp_map[key] = b;
b++;
a++;
uv_textures.insert(ima);
}
}
}
}
}
}
}
// used as fallback when MTex->uvname is "" (this is pretty common)
// it is indeed the correct value to use in that case
std::string active_uv(getActiveUVLayerName(ob));
@ -385,19 +333,6 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
writeTextures(ep, key, sampler, t, ima, uvname);
}
std::set<Image *>::iterator uv_t_iter;
int idx;
for (idx = 0, uv_t_iter = uv_textures.begin(); uv_t_iter != uv_textures.end(); uv_t_iter++, idx++ ) {
if (active_uv_layer>-1 && idx==active_uv_layer) {
Image *ima = *uv_t_iter;
std::string key(id_name(ima));
key = translate_id(key);
int i = im_samp_map[key];
COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i];
ep.setDiffuse(createTexture(ima, active_uv, sampler), false, "diffuse");
}
}
// performs the actual writing
ep.addProfileElements();
bool twoSided = false;

View File

@ -42,7 +42,6 @@ public:
bool deform_bones_only;
bool active_uv_only;
bool include_uv_textures;
bool include_material_textures;
bool use_texture_copies;

View File

@ -152,44 +152,6 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
}
}
void ImagesExporter::export_UV_Images()
{
std::set<Image *> uv_textures;
LinkNode *node;
bool use_texture_copies = this->export_settings->use_texture_copies;
bool active_uv_only = this->export_settings->active_uv_only;
for (node = this->export_settings->export_set; node; node = node->next) {
Object *ob = (Object *)node->link;
if (ob->type == OB_MESH && ob->totcol) {
Mesh *me = (Mesh *) ob->data;
BKE_mesh_tessface_ensure(me);
int active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY);
for (int i = 0; i < me->pdata.totlayer; i++) {
if (me->pdata.layers[i].type == CD_MTEXPOLY) {
if (!active_uv_only || active_uv_layer == i)
{
MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data;
for (int j = 0; j < me->totpoly; j++, txface++) {
Image *ima = txface->tpage;
if (ima == NULL)
continue;
bool not_in_list = uv_textures.find(ima) == uv_textures.end();
if (not_in_list) {
uv_textures.insert(ima);
export_UV_Image(ima, use_texture_copies);
}
}
}
}
}
}
}
}
bool ImagesExporter::hasImages(Scene *sce)
{
LinkNode *node;
@ -209,20 +171,6 @@ bool ImagesExporter::hasImages(Scene *sce)
}
}
if (ob->type == OB_MESH) {
Mesh *me = (Mesh *) ob->data;
BKE_mesh_tessface_ensure(me);
bool has_uvs = (bool)CustomData_has_layer(&me->fdata, CD_MTFACE);
if (has_uvs) {
int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
for (int a = 0; a < num_layers; a++) {
MTFace *tface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, a);
Image *img = tface->tpage;
if (img) return true;
}
}
}
}
return false;
}
@ -236,10 +184,6 @@ void ImagesExporter::exportImages(Scene *sce)
mf.forEachMaterialInExportSet<ImagesExporter>(sce, *this, this->export_settings->export_set);
}
if (this->export_settings->include_uv_textures) {
export_UV_Images();
}
closeLibrary();
}

View File

@ -51,7 +51,6 @@ public:
private:
std::vector<std::string> mImages; // contains list of written images, to avoid duplicates
void export_UV_Images();
void export_UV_Image(Image *image, bool use_texture_copies);
bool hasImages(Scene *sce);
const ExportSettings *export_settings;

View File

@ -1051,11 +1051,11 @@ void MeshImporter::optimize_material_assignements()
* which materials shall be moved to the created geometries. Also see
* optimize_material_assignements() above.
*/
MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial,
std::map<COLLADAFW::UniqueId, Material *>& uid_material_map,
Object *ob, const COLLADAFW::UniqueId *geom_uid,
char *layername, MTFace *texture_face,
std::map<Material *, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index)
void MeshImporter::assign_material_to_geom(
COLLADAFW::MaterialBinding cmaterial,
std::map<COLLADAFW::UniqueId, Material *>& uid_material_map,
Object *ob, const COLLADAFW::UniqueId *geom_uid,
std::map<Material *, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index)
{
MTex *color_texture = NULL;
Mesh *me = (Mesh *)ob->data;
@ -1089,15 +1089,6 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri
color_texture);
}
// set texture face
if (color_texture &&
strlen((color_texture)->uvname) &&
!STREQ(layername, color_texture->uvname)) {
texture_face = (MTFace *)CustomData_get_layer_named(&me->fdata, CD_MTFACE,
color_texture->uvname);
strcpy(layername, color_texture->uvname);
}
MaterialIdPrimitiveArrayMap& mat_prim_map = geom_uid_mat_mapping_map[*geom_uid];
COLLADAFW::MaterialId mat_id = cmaterial.getMaterialId();
@ -1114,15 +1105,9 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri
for (i = 0; i < prim.totpoly; i++, mpoly++) {
mpoly->mat_nr = mat_index;
// bind texture images to faces
if (texture_face && color_texture) {
texture_face->tpage = (Image *)color_texture->tex->ima;
texture_face++;
}
}
}
}
return texture_face;
}
Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom,
@ -1175,10 +1160,6 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta
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();
@ -1186,9 +1167,9 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta
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);
assign_material_to_geom(
mat_array[i], uid_material_map, ob, geom_uid,
material_texture_mapping_map, i);
}
else {
fprintf(stderr, "invalid referenced material for %s\n", mat_array[i].getName().c_str());

View File

@ -171,11 +171,11 @@ public:
void optimize_material_assignements();
MTFace *assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial,
std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
Object *ob, const COLLADAFW::UniqueId *geom_uid,
char *layername, MTFace *texture_face,
std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index);
void assign_material_to_geom(
COLLADAFW::MaterialBinding cmaterial,
std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
Object *ob, const COLLADAFW::UniqueId *geom_uid,
std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index);
Object *create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom,

View File

@ -81,7 +81,6 @@ int collada_export(Scene *sce,
int deform_bones_only,
int active_uv_only,
int include_uv_textures,
int include_material_textures,
int use_texture_copies,
@ -107,7 +106,6 @@ int collada_export(Scene *sce,
export_settings.deform_bones_only = deform_bones_only != 0;
export_settings.active_uv_only = active_uv_only != 0;
export_settings.include_uv_textures = include_uv_textures != 0;
export_settings.include_material_textures= include_material_textures != 0;
export_settings.use_texture_copies = use_texture_copies != 0;

View File

@ -76,7 +76,6 @@ int collada_export(struct Scene *sce,
int deform_bones_only,
int active_uv_only,
int include_uv_textures,
int include_material_textures,
int use_texture_copies,

View File

@ -62,7 +62,7 @@ void ED_object_assign_active_image(struct Main *bmain, struct Object *ob, int ma
bool ED_uvedit_test(struct Object *obedit);
/* visibility and selection */
bool uvedit_face_visible_test(struct Scene *scene, struct Image *ima, struct BMFace *efa, struct MTexPoly *tf);
bool uvedit_face_visible_test(struct Scene *scene, struct Image *ima, struct BMFace *efa);
bool uvedit_face_select_test(struct Scene *scene, struct BMFace *efa,
const int cd_loop_uv_offset);
bool uvedit_edge_select_test(struct Scene *scene, struct BMLoop *l,

View File

@ -87,7 +87,6 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
int include_shapekeys;
int deform_bones_only;
int include_uv_textures;
int include_material_textures;
int use_texture_copies;
int active_uv_only;
@ -139,7 +138,6 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
include_shapekeys = RNA_boolean_get(op->ptr, "include_shapekeys");
deform_bones_only = RNA_boolean_get(op->ptr, "deform_bones_only");
include_uv_textures = RNA_boolean_get(op->ptr, "include_uv_textures");
include_material_textures = RNA_boolean_get(op->ptr, "include_material_textures");
use_texture_copies = RNA_boolean_get(op->ptr, "use_texture_copies");
active_uv_only = RNA_boolean_get(op->ptr, "active_uv_only");
@ -170,7 +168,6 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
deform_bones_only,
active_uv_only,
include_uv_textures,
include_material_textures,
use_texture_copies,
@ -241,9 +238,6 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "active_uv_only", 0, NULL, ICON_NONE);
row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "include_uv_textures", 0, NULL, ICON_NONE);
row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "include_material_textures", 0, NULL, ICON_NONE);
@ -373,9 +367,6 @@ void WM_OT_collada_export(wmOperatorType *ot)
RNA_def_boolean(func, "active_uv_only", 0, "Only Selected UV Map",
"Export only the selected UV Map");
RNA_def_boolean(func, "include_uv_textures", 0, "Include UV Textures",
"Export textures assigned to the object UV Maps");
RNA_def_boolean(func, "include_material_textures", 0, "Include Material Textures",
"Export textures assigned to the object Materials");

View File

@ -985,7 +985,6 @@ static EnumPropertyItem prop_similar_types[] = {
#endif
{SIMFACE_MATERIAL, "MATERIAL", 0, "Material", ""},
{SIMFACE_IMAGE, "IMAGE", 0, "Image", ""},
{SIMFACE_AREA, "AREA", 0, "Area", ""},
{SIMFACE_SIDES, "SIDES", 0, "Polygon Sides", ""},
{SIMFACE_PERIMETER, "PERIMETER", 0, "Perimeter", ""},

View File

@ -52,6 +52,7 @@
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_multires.h"
#include "BKE_report.h"
#include "BKE_cdderivedmesh.h"
@ -86,6 +87,11 @@
* needed to make job totally thread-safe */
typedef struct MultiresBakerJobData {
struct MultiresBakerJobData *next, *prev;
/* material aligned image array (for per-face bake image) */
struct {
Image **array;
int len;
} ob_image;
DerivedMesh *lores_dm, *hires_dm;
bool simple;
int lvl, tot_lvl;
@ -160,7 +166,7 @@ static bool multiresbake_check(bContext *C, wmOperator *op)
else {
a = me->totpoly;
while (ok && a--) {
Image *ima = me->mtpoly[a].tpage;
Image *ima = BKE_object_material_edit_image_get(ob, me->mpoly[a].mat_nr);
if (!ima) {
BKE_report(op->reports, RPT_ERROR, "You should have active texture to use multires baker");
@ -283,20 +289,27 @@ static void clear_single_image(Image *image, ClearFlag flag)
}
}
static void clear_images_poly(MTexPoly *mtpoly, int totpoly, ClearFlag flag)
static void clear_images_poly(Image **ob_image_array, int ob_image_array_len, ClearFlag flag)
{
int a;
for (a = 0; a < totpoly; a++) {
mtpoly[a].tpage->id.tag &= ~LIB_TAG_DOIT;
for (int i = 0; i < ob_image_array_len; i++) {
Image *image = ob_image_array[i];
if (image) {
image->id.tag &= ~LIB_TAG_DOIT;
}
}
for (a = 0; a < totpoly; a++) {
clear_single_image(mtpoly[a].tpage, flag);
for (int i = 0; i < ob_image_array_len; i++) {
Image *image = ob_image_array[i];
if (image) {
clear_single_image(image, flag);
}
}
for (a = 0; a < totpoly; a++) {
mtpoly[a].tpage->id.tag &= ~LIB_TAG_DOIT;
for (int i = 0; i < ob_image_array_len; i++) {
Image *image = ob_image_array[i];
if (image) {
image->id.tag &= ~LIB_TAG_DOIT;
}
}
}
@ -312,11 +325,10 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
if (scene->r.bake_flag & R_BAKE_CLEAR) { /* clear images */
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
{
Mesh *me;
ClearFlag clear_flag = 0;
ob = base->object;
me = (Mesh *)ob->data;
// me = (Mesh *)ob->data;
if (scene->r.bake_mode == RE_BAKE_NORMALS) {
clear_flag = CLEAR_TANGENT_NORMAL;
@ -325,7 +337,11 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
clear_flag = CLEAR_DISPLACEMENT;
}
clear_images_poly(me->mtpoly, me->totpoly, clear_flag);
{
Image **ob_image_array = BKE_object_material_edit_image_get_array(ob);
clear_images_poly(ob_image_array, ob->totcol, clear_flag);
MEM_freeN(ob_image_array);
}
}
CTX_DATA_END;
}
@ -351,11 +367,16 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
//bkr.reports= op->reports;
/* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
bkr.ob_image.array = BKE_object_material_edit_image_get_array(ob);
bkr.ob_image.len = ob->totcol;
bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple);
bkr.lores_dm = multiresbake_create_loresdm(scene, ob, &bkr.lvl);
RE_multires_bake_images(&bkr);
MEM_freeN(bkr.ob_image.array);
BLI_freelistN(&bkr.image);
bkr.lores_dm->release(bkr.lores_dm);
@ -401,6 +422,9 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj)
data = MEM_callocN(sizeof(MultiresBakerJobData), "multiresBaker derivedMesh_data");
data->ob_image.array = BKE_object_material_edit_image_get_array(ob);
data->ob_image.len = ob->totcol;
/* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl, &data->simple);
data->lores_dm = multiresbake_create_loresdm(scene, ob, &lvl);
@ -421,8 +445,6 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa
if (bkj->bake_clear) { /* clear images */
for (data = bkj->data.first; data; data = data->next) {
DerivedMesh *dm = data->lores_dm;
MTexPoly *mtexpoly = CustomData_get_layer(&dm->polyData, CD_MTEXPOLY);
ClearFlag clear_flag = 0;
if (bkj->mode == RE_BAKE_NORMALS) {
@ -432,7 +454,7 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa
clear_flag = CLEAR_DISPLACEMENT;
}
clear_images_poly(mtexpoly, dm->getNumPolys(dm), clear_flag);
clear_images_poly(data->ob_image.array, data->ob_image.len, clear_flag);
}
}
@ -445,6 +467,8 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa
bkr.use_lores_mesh = bkj->use_lores_mesh;
bkr.user_scale = bkj->user_scale;
//bkr.reports = bkj->reports;
bkr.ob_image.array = data->ob_image.array;
bkr.ob_image.len = data->ob_image.len;
/* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
bkr.lores_dm = data->lores_dm;
@ -493,6 +517,8 @@ static void multiresbake_freejob(void *bkv)
GPU_free_image(ima);
}
MEM_freeN(data->ob_image.array);
BLI_freelistN(&data->images);
MEM_freeN(data);

View File

@ -44,11 +44,13 @@
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_editmesh.h"
#include "BKE_image.h"
#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_material.h"
#include "DEG_depsgraph.h"
@ -425,17 +427,20 @@ static void image_refresh(const bContext *C, ScrArea *sa)
}
else {
/* old shading system, we set texface */
MTexPoly *tf;
if (em && EDBM_mtexpoly_check(em)) {
tf = EDBM_mtexpoly_active_get(em, NULL, sloppy, selected);
BMFace *efa = BM_mesh_active_face_get(em->bm, sloppy, selected);
if (tf) {
if (efa) {
/* don't need to check for pin here, see above */
sima->image = tf->tpage;
Image *image = BKE_object_material_edit_image_get(obedit, efa->mat_nr);
sima->image = image;
if ((sima->flag & SI_EDITTILE) == 0) {
sima->curtile = tf->tile;
MTexPoly *tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
if (tf) {
if ((sima->flag & SI_EDITTILE) == 0) {
sima->curtile = tf->tile;
}
}
}
}

View File

@ -2857,7 +2857,6 @@ static void createTransUVs(bContext *C, TransInfo *t)
const bool is_prop_connected = (t->flag & T_PROP_CONNECTED) != 0;
const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS);
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
if (!ED_space_image_show_uvedit(sima, t->obedit))
return;
@ -2881,10 +2880,9 @@ static void createTransUVs(bContext *C, TransInfo *t)
}
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
MTexPoly *tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
BMLoop *l;
if (!uvedit_face_visible_test(scene, ima, efa, tf)) {
if (!uvedit_face_visible_test(scene, ima, efa)) {
BM_elem_flag_disable(efa, BM_ELEM_TAG);
continue;
}

View File

@ -66,17 +66,14 @@ static int uvedit_center(Scene *scene, BMEditMesh *em, Image *ima, float center[
BMFace *f;
BMLoop *l;
BMIter iter, liter;
MTexPoly *tf;
MLoopUV *luv;
int tot = 0;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
zero_v2(center);
BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(f, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, f, tf))
if (!uvedit_face_visible_test(scene, ima, f))
continue;
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
@ -102,14 +99,11 @@ static void uvedit_translate(Scene *scene, BMEditMesh *em, Image *ima, float del
BMLoop *l;
BMIter iter, liter;
MLoopUV *luv;
MTexPoly *tf;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(f, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, f, tf))
if (!uvedit_face_visible_test(scene, ima, f))
continue;
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {

View File

@ -33,6 +33,8 @@
#include <stdlib.h>
#include <string.h>
#include "MEM_guardedalloc.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@ -218,7 +220,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
totarea += BM_face_calc_area(efa);
totuvarea += area_poly_v2((const float (*)[2])tf_uv, efa->len);
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
if (uvedit_face_visible_test(scene, ima, efa)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
}
else {
@ -316,7 +318,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
if (uvedit_face_visible_test(scene, ima, efa)) {
const int efa_len = efa->len;
float (*tf_uv)[2] = (float (*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, efa_len);
float (*tf_uvorig)[2] = (float (*)[2])BLI_buffer_reinit_data(&tf_uvorig_buf, vec2f, efa_len);
@ -421,25 +423,37 @@ static void draw_uvs_other_mesh_texface(Object *ob, const Image *curimage, const
{
Mesh *me = ob->data;
MPoly *mpoly = me->mpoly;
MTexPoly *mtpoly = me->mtpoly;
int a;
if (me->mloopuv == NULL) {
return;
}
for (a = me->totpoly; a != 0; a--, mpoly++, mtpoly++) {
Image **image_array = NULL;
if (other_uv_filter == SI_FILTER_SAME_IMAGE) {
image_array = BKE_object_material_edit_image_get_array(ob);
}
for (a = me->totpoly; a != 0; a--, mpoly++) {
if (other_uv_filter == SI_FILTER_ALL) {
/* Nothing to compare, all UV faces are visible. */
}
else if (other_uv_filter == SI_FILTER_SAME_IMAGE) {
if (mtpoly->tpage != curimage) {
if (mpoly[a].mat_nr >= ob->totcol) {
continue;
}
if (image_array[mpoly[a].mat_nr] != curimage) {
continue;
}
}
draw_uvs_lineloop_mpoly(me, mpoly, pos);
}
if (image_array) {
MEM_freeN(image_array);
}
}
static void draw_uvs_other_mesh_new_shading(Object *ob, const Image *curimage, const int other_uv_filter, unsigned int pos)
{
@ -638,7 +652,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, SceneLayer *sl, Object *obe
}
}
else {
curimage = (activetf) ? activetf->tpage : ima;
curimage = (efa_act) ? BKE_object_material_edit_image_get(obedit, efa_act->mat_nr) : ima;
}
draw_uvs_other(sl, obedit, curimage, new_shading_nodes, sima->other_uv_filter);
@ -677,11 +691,11 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, SceneLayer *sl, Object *obe
for (unsigned int i = 0; i < em->tottri; i++) {
efa = em->looptris[i][0]->f;
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
if (uvedit_face_visible_test(scene, ima, efa)) {
const bool is_select = uvedit_face_select_test(scene, efa, cd_loop_uv_offset);
BM_elem_flag_enable(efa, BM_ELEM_TAG);
if (tf == activetf) {
if (efa == efa_act) {
/* only once */
immUniformThemeColor(TH_EDITMESH_ACTIVE);
}
@ -708,7 +722,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, SceneLayer *sl, Object *obe
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
if (uvedit_face_visible_test(scene, ima, efa)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
}
else {

View File

@ -182,7 +182,6 @@ void ED_uvedit_assign_image(Main *UNUSED(bmain), Scene *scene, Object *obedit, I
{
BMEditMesh *em;
BMIter iter;
MTexPoly *tf;
bool update = false;
const bool selected = !(scene->toolsettings->uv_flag & UV_SYNC_SELECTION);
@ -206,8 +205,6 @@ void ED_uvedit_assign_image(Main *UNUSED(bmain), Scene *scene, Object *obedit, I
BMFace *efa;
int cd_loop_uv_offset;
int cd_poly_tex_offset;
/* old shading system, assign image to selected faces */
#ifdef USE_SWITCH_ASPECT
float prev_aspect[2], fprev_aspect;
@ -230,22 +227,14 @@ void ED_uvedit_assign_image(Main *UNUSED(bmain), Scene *scene, Object *obedit, I
}
cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
/* now assign to all visible faces */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (uvedit_face_visible_test(scene, previma, efa, tf) &&
if (uvedit_face_visible_test(scene, previma, efa) &&
(selected == true || uvedit_face_select_test(scene, efa, cd_loop_uv_offset)))
{
if (ima) {
tf->tpage = ima;
if (ima->id.us == 0) id_us_plus(&ima->id);
else id_lib_extern(&ima->id);
#ifdef USE_SWITCH_ASPECT
if (ima) {
/* we also need to correct the aspect of uvs */
if (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) {
/* do nothing */
@ -261,11 +250,9 @@ void ED_uvedit_assign_image(Main *UNUSED(bmain), Scene *scene, Object *obedit, I
luv->uv[0] /= faspect;
}
}
}
#endif
}
else {
tf->tpage = NULL;
}
BKE_object_material_edit_image_set(obedit, efa->mat_nr, ima);
update = true;
}
@ -346,14 +333,17 @@ bool uvedit_face_visible_nolocal(Scene *scene, BMFace *efa)
return (BM_elem_flag_test(efa, BM_ELEM_HIDDEN) == 0 && BM_elem_flag_test(efa, BM_ELEM_SELECT));
}
bool uvedit_face_visible_test(Scene *scene, Image *ima, BMFace *efa, MTexPoly *tf)
bool uvedit_face_visible_test(Scene *scene, Image *ima, BMFace *efa)
{
ToolSettings *ts = scene->toolsettings;
if (ts->uv_flag & UV_SHOW_SAME_IMAGE)
return (tf->tpage == ima) ? uvedit_face_visible_nolocal(scene, efa) : false;
else
if (ts->uv_flag & UV_SHOW_SAME_IMAGE) {
const Image *face_image = BKE_object_material_edit_image_get(scene->obedit, efa->mat_nr);
return (face_image == ima) ? uvedit_face_visible_nolocal(scene, efa) : false;
}
else {
return uvedit_face_visible_nolocal(scene, efa);
}
}
bool uvedit_face_select_test(Scene *scene, BMFace *efa,
@ -646,18 +636,15 @@ bool ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float r_min[2],
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
MTexPoly *tf;
MLoopUV *luv;
bool changed = false;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
INIT_MINMAX2(r_min, r_max);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@ -696,17 +683,14 @@ static bool ED_uvedit_median(Scene *scene, Image *ima, Object *obedit, float co[
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
MTexPoly *tf;
MLoopUV *luv;
unsigned int sel = 0;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
zero_v2(co);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@ -765,7 +749,7 @@ void uv_find_nearest_edge(Scene *scene, Image *ima, BMEditMesh *em, const float
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
@ -809,7 +793,7 @@ static void uv_find_nearest_face(Scene *scene, Image *ima, BMEditMesh *em, const
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
uv_poly_center(efa, cent, cd_loop_uv_offset);
@ -861,7 +845,7 @@ void uv_find_nearest_vert(Scene *scene, Image *ima, BMEditMesh *em,
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
@ -897,20 +881,17 @@ bool ED_uvedit_nearest_uv(Scene *scene, Object *obedit, Image *ima, const float
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
MTexPoly *tf;
MLoopUV *luv;
float mindist, dist;
bool found = false;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
mindist = 1e10f;
copy_v2_v2(r_uv, co);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@ -1020,7 +1001,6 @@ static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestH
BMFace *efa;
BMIter iter, liter;
BMLoop *l;
MTexPoly *tf;
UvVertMap *vmap;
UvMapVert *iterv_curr;
UvMapVert *iterv_next;
@ -1028,7 +1008,6 @@ static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestH
bool looking, select;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
/* setup */
BM_mesh_elem_table_ensure(em->bm, BM_FACE);
@ -1061,9 +1040,7 @@ static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestH
/* find correct valence edges which are not tagged yet, but connect to tagged one */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!BM_elem_flag_test(efa, BM_ELEM_TAG) && uvedit_face_visible_test(scene, ima, efa, tf)) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG) && uvedit_face_visible_test(scene, ima, efa)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
/* check face not hidden and not tagged */
if (!(iterv_curr = uv_select_edgeloop_vertex_map_get(vmap, efa, l)))
@ -1123,7 +1100,6 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
MTexPoly *tf;
MLoopUV *luv;
UvVertMap *vmap;
UvMapVert *vlist, *iterv, *startv;
@ -1132,7 +1108,6 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo
char *flag;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
BM_mesh_elem_table_ensure(em->bm, BM_FACE); /* we can use this too */
@ -1147,9 +1122,7 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo
if (!hit) {
BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, a) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
if (uvedit_face_visible_test(scene, ima, efa)) {
if (select_faces) {
if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
stack[stacksize] = a;
@ -1313,12 +1286,9 @@ static float *uv_sel_co_from_eve(Scene *scene, Image *ima, BMEditMesh *em, BMVer
BMLoop *l;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
BM_ITER_ELEM (l, &liter, eve, BM_LOOPS_OF_VERT) {
MTexPoly *tf = BM_ELEM_CD_GET_VOID_P(l->f, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, l->f, tf))
if (!uvedit_face_visible_test(scene, ima, l->f))
continue;
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
@ -1344,7 +1314,6 @@ static int uv_select_more_less(bContext *C, const bool select)
ToolSettings *ts = scene->toolsettings;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
if (ts->uv_flag & UV_SYNC_SELECTION) {
if (select) {
@ -1367,9 +1336,7 @@ static int uv_select_more_less(bContext *C, const bool select)
/* mark loops to be selected */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
MTexPoly *tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
if (uvedit_face_visible_test(scene, ima, efa)) {
#define IS_SEL 1
#define IS_UNSEL 2
@ -1412,9 +1379,7 @@ static int uv_select_more_less(bContext *C, const bool select)
/* mark loops to be selected */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
MTexPoly *tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
if (uvedit_face_visible_test(scene, ima, efa)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@ -1481,11 +1446,9 @@ static void uv_weld_align(bContext *C, int tool)
SpaceImage *sima;
Scene *scene;
Image *ima;
MTexPoly *tf;
float cent[2], min[2], max[2];
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
scene = CTX_data_scene(C);
ima = CTX_data_edit_image(C);
@ -1499,9 +1462,7 @@ static void uv_weld_align(bContext *C, int tool)
BMLoop *l;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@ -1523,8 +1484,7 @@ static void uv_weld_align(bContext *C, int tool)
BMLoop *l;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@ -1543,8 +1503,7 @@ static void uv_weld_align(bContext *C, int tool)
BMLoop *l;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@ -1572,9 +1531,7 @@ static void uv_weld_align(bContext *C, int tool)
/* tag verts with a selected UV */
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
BM_ITER_ELEM (l, &liter, eve, BM_LOOPS_OF_VERT) {
tf = BM_ELEM_CD_GET_VOID_P(l->f, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, l->f, tf))
if (!uvedit_face_visible_test(scene, ima, l->f))
continue;
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
@ -1662,9 +1619,7 @@ static void uv_weld_align(bContext *C, int tool)
/* go over all verts except for endpoints */
for (i = 0; i < BLI_array_count(eve_line); i++) {
BM_ITER_ELEM (l, &liter, eve_line[i], BM_LOOPS_OF_VERT) {
tf = BM_ELEM_CD_GET_VOID_P(l->f, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, l->f, tf))
if (!uvedit_face_visible_test(scene, ima, l->f))
continue;
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
@ -1750,7 +1705,6 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op)
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
Image *ima;
MTexPoly *tf;
int uv_a_index;
int uv_b_index;
float *uv_a;
@ -1761,7 +1715,6 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op)
BMLoop *l;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
sima = CTX_wm_space_image(C);
scene = CTX_data_scene(C);
@ -1775,8 +1728,7 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op)
/* TODO, use qsort as with MESH_OT_remove_doubles, this isn't optimal */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@ -1838,8 +1790,7 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op)
BLI_array_declare(loop_arr_unselected);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@ -1929,11 +1880,9 @@ static void uv_select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
MTexPoly *tf;
MLoopUV *luv;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
if (ts->uv_flag & UV_SYNC_SELECTION) {
@ -1957,9 +1906,7 @@ static void uv_select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@ -1975,9 +1922,7 @@ static void uv_select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@ -2066,7 +2011,6 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
MTexPoly *tf;
MLoopUV *luv;
NearestHit hit;
int i, selectmode, sticky, sync, *hitv = NULL;
@ -2076,7 +2020,6 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
float penalty[2];
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
/* notice 'limit' is the same no matter the zoom level, since this is like
* remove doubles and could annoying if it joined points when zoomed out.
@ -2228,8 +2171,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@ -2264,8 +2206,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
/* select sticky uvs */
if (sticky != SI_STICKY_DISABLE) {
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@ -2521,12 +2462,10 @@ static int uv_select_split_exec(bContext *C, wmOperator *op)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
MTexPoly *tf;
MLoopUV *luv;
bool changed = false;
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
if (ts->uv_flag & UV_SYNC_SELECTION) {
BKE_report(op->reports, RPT_ERROR, "Cannot split selection when sync selection is enabled");
@ -2538,9 +2477,8 @@ static int uv_select_split_exec(bContext *C, wmOperator *op)
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
bool is_sel = false;
bool is_unsel = false;
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
/* are we all selected? */
@ -2854,7 +2792,6 @@ static int uv_border_select_exec(bContext *C, wmOperator *op)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
MTexPoly *tf;
MLoopUV *luv;
rctf rectf;
bool changed, pinned, select, extend;
@ -2863,7 +2800,6 @@ static int uv_border_select_exec(bContext *C, wmOperator *op)
(ts->uv_selectmode == UV_SELECT_FACE);
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
/* get rectangle from operator */
WM_operator_properties_border_to_rctf(op, &rectf);
@ -2888,8 +2824,7 @@ static int uv_border_select_exec(bContext *C, wmOperator *op)
/* assume not touched */
BM_elem_flag_disable(efa, BM_ELEM_TAG);
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
if (uvedit_face_visible_test(scene, ima, efa)) {
uv_poly_center(efa, cent, cd_loop_uv_offset);
if (BLI_rctf_isect_pt_v(&rectf, cent)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
@ -2908,8 +2843,7 @@ static int uv_border_select_exec(bContext *C, wmOperator *op)
changed = true;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@ -3110,13 +3044,11 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo
(ts->uv_selectmode == UV_SELECT_FACE));
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
BMIter iter, liter;
BMFace *efa;
BMLoop *l;
MTexPoly *tf;
int screen_uv[2];
bool changed = false;
rcti rect;
@ -3152,8 +3084,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo
}
else { /* Vert Sel */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
if (uvedit_face_visible_test(scene, ima, efa)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if ((select) != (uvedit_uv_select_test(scene, l, cd_loop_uv_offset))) {
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@ -3302,16 +3233,13 @@ static bool uv_snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, cons
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
MTexPoly *tface;
MLoopUV *luv;
bool changed = false;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tface = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tface))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@ -3332,16 +3260,13 @@ static bool uv_snap_uvs_offset(Scene *scene, Image *ima, Object *obedit, const f
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
MTexPoly *mtexpoly;
MLoopUV *luv;
bool changed = false;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
mtexpoly = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, mtexpoly))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@ -3363,17 +3288,14 @@ static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object
BMFace *f;
BMLoop *l, *lsub;
BMIter iter, liter, lsubiter;
MTexPoly *tface;
MLoopUV *luv;
bool changed = false;
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
/* index every vert that has a selected UV using it, but only once so as to
* get unique indices and to count how much to malloc */
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
tface = BM_ELEM_CD_GET_VOID_P(f, cd_poly_tex_offset);
if (uvedit_face_visible_test(scene, ima, f, tface)) {
if (uvedit_face_visible_test(scene, ima, f)) {
BM_elem_flag_enable(f, BM_ELEM_TAG);
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
BM_elem_flag_set(l, BM_ELEM_TAG, uvedit_uv_select_test(scene, l, cd_loop_uv_offset));
@ -3421,22 +3343,19 @@ static bool uv_snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
MTexPoly *tface;
MLoopUV *luv;
int width = 0, height = 0;
float w, h;
bool changed = false;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
ED_space_image_get_size(sima, &width, &height);
w = (float)width;
h = (float)height;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tface = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tface))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@ -3526,16 +3445,13 @@ static int uv_pin_exec(bContext *C, wmOperator *op)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
MTexPoly *tface;
MLoopUV *luv;
const bool clear = RNA_boolean_get(op->ptr, "clear");
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tface = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tface))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@ -3584,15 +3500,12 @@ static int uv_select_pinned_exec(bContext *C, wmOperator *UNUSED(op))
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
MTexPoly *tface;
MLoopUV *luv;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tface = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tface))
if (!uvedit_face_visible_test(scene, ima, efa))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@ -3656,13 +3569,11 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
BMLoop *l;
BMIter iter, liter;
MLoopUV *luv;
MTexPoly *tf;
const bool swap = RNA_boolean_get(op->ptr, "unselected");
Image *ima = sima ? sima->image : NULL;
const int use_face_center = (ts->uv_selectmode == UV_SELECT_FACE);
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
if (ts->uv_flag & UV_SYNC_SELECTION) {
EDBM_mesh_hide(em, swap);
@ -3674,9 +3585,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
int hide = 0;
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf)) {
if (!uvedit_face_visible_test(scene, ima, efa)) {
continue;
}

View File

@ -58,6 +58,7 @@
#include "BKE_depsgraph.h"
#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_editmesh.h"
@ -214,8 +215,7 @@ void ED_uvedit_get_aspect(Scene *scene, Object *ob, BMesh *bm, float *aspx, floa
ED_object_get_active_image(ob, efa->mat_nr + 1, &ima, NULL, NULL, NULL);
}
else {
MTexPoly *tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY);
ima = tf->tpage;
ima = BKE_object_material_edit_image_get(ob, efa->mat_nr);
}
ED_image_get_uv_aspect(ima, NULL, aspx, aspy);

View File

@ -113,12 +113,17 @@ void GPU_render_text(
const float *v_quad[4], const float *uv_quad[4],
int glattrib)
{
if ((mode & GEMAT_TEXT) && (textlen > 0) && mtexpoly->tpage) {
/* XXX, 2.8 removes texface */
#if 0
Image *ima = mtexpoly->tpage;
#else
Image *ima = NULL;
#endif
if ((mode & GEMAT_TEXT) && (textlen > 0) && ima) {
const float *v1 = v_quad[0];
const float *v2 = v_quad[1];
const float *v3 = v_quad[2];
const float *v4 = v_quad[3];
Image *ima = (Image *)mtexpoly->tpage;
const size_t textlen_st = textlen;
float centerx, centery, sizex, sizey, transx, transy, movex, movey, advance;
@ -1033,7 +1038,12 @@ int GPU_set_tpage(MTexPoly *mtexpoly, int mipmap, int alphablend)
return 0;
}
/* XXX, 2.8 removes texface */
#if 0
Image *ima = mtexpoly->tpage;
#else
Image *ima = NULL;
#endif
GTS.lasttface = mtexpoly;
gpu_verify_alpha_blend(alphablend);

View File

@ -211,6 +211,10 @@ typedef struct Material {
char nmap_tangent_names[9][64]; /* [MAX_MTFACE+1][MAX_NAME]; +1 for empty name */
int nmap_tangent_names_count, pad5;
/* image to use for image/uv space, also bake target
* (not to be used shading/rendering pipeline, this is editor featyure only!). */
struct Image *edit_image;
struct TexPaintSlot *texpaintslot; /* cached slot for painting. Make sure to recalculate before use
* with refresh_texpaint_image_cache */
ListBase gpumaterial; /* runtime */
@ -285,7 +289,7 @@ typedef struct Material {
#define MA_ONLYSHADOW 1024
#define MA_HALO_XALPHA 1024
#define MA_STAR 0x800
#define MA_FACETEXTURE 0x800
// #define MA_FACETEXTURE 0x800 /* deprecated */
#define MA_HALOTEX 0x1000
#define MA_HALOPUNO 0x2000
#define MA_ONLYCAST 0x2000
@ -307,7 +311,7 @@ typedef struct Material {
/* qdn: a bit clumsy this, tangents needed for normal maps separated from shading */
#define MA_NORMAP_TANG 0x8000000
#define MA_GROUP_NOLAY 0x10000000
#define MA_FACETEXTURE_ALPHA 0x20000000
// #define MA_FACETEXTURE_ALPHA 0x20000000 /* deprecated */
#define MA_STR_B_UNITS 0x40000000
#define MA_STR_SURFDIFF 0x80000000

View File

@ -188,7 +188,6 @@ typedef struct MVertTri {
typedef struct MTexPoly {
struct Image *tpage;
char flag, transp;
short mode, tile, pad;
} MTexPoly;
@ -196,7 +195,6 @@ typedef struct MTexPoly {
/* can copy from/to MTexPoly/MTFace */
#define ME_MTEXFACE_CPY(dst, src) \
{ \
(dst)->tpage = (src)->tpage; \
(dst)->flag = (src)->flag; \
(dst)->transp = (src)->transp; \
(dst)->mode = (src)->mode; \
@ -256,7 +254,6 @@ typedef struct MSelect {
/*tessellation uv face data*/
typedef struct MTFace {
float uv[4][2];
struct Image *tpage;
char flag, transp;
short mode, tile, unwrap;
} MTFace;

View File

@ -418,7 +418,7 @@ typedef struct UVProjectModifierData {
/* the objects which do the projecting */
struct Object *projectors[10]; /* MOD_UVPROJECT_MAXPROJECTORS */
struct Image *image; /* the image to project */
int flags;
int pad2;
int num_projectors;
float aspectx, aspecty;
float scalex, scaley;

View File

@ -1887,6 +1887,12 @@ void RNA_def_material(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Light Group", "Limit lighting to lamps in this Group");
RNA_def_property_update(prop, 0, "rna_Material_update");
prop = RNA_def_property(srna, "edit_image", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "edit_image");
RNA_def_property_struct_type(prop, "Image");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Edit Image", "Image to use for UV-mapping");
prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "index");
RNA_def_property_ui_text(prop, "Pass Index", "Index number for the \"Material Index\" render pass");
@ -1964,18 +1970,6 @@ void RNA_def_material(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Shadow Type", "How to draw shadows");
RNA_def_property_update(prop, 0, "rna_Material_update");
prop = RNA_def_property(srna, "use_face_texture", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_FACETEXTURE);
RNA_def_property_ui_text(prop, "Face Textures",
"Replace the object's base color with color from UV map image textures");
RNA_def_property_update(prop, 0, "rna_Material_update");
prop = RNA_def_property(srna, "use_face_texture_alpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_FACETEXTURE_ALPHA);
RNA_def_property_ui_text(prop, "Face Textures Alpha",
"Replace the object's base alpha value with alpha from UV map image textures");
RNA_def_property_update(prop, 0, "rna_Material_update");
prop = RNA_def_property(srna, "use_cast_shadows", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode2", MA_CASTSHADOW);
RNA_def_property_ui_text(prop, "Cast Shadows",

View File

@ -1203,42 +1203,6 @@ static int rna_MeshPaintMaskLayer_data_length(PointerRNA *ptr)
/* End paint mask */
static void rna_TexturePoly_image_set(PointerRNA *ptr, PointerRNA value)
{
MTexPoly *tf = (MTexPoly *)ptr->data;
ID *id = value.data;
if (id) {
/* special exception here, individual faces don't count
* as reference, but we do ensure the refcount is not zero */
if (id->us == 0)
id_us_plus(id);
else
id_lib_extern(id);
}
tf->tpage = (struct Image *)id;
}
/* while this is supposed to be readonly,
* keep it to support importers that only make tessfaces */
static void rna_TextureFace_image_set(PointerRNA *ptr, PointerRNA value)
{
MTFace *tf = (MTFace *)ptr->data;
ID *id = value.data;
if (id) {
/* special exception here, individual faces don't count
* as reference, but we do ensure the refcount is not zero */
if (id->us == 0)
id_us_plus(id);
else
id_lib_extern(id);
}
tf->tpage = (struct Image *)id;
}
static int rna_MeshTessFace_verts_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION])
{
MFace *face = (MFace *)ptr->data;
@ -2342,13 +2306,6 @@ static void rna_def_mtface(BlenderRNA *brna)
RNA_def_struct_path_func(srna, "rna_MeshTextureFace_path");
RNA_def_struct_ui_icon(srna, ICON_FACESEL_HLT);
prop = RNA_def_property(srna, "image", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "tpage");
RNA_def_property_pointer_funcs(prop, NULL, "rna_TextureFace_image_set", NULL, NULL);
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Image", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
/* these are for editing only, access at loops now */
#if 0
prop = RNA_def_property(srna, "select_uv", PROP_BOOLEAN, PROP_NONE);
@ -2454,13 +2411,6 @@ static void rna_def_mtexpoly(BlenderRNA *brna)
RNA_def_struct_path_func(srna, "rna_MeshTexturePoly_path");
RNA_def_struct_ui_icon(srna, ICON_FACESEL_HLT);
prop = RNA_def_property(srna, "image", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "tpage");
RNA_def_property_pointer_funcs(prop, NULL, "rna_TexturePoly_image_set", NULL, NULL);
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Image", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
#if 0 /* moved to MeshUVLoopLayer */
prop = RNA_def_property(srna, "select_uv", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TF_SEL1);

View File

@ -2248,11 +2248,6 @@ static void rna_def_modifier_uvproject(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Vertical Scale", "");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "use_image_override", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_UVPROJECT_OVERRIDEIMAGE);
RNA_def_property_ui_text(prop, "Override Image", "Override faces' current images with the given image");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
srna = RNA_def_struct(brna, "UVProjector", NULL);
RNA_def_struct_ui_text(srna, "UVProjector", "UV projector used by the UV project modifier");

View File

@ -280,7 +280,6 @@ static void rna_Scene_collada_export(
int include_shapekeys,
int deform_bones_only,
int active_uv_only,
int include_uv_textures,
int include_material_textures,
int use_texture_copies,
int triangulate,
@ -306,7 +305,6 @@ static void rna_Scene_collada_export(
deform_bones_only,
active_uv_only,
include_uv_textures,
include_material_textures,
use_texture_copies,
@ -406,9 +404,6 @@ void RNA_api_scene(StructRNA *srna)
RNA_def_boolean(func, "active_uv_only", false, "Only Selected UV Map", "Export only the selected UV Map");
RNA_def_boolean(func, "include_uv_textures", false,
"Include UV Textures", "Export textures assigned to the object UV Maps");
RNA_def_boolean(func, "include_material_textures", false,
"Include Material Textures", "Export textures assigned to the object Materials");

View File

@ -46,6 +46,7 @@
#include "BKE_camera.h"
#include "BKE_library_query.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_DerivedMesh.h"
@ -59,7 +60,7 @@ static void initData(ModifierData *md)
{
UVProjectModifierData *umd = (UVProjectModifierData *) md;
umd->flags = 0;
umd->num_projectors = 1;
umd->aspectx = umd->aspecty = 1.0f;
umd->scalex = umd->scaley = 1.0f;
@ -136,7 +137,6 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
Image *image = umd->image;
MPoly *mpoly, *mp;
MLoop *mloop;
const bool override_image = (umd->flags & MOD_UVPROJECT_OVERRIDEIMAGE) != 0;
Projector projectors[MOD_UVPROJECT_MAXPROJECTORS];
int num_projectors = 0;
char uvname[MAX_CUSTOMDATA_LAYER_NAME];
@ -243,9 +243,14 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
mpoly = dm->getPolyArray(dm);
mloop = dm->getLoopArray(dm);
Image **ob_image_array = NULL;
if (image) {
ob_image_array = BKE_object_material_edit_image_get_array(ob);
}
/* apply coords as UVs, and apply image if tfaces are new */
for (i = 0, mp = mpoly; i < numPolys; ++i, ++mp, ++mt) {
if (override_image || !image || (mtexpoly == NULL || mt->tpage == image)) {
if (!image || (mtexpoly == NULL || (mp->mat_nr < ob->totcol ? ob_image_array[mp->mat_nr] : NULL) == image)) {
if (num_projectors == 1) {
if (projectors[0].uci) {
unsigned int fidx = mp->totloop - 1;
@ -308,13 +313,13 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
}
}
}
if (override_image && mtexpoly) {
mt->tpage = image;
}
}
MEM_freeN(coords);
if (ob_image_array) {
MEM_freeN(ob_image_array);
}
if (free_uci) {
int j;

View File

@ -58,46 +58,14 @@ typedef struct BPy_BMTexPoly {
MTexPoly *data;
} BPy_BMTexPoly;
extern PyObject *pyrna_id_CreatePyObject(ID *id);
extern bool pyrna_id_FromPyObject(PyObject *obj, ID **id);
PyDoc_STRVAR(bpy_bmtexpoly_image_doc,
"Image or None.\n\n:type: :class:`bpy.types.Image`"
);
static PyObject *bpy_bmtexpoly_image_get(BPy_BMTexPoly *self, void *UNUSED(closure))
{
return pyrna_id_CreatePyObject((ID *)self->data->tpage);
}
static int bpy_bmtexpoly_image_set(BPy_BMTexPoly *self, PyObject *value, void *UNUSED(closure))
{
ID *id;
if (value == Py_None) {
id = NULL;
}
else if (pyrna_id_FromPyObject(value, &id) && id && GS(id->name) == ID_IM) {
/* pass */
}
else {
PyErr_Format(PyExc_KeyError, "BMTexPoly.image = x"
"expected an image or None, not '%.200s'",
Py_TYPE(value)->tp_name);
return -1;
}
id_lib_extern(id);
self->data->tpage = (struct Image *)id;
return 0;
}
/* TODO, flag access */
#if 0
static PyGetSetDef bpy_bmtexpoly_getseters[] = {
/* attributes match rna_def_mtpoly */
{(char *)"image", (getter)bpy_bmtexpoly_image_get, (setter)bpy_bmtexpoly_image_set, (char *)bpy_bmtexpoly_image_doc, NULL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
#endif
static PyTypeObject BPy_BMTexPoly_Type; /* bm.loops.layers.uv.active */
@ -109,7 +77,9 @@ static void bm_init_types_bmtexpoly(void)
BPy_BMTexPoly_Type.tp_doc = NULL; // todo
#if 0
BPy_BMTexPoly_Type.tp_getset = bpy_bmtexpoly_getseters;
#endif
BPy_BMTexPoly_Type.tp_flags = Py_TPFLAGS_DEFAULT;

View File

@ -43,6 +43,12 @@ typedef struct MultiresBakeRender {
short mode;
bool use_lores_mesh; /* Use low-resolution mesh when baking displacement maps */
/* material aligned image array (for per-face bake image) */
struct {
Image **array;
int len;
} ob_image;
int number_of_rays; /* Number of rays to be cast when doing AO baking */
float bias; /* Bias between object and start ray point when doing AO baking */

View File

@ -669,11 +669,12 @@ static int get_next_bake_face(BakeShade *bs)
const float disp_solid[4] = {0.5f, 0.5f, 0.5f, 1.0f};
tface = RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
/* should use 'BKE_object_material_edit_image_get' but in this case simpler not to */
ima = vlr->mat ? vlr->mat->edit_image : NULL;
if (!tface || !tface->tpage)
if (!tface || !ima)
continue;
ima = tface->tpage;
ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ibuf == NULL)
@ -814,7 +815,7 @@ static void shade_tface(BakeShade *bs)
ObjectInstanceRen *obi = bs->obi;
ObjectRen *obr = obi->obr;
MTFace *tface = RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
Image *ima = tface->tpage;
Image *ima = vlr->mat->edit_image;
float vec[4][2];
int a, i1, i2, i3;

View File

@ -44,6 +44,7 @@
#include "BKE_ccg.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_multires.h"
#include "BKE_modifier.h"
@ -90,6 +91,8 @@ typedef struct {
void *bake_data;
ImBuf *ibuf;
MPassKnownData pass_data;
/* material aligned UV array */
Image **image_array;
} MResolvePixelData;
typedef void (*MFlushPixel)(const MResolvePixelData *data, const int x, const int y);
@ -374,13 +377,15 @@ static void *do_multires_bake_thread(void *data_v)
while ((tri_index = multires_bake_queue_next_tri(handle->queue)) >= 0) {
const MLoopTri *lt = &data->mlooptri[tri_index];
MTexPoly *mtpoly = &data->mtpoly[lt->poly];
MLoopUV *mloopuv = data->mloopuv;
const MPoly *mp = &data->mpoly[lt->poly];
const short mat_nr = mp->mat_nr;
const MLoopUV *mloopuv = data->mloopuv;
if (multiresbake_test_break(bkr))
break;
if (mtpoly->tpage != handle->image)
Image *tri_image = mat_nr < bkr->ob_image.len ? bkr->ob_image.array[mat_nr] : NULL;
if (tri_image != handle->image)
continue;
data->tri_index = tri_index;
@ -1179,30 +1184,34 @@ static void apply_ao_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, void
static void count_images(MultiresBakeRender *bkr)
{
int a, totpoly;
DerivedMesh *dm = bkr->lores_dm;
MTexPoly *mtexpoly = CustomData_get_layer(&dm->polyData, CD_MTEXPOLY);
BLI_listbase_clear(&bkr->image);
bkr->tot_image = 0;
totpoly = dm->getNumPolys(dm);
for (a = 0; a < totpoly; a++)
mtexpoly[a].tpage->id.tag &= ~LIB_TAG_DOIT;
for (a = 0; a < totpoly; a++) {
Image *ima = mtexpoly[a].tpage;
if ((ima->id.tag & LIB_TAG_DOIT) == 0) {
LinkData *data = BLI_genericNodeN(ima);
BLI_addtail(&bkr->image, data);
bkr->tot_image++;
ima->id.tag |= LIB_TAG_DOIT;
for (int i = 0; i < bkr->ob_image.len; i++) {
Image *ima = bkr->ob_image.array[i];
if (ima) {
ima->id.tag &= ~LIB_TAG_DOIT;
}
}
for (a = 0; a < totpoly; a++)
mtexpoly[a].tpage->id.tag &= ~LIB_TAG_DOIT;
for (int i = 0; i < bkr->ob_image.len; i++) {
Image *ima = bkr->ob_image.array[i];
if (ima) {
if ((ima->id.tag & LIB_TAG_DOIT) == 0) {
LinkData *data = BLI_genericNodeN(ima);
BLI_addtail(&bkr->image, data);
bkr->tot_image++;
ima->id.tag |= LIB_TAG_DOIT;
}
}
}
for (int i = 0; i < bkr->ob_image.len; i++) {
Image *ima = bkr->ob_image.array[i];
if (ima) {
ima->id.tag &= ~LIB_TAG_DOIT;
}
}
}
static void bake_images(MultiresBakeRender *bkr, MultiresBakeResult *result)

View File

@ -442,7 +442,7 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert
}
}
if ((texco & TEXCO_UV) || (mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE))) {
if ((texco & TEXCO_UV) || (mode & (MA_VERTEXCOL | MA_VERTEXCOLP))) {
MCol *mcol;
const float *uv;
char *name;
@ -504,15 +504,6 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert
suv->dyuv[0] = 0.0f;
suv->dyuv[1] = 0.0f;
}
if ((mode & MA_FACETEXTURE) && i == obr->actmtface) {
if ((mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) == 0) {
shi->vcol[0] = 1.0f;
shi->vcol[1] = 1.0f;
shi->vcol[2] = 1.0f;
shi->vcol[3] = 1.0f;
}
}
}
if (shi->totuv == 0) {
@ -521,14 +512,6 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert
suv->uv[0] = 0.0f;
suv->uv[1] = spoint->strandco;
suv->uv[2] = 0.0f; /* texture.c assumes there are 3 coords */
if (mode & MA_FACETEXTURE) {
/* no tface? set at 1.0f */
shi->vcol[0] = 1.0f;
shi->vcol[1] = 1.0f;
shi->vcol[2] = 1.0f;
shi->vcol[3] = 1.0f;
}
}
}
@ -570,7 +553,7 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert
}
if (shi->do_manage) {
if (mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE)) {
if (mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) {
srgb_to_linearrgb_v3_v3(shi->vcol, shi->vcol);
}
}
@ -1076,7 +1059,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
}
}
if ((texco & TEXCO_UV) || (mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE)) || (R.flag & R_NEED_VCOL)) {
if ((texco & TEXCO_UV) || (mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) || (R.flag & R_NEED_VCOL)) {
VlakRen *vlr = shi->vlr;
MTFace *tface;
MCol *mcol;
@ -1231,18 +1214,6 @@ void shade_input_set_shade_texco(ShadeInput *shi)
suv->dyuv[0] = 2.0f * (dl * uv3[0] - duv[0] * uv1[0] - duv[1] * uv2[0]);
suv->dyuv[1] = 2.0f * (dl * uv3[1] - duv[0] * uv1[1] - duv[1] * uv2[1]);
}
if ((mode & MA_FACETEXTURE) && i == obr->actmtface) {
if (((mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) == 0) && ((R.flag & R_NEED_VCOL) == 0)) {
shi->vcol[0] = 1.0f;
shi->vcol[1] = 1.0f;
shi->vcol[2] = 1.0f;
shi->vcol[3] = 1.0f;
}
if (tface->tpage) {
render_realtime_texture(shi, tface->tpage);
}
}
}
}
@ -1256,14 +1227,6 @@ void shade_input_set_shade_texco(ShadeInput *shi)
suv->uv[0] = 2.0f * (u + .5f);
suv->uv[1] = 2.0f * (v + .5f);
suv->uv[2] = 0.0f; /* texture.c assumes there are 3 coords */
if (mode & MA_FACETEXTURE) {
/* no tface? set at 1.0f */
shi->vcol[0] = 1.0f;
shi->vcol[1] = 1.0f;
shi->vcol[2] = 1.0f;
shi->vcol[3] = 1.0f;
}
}
}
@ -1319,7 +1282,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
* else un-initialized values are used
*/
if (shi->do_manage) {
if ((mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE)) || (R.flag & R_NEED_VCOL)) {
if ((mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) || (R.flag & R_NEED_VCOL)) {
srgb_to_linearrgb_v3_v3(shi->vcol, shi->vcol);
}
}

View File

@ -899,14 +899,7 @@ void shade_color(ShadeInput *shi, ShadeResult *shr)
{
Material *ma= shi->mat;
if (ma->mode & (MA_FACETEXTURE)) {
shi->r= shi->vcol[0];
shi->g= shi->vcol[1];
shi->b= shi->vcol[2];
if (ma->mode & (MA_FACETEXTURE_ALPHA))
shi->alpha= shi->vcol[3];
}
else if (ma->mode & (MA_VERTEXCOLP)) {
if (ma->mode & (MA_VERTEXCOLP)) {
float neg_alpha = 1.0f - shi->vcol[3];
shi->r= shi->r*neg_alpha + shi->vcol[0]*shi->vcol[3];
shi->g= shi->g*neg_alpha + shi->vcol[1]*shi->vcol[3];
@ -1764,12 +1757,8 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
/* material color itself */
if (passflag & color_passes) {
if (ma->mode & (MA_FACETEXTURE)) {
shi->r= shi->vcol[0];
shi->g= shi->vcol[1];
shi->b= shi->vcol[2];
if (ma->mode & (MA_FACETEXTURE_ALPHA))
shi->alpha= shi->vcol[3];
if (false) {
/* pass */
}
#ifdef WITH_FREESTYLE
else if (ma->vcol_alpha) {

View File

@ -769,7 +769,6 @@ int collada_export(struct Scene *sce,
int deform_bones_only,
int active_uv_only,
int include_uv_textures,
int include_material_textures,
int use_texture_copies,

View File

@ -589,17 +589,17 @@ static bool ConvertMaterial(
/* In Multitexture use the face texture if and only if
* it is set in the buttons
* In GLSL is not working yet :/ 3.2011 */
bool facetex = false;
if (validface && mat->mode & MA_FACETEXTURE) {
facetex = true;
}
// foreach MTex
for (int i = 0; i < MAXTEX; i++) {
// use face tex
if (i == 0 && facetex ) {
facetex = false;
if (i == 0) {
#if 0
Image *tmp = (Image *)(tface->tpage);
#else
/* weak but better then nothing */
Image *tmp = mat ? mat->edit_image : NULL;
#endif
if (tmp) {
material->img[i] = tmp;
@ -789,7 +789,11 @@ static bool ConvertMaterial(
// check for tface tex to fallback on
if (validface) {
#if 0
material->img[0] = (Image *)(tface->tpage);
#else
material->img[0] = mat ? mat->edit_image : NULL;
#endif
// ------------------------
if (material->img[0]) {
material->texname[0] = material->img[0]->id.name;
@ -894,7 +898,7 @@ static RAS_MaterialBucket *material_from_mesh(Material *ma, MFace *mface, MTFace
ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol,
converter->GetGLSLMaterials());
if (ma && (ma->mode & MA_FACETEXTURE) == 0)
if (ma)
converter->CacheBlenderMaterial(scene, ma, bl_mat);
}
@ -910,7 +914,7 @@ static RAS_MaterialBucket *material_from_mesh(Material *ma, MFace *mface, MTFace
kx_blmat->Initialize(scene, bl_mat, (ma?&ma->game:NULL), lightlayer);
polymat = static_cast<RAS_IPolyMaterial*>(kx_blmat);
if (ma && (ma->mode & MA_FACETEXTURE) == 0)
if (ma)
converter->CachePolyMaterial(scene, ma, polymat);
}

View File

@ -190,7 +190,7 @@ Material *KX_BlenderMaterial::GetBlenderMaterial() const
Image *KX_BlenderMaterial::GetBlenderImage() const
{
return mMaterial->mtexpoly.tpage;
return mMaterial->material ? mMaterial->material->edit_image : NULL;
}
Scene* KX_BlenderMaterial::GetBlenderScene() const

View File

@ -60,6 +60,7 @@
extern "C"{
#include "BLF_api.h"
#include "BKE_DerivedMesh.h"
#include "DNA_material_types.h"
}
@ -785,8 +786,9 @@ static DMDrawOption CheckTexDM(MTexPoly *mtexpoly, const bool has_mcol, int matn
{
// index is the original face index, retrieve the polygon
Material *bl_material = current_polymat->GetBlenderMaterial();
if (matnr == current_blmat_nr &&
(mtexpoly == NULL || mtexpoly->tpage == current_image)) {
(mtexpoly == NULL || (bl_material ? bl_material->edit_image : NULL) == current_image)) {
// must handle color.
if (current_wireframe)
return DM_DRAW_OPTION_NO_MCOL;