Merging r49840 through r49854 from trunk into soc-2011-tomato

This commit is contained in:
Sergey Sharybin
2012-08-12 18:39:05 +00:00
24 changed files with 307 additions and 110 deletions

View File

@@ -67,10 +67,16 @@ short *give_totcolp(struct Object *ob);
struct Material ***give_matarar_id(struct ID *id); /* same but for ID's */
short *give_totcolp_id(struct ID *id);
enum {
BKE_MAT_ASSIGN_USERPREF,
BKE_MAT_ASSIGN_OBDATA,
BKE_MAT_ASSIGN_OBJECT
};
struct Material *give_current_material(struct Object *ob, short act);
struct ID *material_from(struct Object *ob, short act);
void assign_material_id(struct ID *id, struct Material *ma, short act);
void assign_material(struct Object *ob, struct Material *ma, short act);
void assign_material(struct Object *ob, struct Material *ma, short act, int assign_type);
void assign_matarar(struct Object *ob, struct Material ***matar, short totcol);
short find_material_index(struct Object *ob, struct Material *ma);

View File

@@ -254,6 +254,7 @@ endif()
if(WITH_MOD_CLOTH_ELTOPO)
list(APPEND INC
../../../extern/eltopo
../../../extern/eltopo/eltopo3d
)
add_definitions(-DWITH_ELTOPO)
endif()

View File

@@ -41,7 +41,8 @@ if env['WITH_BF_PYTHON']:
defs.append('DEBUG')
if env['WITH_BF_ELTOPO']:
incs += ' ../../../extern/eltopo'
incs += ' #/extern/eltopo'
incs += ' #/extern/eltopo/eltopo3d'
defs.append('WITH_ELTOPO')
if env['WITH_BF_QUICKTIME']:

View File

@@ -2596,7 +2596,8 @@ static void dag_id_flush_update(Scene *sce, ID *id)
if (id) {
idtype = GS(id->name);
if (ELEM8(idtype, ID_ME, ID_CU, ID_MB, ID_LA, ID_LT, ID_CA, ID_AR, ID_SPK)) {
if (OB_DATA_SUPPORT_ID(idtype)) {
for (obt = bmain->object.first; obt; obt = obt->id.next) {
if (!(ob && obt == ob) && obt->data == id) {
obt->recalc |= OB_RECALC_DATA;

View File

@@ -494,6 +494,9 @@ short *give_totcolp(Object *ob)
/* same as above but for ID's */
Material ***give_matarar_id(ID *id)
{
/* ensure we don't try get materials from non-obdata */
BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
switch (GS(id->name)) {
case ID_ME:
return &(((Mesh *)id)->mat);
@@ -510,6 +513,9 @@ Material ***give_matarar_id(ID *id)
short *give_totcolp_id(ID *id)
{
/* ensure we don't try get materials from non-obdata */
BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
switch (GS(id->name)) {
case ID_ME:
return &(((Mesh *)id)->totcol);
@@ -526,6 +532,9 @@ short *give_totcolp_id(ID *id)
static void data_delete_material_index_id(ID *id, short index)
{
/* ensure we don't try get materials from non-obdata */
BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
switch (GS(id->name)) {
case ID_ME:
BKE_mesh_delete_material_index((Mesh *)id, index);
@@ -765,11 +774,12 @@ void assign_material_id(ID *id, Material *ma, short act)
test_object_materials(id);
}
void assign_material(Object *ob, Material *ma, short act)
void assign_material(Object *ob, Material *ma, short act, int assign_type)
{
Material *mao, **matar, ***matarar;
char *matbits;
short *totcolp;
char bit=0;
if (act > MAXMAT) return;
if (act < 1) act = 1;
@@ -796,8 +806,29 @@ void assign_material(Object *ob, Material *ma, short act)
*matarar = matar;
*totcolp = act;
}
// Determine the object/mesh linking
if (assign_type == BKE_MAT_ASSIGN_USERPREF && ob->actcol) {
/* copy from previous material */
bit = ob->matbits[ob->actcol - 1];
}
else {
switch(assign_type) {
case BKE_MAT_ASSIGN_OBDATA:
bit = 0;
break;
case BKE_MAT_ASSIGN_OBJECT:
bit = 1;
break;
case BKE_MAT_ASSIGN_USERPREF:
default:
bit = (U.flag & USER_MAT_ON_OB) ? 1 : 0;
break;
}
}
if (act > ob->totcol) {
/* Need more space in the material arrays */
matar = MEM_callocN(sizeof(void *) * act, "matarray2");
matbits = MEM_callocN(sizeof(char) * act, "matbits1");
if (ob->totcol) {
@@ -809,17 +840,12 @@ void assign_material(Object *ob, Material *ma, short act)
ob->mat = matar;
ob->matbits = matbits;
ob->totcol = act;
/* copy object/mesh linking, or assign based on userpref */
if (ob->actcol)
ob->matbits[act - 1] = ob->matbits[ob->actcol - 1];
else
ob->matbits[act - 1] = (U.flag & USER_MAT_ON_OB) ? 1 : 0;
}
/* do it */
if (ob->matbits[act - 1]) { /* in object */
ob->matbits[act - 1] = bit;
if (bit == 1) { /* in object */
mao = ob->mat[act - 1];
if (mao) mao->id.us--;
ob->mat[act - 1] = ma;
@@ -845,7 +871,7 @@ void assign_matarar(struct Object *ob, struct Material ***matar, short totcol)
/* now we have the right number of slots */
for (i = 0; i < totcol; i++)
assign_material(ob, (*matar)[i], i + 1);
assign_material(ob, (*matar)[i], i + 1, BKE_MAT_ASSIGN_USERPREF);
if (actcol_orig > ob->totcol)
actcol_orig = ob->totcol;
@@ -879,7 +905,7 @@ int object_add_material_slot(Object *ob)
if (ob == NULL) return FALSE;
if (ob->totcol >= MAXMAT) return FALSE;
assign_material(ob, NULL, ob->totcol + 1);
assign_material(ob, NULL, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF);
ob->actcol = ob->totcol;
return TRUE;
}

View File

@@ -136,8 +136,6 @@ static void free_proxy_seq(Sequence *seq)
IMB_free_anim(seq->strip->proxy->anim);
seq->strip->proxy->anim = NULL;
}
BKE_sequencer_cache_cleanup_sequence(seq);
}
static void seq_free_strip(Strip *strip)
@@ -205,6 +203,8 @@ void BKE_sequence_free(Scene *scene, Sequence *seq)
seq_free_animdata(scene, seq);
}
BKE_sequencer_cache_cleanup_sequence(seq);
MEM_freeN(seq);
}
@@ -1640,6 +1640,13 @@ static void color_balance(SeqRenderData context, Sequence *seq, ImBuf *ibuf, flo
IMB_processor_apply_threaded(ibuf->y, sizeof(ColorBalanceThread), &init_data,
color_balance_init_handle, color_balance_do_thread);
/* color balance either happens on float buffer or byte buffer, but never on both,
* free byte buffer if there's float buffer since float buffer would be used for
* color balance in favor of byte buffer
*/
if (ibuf->rect_float && ibuf->rect)
imb_freerectImBuf(ibuf);
if (init_data.mask)
IMB_freeImBuf(init_data.mask);
}

View File

@@ -208,6 +208,10 @@ void DocumentImporter::finish()
write_node(roots[i], NULL, sce, NULL, false);
}
}
mesh_importer.optimize_material_assignements();
armature_importer.set_tags_map(this->uid_tags_map);
armature_importer.make_armatures(mContext);

View File

@@ -35,17 +35,19 @@
#include "DocumentExporter.h"
#include "MaterialExporter.h"
#include "DNA_mesh_types.h"
#include "DNA_texture_types.h"
#include "DNA_world_types.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_material.h"
#include "collada_internal.h"
#include "collada_utils.h"
extern "C" {
#include "DNA_mesh_types.h"
#include "DNA_texture_types.h"
#include "DNA_world_types.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_material.h"
}
// OB_MESH is assumed
static std::string getActiveUVLayerName(Object *ob)
{

View File

@@ -42,12 +42,11 @@ extern "C" {
#include "BKE_main.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_customdata.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
}
#include "BKE_customdata.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "collada_internal.h"
#include "collada_utils.h"

View File

@@ -31,13 +31,13 @@
#include "COLLADASWInstanceMaterial.h"
#include "BKE_customdata.h"
#include "BKE_material.h"
#include "DNA_mesh_types.h"
extern "C" {
#include "BKE_customdata.h"
#include "BKE_material.h"
#include "DNA_mesh_types.h"
}
#include "InstanceWriter.h"
#include "collada_internal.h"
#include "collada_utils.h"

View File

@@ -34,11 +34,12 @@
#include "COLLADASWLibraryMaterials.h"
#include "COLLADASWStreamWriter.h"
#include "BKE_material.h"
#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
extern "C" {
#include "BKE_material.h"
#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
}
#include "GeometryExporter.h"
#include "collada_internal.h"

View File

@@ -39,22 +39,22 @@
#include "COLLADAFWPolygons.h"
extern "C" {
#include "BKE_blender.h"
#include "BKE_customdata.h"
#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_blender.h"
#include "BKE_customdata.h"
#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_edgehash.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_edgehash.h"
#include "MEM_guardedalloc.h"
#include "MEM_guardedalloc.h"
}
#include "ArmatureImporter.h"
@@ -988,6 +988,139 @@ MTex *MeshImporter::assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBindi
return color_texture;
}
/**
* this function checks if both objects have the same
* materials assigned to Object (in the same order)
* returns true if condition matches, otherwise false;
**/
static bool bc_has_same_material_configuration(Object *ob1, Object *ob2)
{
if (ob1->totcol != ob2->totcol) return false; // not same number of materials
if (ob1->totcol == 0) return false; // no material at all
for(int index=0; index < ob1->totcol; index++) {
if (ob1->matbits[index] != ob2->matbits[index]) return false; // shouldn't happen
if (ob1->matbits[index] == 0) return false; // shouldn't happen
if (ob1->mat[index] != ob2->mat[index]) return false; // different material assignment
}
return true;
}
/**
*
* Caution here: This code assumes tha all materials are assigned to Object
* and no material is assigned to Data.
* That is true right after the objects have been imported.
*
**/
static void bc_copy_materials_to_data(Object *ob, Mesh *me)
{
for (int index = 0; index < ob->totcol; index++) {
ob->matbits[index] = 0;
me->mat[index] = ob->mat[index];
}
}
/**
*
* Remove all references to materials from the object
*
**/
static void bc_remove_materials_from_object(Object *ob, Mesh *me)
{
for (int index = 0; index < ob->totcol; index++) {
ob->matbits[index] = 0;
ob->mat[index] = NULL;
}
}
/**
* Returns the list of Users of the given Mesh object.
* Note: This function uses the object user flag to control
* which objects have already been processed.
**/
std::vector<Object *> MeshImporter::get_all_users_of(Mesh *reference_mesh)
{
std::vector<Object *> mesh_users;
for (std::vector<Object *>::iterator it = imported_objects.begin();
it != imported_objects.end(); ++it)
{
Object *ob = (*it);
if (bc_is_marked(ob)) {
bc_remove_mark(ob);
Mesh *me = (Mesh *) ob->data;
if (me == reference_mesh)
mesh_users.push_back(ob);
}
}
return mesh_users;
}
/**
*
* During import all materials have been assigned to Object.
* Now we iterate over the imported objects and optimize
* the assignements as follows:
*
* for each imported geometry:
* if number of users is 1:
* get the user (object)
* move the materials from Object to Data
* else:
* determine which materials are assigned to the first user
* check if all other users have the same materials in the same order
* if the check is positive:
* Add the materials of the first user to the geometry
* adjust all other users accordingly.
*
**/
void MeshImporter::optimize_material_assignements()
{
for (std::vector<Object *>::iterator it = imported_objects.begin();
it != imported_objects.end(); ++it)
{
Object *ob = (*it);
Mesh *me = (Mesh *) ob->data;
if (me->id.us==1) {
bc_copy_materials_to_data(ob,me);
bc_remove_materials_from_object(ob,me);
bc_remove_mark(ob);
}
else if (me->id.us > 1)
{
bool can_move = true;
std::vector<Object *> mesh_users = get_all_users_of(me);
if (mesh_users.size() > 1)
{
Object *ref_ob = mesh_users[0];
for (int index = 1; index < mesh_users.size(); index++) {
if (!bc_has_same_material_configuration(ref_ob, mesh_users[index])) {
can_move = false;
break;
}
}
if (can_move) {
bc_copy_materials_to_data(ref_ob,me);
for (int index = 0; index < mesh_users.size(); index++) {
Object *object = mesh_users[index];
bc_remove_materials_from_object(object,me);
bc_remove_mark(object);
}
}
}
}
}
}
/**
* We do not know in advance which objects will share geometries.
* And we do not know either if the objects which share geometries
* come along with different materials. So we first create the objects
* and assign the materials to Object, then in a later cleanup we decide
* 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,
@@ -1003,21 +1136,16 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri
fprintf(stderr, "Cannot find material by UID.\n");
return NULL;
}
// different nodes can point to same geometry, but still also specify the same materials
// again. Make sure we don't overwrite them on the next occurrences, so keep list of
// what we already have handled.
std::multimap<COLLADAFW::UniqueId, COLLADAFW::UniqueId>::iterator it;
it = materials_mapped_to_geom.find(*geom_uid);
while (it != materials_mapped_to_geom.end()) {
if (it->second == ma_uid && it->first == *geom_uid) return NULL; // do nothing if already found
it++;
}
// first time we get geom_uid, ma_uid pair. Save for later check.
materials_mapped_to_geom.insert(std::pair<COLLADAFW::UniqueId, COLLADAFW::UniqueId>(*geom_uid, ma_uid));
Material *ma = uid_material_map[ma_uid];
assign_material(ob, ma, ob->totcol + 1);
// Attention! This temporaly assigns material to object on purpose!
// See note above.
ob->actcol=0;
assign_material(ob, ma, mat_index + 1, BKE_MAT_ASSIGN_OBJECT);
COLLADAFW::TextureCoordinateBindingArray& tex_array =
cmaterial.getTextureCoordinateBindingArray();
@@ -1101,9 +1229,12 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta
// add object
Object *ob = bc_add_object(scene, OB_MESH, name);
bc_set_mark(ob); // used later for material assignement optimization
// store object pointer for ArmatureImporter
uid_object_map[*geom_uid] = ob;
imported_objects.push_back(ob);
// replace ob->data freeing the old one
Mesh *old_mesh = (Mesh *)ob->data;

View File

@@ -40,6 +40,11 @@
#include "COLLADAFWTypes.h"
#include "COLLADAFWUniqueId.h"
#include "ArmatureImporter.h"
#include "collada_utils.h"
extern "C" {
#include "BLI_edgehash.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@@ -47,11 +52,6 @@
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
#include "ArmatureImporter.h"
#include "collada_utils.h"
extern "C" {
#include "BLI_edgehash.h"
}
// only for ArmatureImporter to "see" MeshImporter::get_object_by_geom_uid
@@ -85,6 +85,7 @@ private:
std::map<COLLADAFW::UniqueId, Mesh*> uid_mesh_map; // geometry unique id-to-mesh map
std::map<COLLADAFW::UniqueId, Object*> uid_object_map; // geom uid-to-object
std::vector<Object*> imported_objects; // list of imported objects
// this structure is used to assign material indices to faces
// it holds a portion of Mesh faces and corresponds to a DAE primitive list (<triangles>, <polylist>, etc.)
struct Primitive {
@@ -140,7 +141,9 @@ private:
void get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i, int stride);
bool flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count);
std::vector<Object *> get_all_users_of(Mesh *reference_mesh);
public:
MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Scene *sce);
@@ -152,7 +155,9 @@ public:
MTex *assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture,
Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map,
MTex *color_texture);
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,

View File

@@ -230,6 +230,11 @@ void bc_remove_mark(Object *ob)
ob->id.flag &= ~LIB_DOIT;
}
void bc_set_mark(Object *ob)
{
ob->id.flag |= LIB_DOIT;
}
// Use bubble sort algorithm for sorting the export set
void bc_bubble_sort_by_Object_name(LinkNode *export_set)
{

View File

@@ -67,6 +67,7 @@ extern bool bc_has_object_type(LinkNode *export_set, short obtype);
extern int bc_is_marked(Object *ob);
extern void bc_remove_mark(Object *ob);
extern void bc_set_mark(Object *ob);
extern char *bc_CustomData_get_layer_name(const CustomData *data, int type, int n);
extern char *bc_CustomData_get_active_layer_name(const CustomData *data, int type);

View File

@@ -57,7 +57,7 @@ void InpaintSimpleOperation::initExecution()
this->initMutex();
}
void InpaintSimpleOperation::clamp_xy(int & x, int & y)
void InpaintSimpleOperation::clamp_xy(int &x, int &y)
{
int width = this->getWidth();
int height = this->getHeight();
@@ -97,7 +97,7 @@ int InpaintSimpleOperation::mdist(int x, int y)
return this->m_manhatten_distance[y * width + x];
}
bool InpaintSimpleOperation::next_pixel(int & x, int & y, int & curr, int iters)
bool InpaintSimpleOperation::next_pixel(int &x, int &y, int & curr, int iters)
{
int width = this->getWidth();
@@ -110,7 +110,7 @@ bool InpaintSimpleOperation::next_pixel(int & x, int & y, int & curr, int iters)
x = r % width;
y = r / width;
if (mdist(x, y) > iters) {
if (this->mdist(x, y) > iters) {
return false;
}
@@ -176,11 +176,9 @@ void InpaintSimpleOperation::calc_manhatten_distance()
void InpaintSimpleOperation::pix_step(int x, int y)
{
int d = this->mdist(x, y);
float n = 0;
const int d = this->mdist(x, y);
float pix[3] = {0.0f, 0.0f, 0.0f};
float pix_divider = 0.0f;
for (int dx = -1; dx <= 1; dx++) {
for (int dy = -1; dy <= 1; dy++) {
@@ -202,13 +200,19 @@ void InpaintSimpleOperation::pix_step(int x, int y)
}
madd_v3_v3fl(pix, this->get_pixel(x_ofs, y_ofs), weight);
n += weight;
pix_divider += weight;
}
}
}
}
mul_v3_v3fl(this->get_pixel(x, y), pix, 1.0f / n);
float *output = this->get_pixel(x, y);
if (pix_divider != 0.0f) {
mul_v3_fl(pix, 1.0f / pix_divider);
/* use existing pixels alpha to blend into */
interp_v3_v3v3(output, pix, output, output[3]);
output[3] = 1.0f;
}
this->get_pixel(x, y)[3] = 1.0f;
}
@@ -225,14 +229,14 @@ void *InpaintSimpleOperation::initializeTileData(rcti *rect)
this->m_cached_buffer = new float[this->getWidth() * this->getHeight() * COM_NUMBER_OF_CHANNELS];
memcpy(this->m_cached_buffer, buf->getBuffer(), this->getWidth() * this->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float));
calc_manhatten_distance();
this->calc_manhatten_distance();
int curr = 0;
int x, y;
while (next_pixel(x, y, curr, this->m_iterations)) {
pix_step(x, y);
while (this->next_pixel(x, y, curr, this->m_iterations)) {
this->pix_step(x, y);
}
this->m_cached_buffer_ready = true;
}

View File

@@ -81,19 +81,6 @@ int main(int argc, char **argv)
sprintf(sizest, "%d", (int)size);
#ifdef VERBOSE
printf("Input filesize is %d, Output size should be %d\n",
(int)size,
(int)(((int)size) * 4 +
strlen("/* DataToC output of file <> */\n\n") +
strlen("char datatoc_[] = {\"") +
strlen("\"};\n") +
(strlen(argv[1]) * 3) +
strlen(sizest) +
strlen("int datatoc__size = ;\n") +
(((int)(size / 256) + 1) * 5)));
#endif
fpout = fopen(argv[2], "w");
if (!fpout) {
fprintf(stderr, "Unable to open output <%s>\n", argv[2]);
@@ -104,6 +91,8 @@ int main(int argc, char **argv)
fprintf(fpout, "int datatoc_%s_size = %s;\n", argv[1], sizest);
fprintf(fpout, "char datatoc_%s[] = {\n", argv[1]);
while (size--) {
/* if we want to open in an editor
* this is nicer to avoid very long lines */
#ifdef VERBOSE
if (size % 32 == 31) {
fprintf(fpout, "\n");
@@ -114,7 +103,10 @@ int main(int argc, char **argv)
fprintf(fpout, "%3d,", getc(fpin));
}
fprintf(fpout, "\n};\n\n");
/* trailing NULL terminator, this isnt needed in some cases and
* won't be taken into account by the size variable, but its useful when dealing with
* NULL terminated string data */
fprintf(fpout, "0\n};\n\n");
fclose(fpin);
fclose(fpout);

View File

@@ -1368,7 +1368,7 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
/* new approach, using functions from kernel */
for (a = 0; a < ob_src->totcol; a++) {
Material *ma = give_current_material(ob_src, a + 1);
assign_material(ob_dst, ma, a + 1); /* also works with ma==NULL */
assign_material(ob_dst, ma, a + 1, BKE_MAT_ASSIGN_USERPREF); /* also works with ma==NULL */
}
break;
case MAKE_LINKS_ANIMDATA:
@@ -1692,7 +1692,7 @@ static void single_mat_users(Scene *scene, int flag, int do_textures)
BKE_copy_animdata_id_action(&man->id);
man->id.us = 0;
assign_material(ob, man, a);
assign_material(ob, man, a, BKE_MAT_ASSIGN_USERPREF);
if (do_textures) {
for (b = 0; b < MAX_MTEX; b++) {
@@ -2044,7 +2044,7 @@ static int drop_named_material_invoke(bContext *C, wmOperator *op, wmEvent *even
if (base == NULL || ma == NULL)
return OPERATOR_CANCELLED;
assign_material(base->object, ma, 1);
assign_material(base->object, ma, 1, BKE_MAT_ASSIGN_USERPREF);
DAG_ids_flush_update(bmain, 0);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));

View File

@@ -388,21 +388,22 @@ static int object_select_all_by_library_obdata(bContext *C, Library *lib)
void ED_object_select_linked_by_id(bContext *C, ID *id)
{
int gs = GS(id->name);
int idtype = GS(id->name);
int changed = FALSE;
if (ELEM8(gs, ID_ME, ID_CU, ID_MB, ID_LT, ID_LA, ID_CA, ID_TXT, ID_SPK)) {
if (OB_DATA_SUPPORT_ID(idtype)) {
changed = object_select_all_by_obdata(C, id);
}
else if (gs == ID_MA) {
else if (idtype == ID_MA) {
changed = object_select_all_by_material_texture(C, FALSE, (Material *)id, NULL);
}
else if (gs == ID_LI) {
else if (idtype == ID_LI) {
changed = object_select_all_by_library(C, (Library *) id);
}
if (changed)
if (changed) {
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C));
}
}
static int object_select_linked_exec(bContext *C, wmOperator *op)

View File

@@ -1851,7 +1851,7 @@ static int material_drop_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_CANCELLED;
}
assign_material(ob, ma, ob->totcol + 1);
assign_material(ob, ma, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF);
DAG_ids_flush_update(bmain, 0);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));

View File

@@ -343,6 +343,10 @@ typedef struct DupliObject {
#define OB_TYPE_SUPPORT_EDITMODE(_type) \
(ELEM7(_type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE))
/* is this ID type used as object data */
#define OB_DATA_SUPPORT_ID(_id_type) \
(ELEM8(_id_type, ID_ME, ID_CU, ID_MB, ID_LA, ID_SPK, ID_CA, ID_LT, ID_AR))
/* partype: first 4 bits: type */
#define PARTYPE 15
#define PAROBJECT 0

View File

@@ -140,6 +140,7 @@ Object *rna_Main_objects_new(Main *UNUSED(bmain), ReportList *reports, const cha
Object *ob;
int type = OB_EMPTY;
if (data) {
/* keep in sync with OB_DATA_SUPPORT_ID() macro */
switch (GS(data->name)) {
case ID_ME:
type = OB_MESH;

View File

@@ -355,10 +355,14 @@ static void rna_Object_data_set(PointerRNA *ptr, PointerRNA value)
set_mesh(ob, (Mesh *)id);
}
else {
if (ob->data)
if (ob->data) {
id_us_min((ID *)ob->data);
if (id)
}
if (id) {
/* no need to type-check here ID. this is done in the _typef() function */
BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
id_us_plus(id);
}
ob->data = id;
test_object_materials(id);
@@ -374,6 +378,7 @@ static StructRNA *rna_Object_data_typef(PointerRNA *ptr)
{
Object *ob = (Object *)ptr->data;
/* keep in sync with OB_DATA_SUPPORT_ID() macro */
switch (ob->type) {
case OB_EMPTY: return &RNA_Image;
case OB_MESH: return &RNA_Mesh;
@@ -658,7 +663,7 @@ static void rna_Object_active_material_set(PointerRNA *ptr, PointerRNA value)
Object *ob = (Object *)ptr->id.data;
DAG_id_tag_update(value.data, 0);
assign_material(ob, value.data, ob->actcol);
assign_material(ob, value.data, ob->actcol, BKE_MAT_ASSIGN_USERPREF);
}
static void rna_Object_active_particle_system_index_range(PointerRNA *ptr, int *min, int *max,
@@ -815,7 +820,7 @@ static void rna_MaterialSlot_material_set(PointerRNA *ptr, PointerRNA value)
Object *ob = (Object *)ptr->id.data;
int index = (Material **)ptr->data - ob->mat;
assign_material(ob, value.data, index + 1);
assign_material(ob, value.data, index + 1, BKE_MAT_ASSIGN_USERPREF);
}
static int rna_MaterialSlot_link_get(PointerRNA *ptr)

View File

@@ -632,7 +632,7 @@ int NewBooleanMesh(Scene *scene, Base *base, Base *base_select, int int_op_type)
/* add materials to object */
for (a = 0; a < totmat; a++)
assign_material(ob_new, mat[a], a + 1);
assign_material(ob_new, mat[a], a + 1, BKE_MAT_ASSIGN_USERPREF);
MEM_freeN(mat);