2.5
* Objects now support up to 32767 material slots. It's easy to increase this further, but I prefer not to increase the memory usage of mesh faces, it seems unlikely that someone would create 32767 distinct materials? * Forward compatibility: the only thing you can potentially lose reading a 2.5 file in 2.4 is object linking (instead of default data), though usually that will go fine too. Reading files with > 32 material slots in 2.4 can start giving issues. * The ob->colbits variable is deprecated by the array ob->matbits but I didn't remove the ob->colbits updates in very few places it is set. * I hope I changed all the relevant things, various places just hardcoded the number 16 instead of using the MAXMAT define. * Join Objects operator back. This is using the version from the animsys2 branch coded by Joshua, which means it now supports joining of shape keys. * Fix for crash reading file saved during render.
This commit is contained in:
parent
6fb0181b50
commit
26ef6da24b
|
@ -47,11 +47,11 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel):
|
|||
|
||||
if ob and slot:
|
||||
split.template_ID(slot, "material", new="MATERIAL_OT_new")
|
||||
#split.itemR(ob, "active_material_index", text="Active")
|
||||
row = split.row()
|
||||
row.itemR(slot, "link", expand=True)
|
||||
elif mat:
|
||||
split.template_ID(space, "pin_id")
|
||||
split.itemS()
|
||||
|
||||
|
||||
class MATERIAL_PT_material(MaterialButtonsPanel):
|
||||
__idname__= "MATERIAL_PT_material"
|
||||
|
|
|
@ -1415,11 +1415,6 @@ static void displist_to_mesh(Scene *scene, DispList *dlfirst)
|
|||
return;
|
||||
}
|
||||
|
||||
if(totcol>16) {
|
||||
//XXX error("Found more than 16 different colors");
|
||||
totcol= 16;
|
||||
}
|
||||
|
||||
vec[0]= (min[0]+max[0])/2;
|
||||
vec[1]= (min[1]+max[1])/2;
|
||||
vec[2]= (min[2]+max[2])/2;
|
||||
|
@ -1433,6 +1428,7 @@ static void displist_to_mesh(Scene *scene, DispList *dlfirst)
|
|||
/* colors */
|
||||
if(totcol) {
|
||||
ob->mat= MEM_callocN(sizeof(void *)*totcol, "ob->mat");
|
||||
ob->matbits= MEM_callocN(sizeof(char)*totcol, "ob->matbits");
|
||||
me->mat= MEM_callocN(sizeof(void *)*totcol, "me->mat");
|
||||
me->totcol= totcol;
|
||||
ob->totcol= (unsigned char) me->totcol;
|
||||
|
@ -1482,7 +1478,7 @@ static void displist_to_mesh(Scene *scene, DispList *dlfirst)
|
|||
dl= dlfirst;
|
||||
while(dl) {
|
||||
|
||||
colnr= (dl->col>15 ? 15: dl->col);
|
||||
colnr= dl->col;
|
||||
if(colnr) colnr--;
|
||||
|
||||
if(dl->type==DL_SURF) {
|
||||
|
@ -2804,8 +2800,11 @@ static void dxf_add_mat (Object *ob, Mesh *me, float color[3], char *layer)
|
|||
|
||||
if (!me) return;
|
||||
|
||||
if(ob) ob->mat= MEM_callocN(sizeof(void *)*1, "ob->mat");
|
||||
if(ob) ob->actcol= 1;
|
||||
if(ob) {
|
||||
ob->mat= MEM_callocN(sizeof(void *)*1, "ob->mat");
|
||||
ob->matbits= MEM_callocN(sizeof(char)*1, "ob->matbits");
|
||||
ob->actcol= 1;
|
||||
}
|
||||
|
||||
me->totcol= 1;
|
||||
me->mat= MEM_callocN(sizeof(void *)*1, "me->mat");
|
||||
|
@ -4053,7 +4052,6 @@ static void dxf_read(Scene *scene, char *filename)
|
|||
ob->type= OB_MESH;
|
||||
|
||||
ob->dt= OB_SHADED;
|
||||
if(U.flag & USER_MAT_ON_OB) ob->colbits= -1;
|
||||
|
||||
ob->trackflag= OB_POSY;
|
||||
ob->upflag= OB_POSZ;
|
||||
|
@ -4072,9 +4070,10 @@ static void dxf_read(Scene *scene, char *filename)
|
|||
VECCOPY(ob->rot, obrot);
|
||||
|
||||
ob->mat= MEM_callocN(sizeof(void *)*1, "ob->mat");
|
||||
ob->matbits= MEM_callocN(sizeof(char)*1, "ob->matbits");
|
||||
ob->totcol= (unsigned char) ((Mesh*)ob->data)->totcol;
|
||||
ob->actcol= 1;
|
||||
|
||||
|
||||
/* note: materials are either linked to mesh or object, if both then
|
||||
you have to increase user counts. below line is not needed.
|
||||
I leave it commented out here as warning (ton) */
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_texture_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_arithb.h"
|
||||
|
@ -445,7 +446,7 @@ Material *give_current_material(Object *ob, int act)
|
|||
if(act>ob->totcol) act= ob->totcol;
|
||||
else if(act<=0) act= 1;
|
||||
|
||||
if( BTST(ob->colbits, act-1) ) { /* in object */
|
||||
if(ob->matbits[act-1]) { /* in object */
|
||||
ma= ob->mat[act-1];
|
||||
}
|
||||
else { /* in data */
|
||||
|
@ -473,7 +474,7 @@ ID *material_from(Object *ob, int act)
|
|||
if(ob->totcol==0) return ob->data;
|
||||
if(act==0) act= 1;
|
||||
|
||||
if( BTST(ob->colbits, act-1) ) return (ID *)ob;
|
||||
if(ob->matbits[act-1]) return (ID *)ob;
|
||||
else return ob->data;
|
||||
}
|
||||
|
||||
|
@ -498,6 +499,7 @@ void test_object_materials(ID *id)
|
|||
Curve *cu;
|
||||
MetaBall *mb;
|
||||
Material **newmatar;
|
||||
char *newmatbits;
|
||||
int totcol=0;
|
||||
|
||||
if(id==0) return;
|
||||
|
@ -524,16 +526,22 @@ void test_object_materials(ID *id)
|
|||
if(totcol==0) {
|
||||
if(ob->totcol) {
|
||||
MEM_freeN(ob->mat);
|
||||
ob->mat= 0;
|
||||
MEM_freeN(ob->matbits);
|
||||
ob->mat= NULL;
|
||||
ob->matbits= NULL;
|
||||
}
|
||||
}
|
||||
else if(ob->totcol<totcol) {
|
||||
newmatar= MEM_callocN(sizeof(void *)*totcol, "newmatar");
|
||||
newmatbits= MEM_callocN(sizeof(char)*totcol, "newmatbits");
|
||||
if(ob->totcol) {
|
||||
memcpy(newmatar, ob->mat, sizeof(void *)*ob->totcol);
|
||||
memcpy(newmatbits, ob->matbits, sizeof(char)*ob->totcol);
|
||||
MEM_freeN(ob->mat);
|
||||
MEM_freeN(ob->matbits);
|
||||
}
|
||||
ob->mat= newmatar;
|
||||
ob->matbits= newmatbits;
|
||||
}
|
||||
ob->totcol= totcol;
|
||||
if(ob->totcol && ob->actcol==0) ob->actcol= 1;
|
||||
|
@ -547,6 +555,7 @@ void test_object_materials(ID *id)
|
|||
void assign_material(Object *ob, Material *ma, int act)
|
||||
{
|
||||
Material *mao, **matar, ***matarar;
|
||||
char *matbits;
|
||||
short *totcolp;
|
||||
|
||||
if(act>MAXMAT) return;
|
||||
|
@ -559,29 +568,41 @@ void assign_material(Object *ob, Material *ma, int act)
|
|||
|
||||
if(totcolp==0 || matarar==0) return;
|
||||
|
||||
if( act > *totcolp) {
|
||||
if(act > *totcolp) {
|
||||
matar= MEM_callocN(sizeof(void *)*act, "matarray1");
|
||||
if( *totcolp) {
|
||||
memcpy(matar, *matarar, sizeof(void *)*( *totcolp ));
|
||||
|
||||
if(*totcolp) {
|
||||
memcpy(matar, *matarar, sizeof(void *)*(*totcolp));
|
||||
MEM_freeN(*matarar);
|
||||
}
|
||||
|
||||
*matarar= matar;
|
||||
*totcolp= act;
|
||||
}
|
||||
|
||||
if(act > ob->totcol) {
|
||||
matar= MEM_callocN(sizeof(void *)*act, "matarray2");
|
||||
matbits= MEM_callocN(sizeof(char)*act, "matbits1");
|
||||
if( ob->totcol) {
|
||||
memcpy(matar, ob->mat, sizeof(void *)*( ob->totcol ));
|
||||
memcpy(matbits, ob->matbits, sizeof(char)*(*totcolp));
|
||||
MEM_freeN(ob->mat);
|
||||
MEM_freeN(ob->matbits);
|
||||
}
|
||||
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( BTST(ob->colbits, act-1) ) { /* in object */
|
||||
if(ob->matbits[act-1]) { /* in object */
|
||||
mao= ob->mat[act-1];
|
||||
if(mao) mao->id.us--;
|
||||
ob->mat[act-1]= ma;
|
||||
|
@ -591,6 +612,7 @@ void assign_material(Object *ob, Material *ma, int act)
|
|||
if(mao) mao->id.us--;
|
||||
(*matarar)[act-1]= ma;
|
||||
}
|
||||
|
||||
id_us_plus((ID *)ma);
|
||||
test_object_materials(ob->data);
|
||||
}
|
||||
|
@ -630,12 +652,6 @@ void object_add_material_slot(Object *ob)
|
|||
|
||||
ma->id.us= 0; /* eeh... */
|
||||
|
||||
if(ob->actcol) {
|
||||
if( BTST(ob->colbits, ob->actcol-1) ) {
|
||||
ob->colbits= BSET(ob->colbits, ob->totcol);
|
||||
}
|
||||
}
|
||||
|
||||
assign_material(ob, ma, ob->totcol+1);
|
||||
ob->actcol= ob->totcol;
|
||||
}
|
||||
|
@ -880,9 +896,8 @@ void object_remove_material_slot(Object *ob)
|
|||
if(mao) mao->id.us--;
|
||||
}
|
||||
|
||||
for(a=ob->actcol; a<ob->totcol; a++) {
|
||||
for(a=ob->actcol; a<ob->totcol; a++)
|
||||
(*matarar)[a-1]= (*matarar)[a];
|
||||
}
|
||||
(*totcolp)--;
|
||||
|
||||
if(*totcolp==0) {
|
||||
|
@ -900,13 +915,18 @@ void object_remove_material_slot(Object *ob)
|
|||
mao= obt->mat[actcol-1];
|
||||
if(mao) mao->id.us--;
|
||||
|
||||
for(a=actcol; a<obt->totcol; a++) obt->mat[a-1]= obt->mat[a];
|
||||
for(a=actcol; a<obt->totcol; a++) {
|
||||
obt->mat[a-1]= obt->mat[a];
|
||||
obt->matbits[a-1]= obt->matbits[a];
|
||||
}
|
||||
obt->totcol--;
|
||||
if(obt->actcol > obt->totcol) obt->actcol= obt->totcol;
|
||||
|
||||
if(obt->totcol==0) {
|
||||
MEM_freeN(obt->mat);
|
||||
MEM_freeN(obt->matbits);
|
||||
obt->mat= 0;
|
||||
obt->matbits= NULL;
|
||||
}
|
||||
}
|
||||
obt= obt->id.next;
|
||||
|
|
|
@ -243,7 +243,9 @@ void free_object(Object *ob)
|
|||
if(ob->mat[a]) ob->mat[a]->id.us--;
|
||||
}
|
||||
if(ob->mat) MEM_freeN(ob->mat);
|
||||
if(ob->matbits) MEM_freeN(ob->matbits);
|
||||
ob->mat= 0;
|
||||
ob->matbits= 0;
|
||||
if(ob->bb) MEM_freeN(ob->bb);
|
||||
ob->bb= 0;
|
||||
if(ob->path) free_path(ob->path);
|
||||
|
@ -942,7 +944,6 @@ Object *add_only_object(int type, char *name)
|
|||
Mat4One(ob->parentinv);
|
||||
Mat4One(ob->obmat);
|
||||
ob->dt= OB_SHADED;
|
||||
if(U.flag & USER_MAT_ON_OB) ob->colbits= -1;
|
||||
ob->empty_drawtype= OB_ARROWS;
|
||||
ob->empty_drawsize= 1.0;
|
||||
|
||||
|
@ -1170,6 +1171,7 @@ Object *copy_object(Object *ob)
|
|||
|
||||
if(ob->totcol) {
|
||||
obn->mat= MEM_dupallocN(ob->mat);
|
||||
obn->matbits= MEM_dupallocN(ob->matbits);
|
||||
}
|
||||
|
||||
if(ob->bb) obn->bb= MEM_dupallocN(ob->bb);
|
||||
|
@ -1397,7 +1399,9 @@ void object_make_proxy(Object *ob, Object *target, Object *gob)
|
|||
/* copy material and index information */
|
||||
ob->actcol= ob->totcol= 0;
|
||||
if(ob->mat) MEM_freeN(ob->mat);
|
||||
if(ob->matbits) MEM_freeN(ob->matbits);
|
||||
ob->mat = NULL;
|
||||
ob->matbits= NULL;
|
||||
if ((target->totcol) && (target->mat) && ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) { //XXX OB_SUPPORT_MATERIAL
|
||||
int i;
|
||||
ob->colbits = target->colbits;
|
||||
|
@ -1406,6 +1410,7 @@ void object_make_proxy(Object *ob, Object *target, Object *gob)
|
|||
ob->totcol= target->totcol;
|
||||
|
||||
ob->mat = MEM_dupallocN(target->mat);
|
||||
ob->matbits = MEM_dupallocN(target->matbits);
|
||||
for(i=0; i<target->totcol; i++) {
|
||||
/* dont need to run test_object_materials since we know this object is new and not used elsewhere */
|
||||
id_us_plus((ID *)ob->mat[i]);
|
||||
|
|
|
@ -784,7 +784,7 @@ Tex *give_current_texture(Object *ob, int act)
|
|||
if(act>ob->totcol) act= ob->totcol;
|
||||
else if(act==0) act= 1;
|
||||
|
||||
if( BTST(ob->colbits, act-1) ) { /* in object */
|
||||
if(ob->matbits[act-1]) { /* in object */
|
||||
ma= ob->mat[act-1];
|
||||
}
|
||||
else { /* in data */
|
||||
|
|
|
@ -125,10 +125,11 @@ typedef struct EditFace
|
|||
float fp;
|
||||
} tmp;
|
||||
float n[3], cent[3];
|
||||
unsigned char mat_nr, flag;
|
||||
unsigned char flag;
|
||||
unsigned char f, f1, h;
|
||||
unsigned char fast; /* only 0 or 1, for editmesh_fastmalloc */
|
||||
unsigned char fgonf; /* flag for fgon options */
|
||||
short mat_nr;
|
||||
void *data; /* custom face data */
|
||||
} EditFace;
|
||||
|
||||
|
|
|
@ -3732,6 +3732,7 @@ static void direct_link_object(FileData *fd, Object *ob)
|
|||
|
||||
ob->mat= newdataadr(fd, ob->mat);
|
||||
test_pointer_array(fd, (void **)&ob->mat);
|
||||
ob->matbits= newdataadr(fd, ob->matbits);
|
||||
|
||||
/* do it here, below old data gets converted */
|
||||
direct_link_modifiers(fd, &ob->modifiers);
|
||||
|
@ -4221,6 +4222,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
|
|||
wm->paintcursors.first= wm->paintcursors.last= NULL;
|
||||
wm->queue.first= wm->queue.last= NULL;
|
||||
wm->reports.first= wm->reports.last= NULL;
|
||||
wm->jobs.first= wm->jobs.last= NULL;
|
||||
|
||||
wm->windrawable= NULL;
|
||||
wm->initialized= 0;
|
||||
|
@ -9242,6 +9244,14 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
|||
|
||||
ob->data = olddata;
|
||||
}
|
||||
|
||||
if(ob->totcol && ob->matbits == NULL) {
|
||||
int a;
|
||||
|
||||
ob->matbits= MEM_callocN(sizeof(char)*ob->totcol, "ob->matbits");
|
||||
for(a=0; a<ob->totcol; a++)
|
||||
ob->matbits[a]= ob->colbits & (1<<a);
|
||||
}
|
||||
}
|
||||
|
||||
for(ma = main->mat.first; ma; ma = ma->id.next) {
|
||||
|
|
|
@ -1131,6 +1131,7 @@ static void write_objects(WriteData *wd, ListBase *idbase, int write_undo)
|
|||
|
||||
/* direct data */
|
||||
writedata(wd, DATA, sizeof(void *)*ob->totcol, ob->mat);
|
||||
writedata(wd, DATA, sizeof(char)*ob->totcol, ob->matbits);
|
||||
/* write_effects(wd, &ob->effect); */ /* not used anymore */
|
||||
write_properties(wd, &ob->prop);
|
||||
write_sensors(wd, &ob->sensors);
|
||||
|
|
|
@ -669,24 +669,21 @@ static void joined_armature_fix_links(Object *tarArm, Object *srcArm, bPoseChann
|
|||
}
|
||||
}
|
||||
|
||||
int join_armature(Scene *scene, View3D *v3d)
|
||||
int join_armature_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob= scene->basact->object; // XXX context
|
||||
bArmature *arm= ob->data;
|
||||
Base *base, *nextbase;
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
Object *ob= CTX_data_active_object(C);
|
||||
bArmature *arm= (ob)? ob->data: NULL;
|
||||
bPose *pose, *opose;
|
||||
bPoseChannel *pchan, *pchann;
|
||||
EditBone *curbone;
|
||||
float mat[4][4], oimat[4][4];
|
||||
|
||||
/* Ensure we're not in editmode and that the active object is an armature*/
|
||||
if (ob->type!=OB_ARMATURE) return 0;
|
||||
if (arm->edbo) return 0;
|
||||
|
||||
if (object_data_is_libdata(ob)) {
|
||||
error_libdata();
|
||||
return 0;
|
||||
}
|
||||
if (!ob || ob->type!=OB_ARMATURE)
|
||||
return OPERATOR_CANCELLED;
|
||||
if (!arm || arm->edbo)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
/* Get editbones of active armature to add editbones to */
|
||||
ED_armature_to_edit(ob);
|
||||
|
@ -694,89 +691,89 @@ int join_armature(Scene *scene, View3D *v3d)
|
|||
/* get pose of active object and move it out of posemode */
|
||||
pose= ob->pose;
|
||||
ob->flag &= ~OB_POSEMODE;
|
||||
|
||||
for (base=FIRSTBASE; base; base=nextbase) {
|
||||
nextbase = base->next;
|
||||
if (TESTBASE(v3d, base)){
|
||||
if ((base->object->type==OB_ARMATURE) && (base->object!=ob)) {
|
||||
bArmature *curarm= base->object->data;
|
||||
|
||||
CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
|
||||
if ((base->object->type==OB_ARMATURE) && (base->object!=ob)) {
|
||||
bArmature *curarm= base->object->data;
|
||||
|
||||
/* Make a list of editbones in current armature */
|
||||
ED_armature_to_edit(base->object);
|
||||
|
||||
/* Get Pose of current armature */
|
||||
opose= base->object->pose;
|
||||
base->object->flag &= ~OB_POSEMODE;
|
||||
BASACT->flag &= ~OB_POSEMODE;
|
||||
|
||||
/* Find the difference matrix */
|
||||
Mat4Invert(oimat, ob->obmat);
|
||||
Mat4MulMat4(mat, base->object->obmat, oimat);
|
||||
|
||||
/* Copy bones and posechannels from the object to the edit armature */
|
||||
for (pchan=opose->chanbase.first; pchan; pchan=pchann) {
|
||||
pchann= pchan->next;
|
||||
curbone= editbone_name_exists(curarm->edbo, pchan->name);
|
||||
|
||||
/* Make a list of editbones in current armature */
|
||||
ED_armature_to_edit(base->object);
|
||||
/* Get new name */
|
||||
unique_editbone_name(arm->edbo, curbone->name, NULL);
|
||||
|
||||
/* Get Pose of current armature */
|
||||
opose= base->object->pose;
|
||||
base->object->flag &= ~OB_POSEMODE;
|
||||
BASACT->flag &= ~OB_POSEMODE;
|
||||
|
||||
/* Find the difference matrix */
|
||||
Mat4Invert(oimat, ob->obmat);
|
||||
Mat4MulMat4(mat, base->object->obmat, oimat);
|
||||
|
||||
/* Copy bones and posechannels from the object to the edit armature */
|
||||
for (pchan=opose->chanbase.first; pchan; pchan=pchann) {
|
||||
pchann= pchan->next;
|
||||
curbone= editbone_name_exists(curarm->edbo, pchan->name);
|
||||
/* Transform the bone */
|
||||
{
|
||||
float premat[4][4];
|
||||
float postmat[4][4];
|
||||
float difmat[4][4];
|
||||
float imat[4][4];
|
||||
float temp[3][3];
|
||||
float delta[3];
|
||||
|
||||
/* Get new name */
|
||||
unique_editbone_name(arm->edbo, curbone->name, NULL);
|
||||
/* Get the premat */
|
||||
VecSubf(delta, curbone->tail, curbone->head);
|
||||
vec_roll_to_mat3(delta, curbone->roll, temp);
|
||||
|
||||
/* Transform the bone */
|
||||
{
|
||||
float premat[4][4];
|
||||
float postmat[4][4];
|
||||
float difmat[4][4];
|
||||
float imat[4][4];
|
||||
float temp[3][3];
|
||||
float delta[3];
|
||||
|
||||
/* Get the premat */
|
||||
VecSubf(delta, curbone->tail, curbone->head);
|
||||
vec_roll_to_mat3(delta, curbone->roll, temp);
|
||||
|
||||
Mat4One(premat); /* Mat4MulMat34 only sets 3x3 part */
|
||||
Mat4MulMat34(premat, temp, mat);
|
||||
|
||||
Mat4MulVecfl(mat, curbone->head);
|
||||
Mat4MulVecfl(mat, curbone->tail);
|
||||
|
||||
/* Get the postmat */
|
||||
VecSubf(delta, curbone->tail, curbone->head);
|
||||
vec_roll_to_mat3(delta, curbone->roll, temp);
|
||||
Mat4CpyMat3(postmat, temp);
|
||||
|
||||
/* Find the roll */
|
||||
Mat4Invert(imat, premat);
|
||||
Mat4MulMat4(difmat, postmat, imat);
|
||||
|
||||
curbone->roll -= (float)atan2(difmat[2][0], difmat[2][2]);
|
||||
}
|
||||
Mat4One(premat); /* Mat4MulMat34 only sets 3x3 part */
|
||||
Mat4MulMat34(premat, temp, mat);
|
||||
|
||||
/* Fix Constraints and Other Links to this Bone and Armature */
|
||||
joined_armature_fix_links(ob, base->object, pchan, curbone);
|
||||
Mat4MulVecfl(mat, curbone->head);
|
||||
Mat4MulVecfl(mat, curbone->tail);
|
||||
|
||||
/* Rename pchan */
|
||||
BLI_strncpy(pchan->name, curbone->name, sizeof(pchan->name));
|
||||
/* Get the postmat */
|
||||
VecSubf(delta, curbone->tail, curbone->head);
|
||||
vec_roll_to_mat3(delta, curbone->roll, temp);
|
||||
Mat4CpyMat3(postmat, temp);
|
||||
|
||||
/* Jump Ship! */
|
||||
BLI_remlink(curarm->edbo, curbone);
|
||||
BLI_addtail(arm->edbo, curbone);
|
||||
/* Find the roll */
|
||||
Mat4Invert(imat, premat);
|
||||
Mat4MulMat4(difmat, postmat, imat);
|
||||
|
||||
BLI_remlink(&opose->chanbase, pchan);
|
||||
BLI_addtail(&pose->chanbase, pchan);
|
||||
curbone->roll -= (float)atan2(difmat[2][0], difmat[2][2]);
|
||||
}
|
||||
|
||||
ED_base_object_free_and_unlink(scene, base);
|
||||
/* Fix Constraints and Other Links to this Bone and Armature */
|
||||
joined_armature_fix_links(ob, base->object, pchan, curbone);
|
||||
|
||||
/* Rename pchan */
|
||||
BLI_strncpy(pchan->name, curbone->name, sizeof(pchan->name));
|
||||
|
||||
/* Jump Ship! */
|
||||
BLI_remlink(curarm->edbo, curbone);
|
||||
BLI_addtail(arm->edbo, curbone);
|
||||
|
||||
BLI_remlink(&opose->chanbase, pchan);
|
||||
BLI_addtail(&pose->chanbase, pchan);
|
||||
}
|
||||
|
||||
ED_base_object_free_and_unlink(scene, base);
|
||||
}
|
||||
}
|
||||
CTX_DATA_END;
|
||||
|
||||
DAG_scene_sort(scene); // because we removed object(s)
|
||||
|
||||
ED_armature_from_edit(scene, ob);
|
||||
ED_armature_edit_free(ob);
|
||||
|
||||
WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene);
|
||||
|
||||
return 1;
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
/* Helper function for armature separating - link fixing */
|
||||
|
|
|
@ -4594,12 +4594,10 @@ void CURVE_OT_smooth_set(wmOperatorType *ot)
|
|||
|
||||
/************** join operator, to be used externally? ****************/
|
||||
|
||||
int join_curve(bContext *C, wmOperator *op, int type)
|
||||
int join_curve_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
View3D *v3d= CTX_wm_view3d(C);
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
Object *ob= CTX_data_edit_object(C);
|
||||
Base *base, *nextb;
|
||||
Object *ob= CTX_data_active_object(C);
|
||||
Curve *cu;
|
||||
Nurb *nu, *newnu;
|
||||
BezTriple *bezt;
|
||||
|
@ -4608,64 +4606,51 @@ int join_curve(bContext *C, wmOperator *op, int type)
|
|||
float imat[4][4], cmat[4][4];
|
||||
int a;
|
||||
|
||||
// XXX not integrated yet, to be called by object/ module? */
|
||||
|
||||
if(object_data_is_libdata(ob)) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Can't edit external libdata");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if(ob->type!=type)
|
||||
return 0;
|
||||
|
||||
tempbase.first= tempbase.last= 0;
|
||||
|
||||
/* trasnform all selected curves inverse in obact */
|
||||
Mat4Invert(imat, ob->obmat);
|
||||
|
||||
for(base= FIRSTBASE; base; base=nextb) {
|
||||
nextb= base->next;
|
||||
|
||||
if(TESTBASE(v3d, base)) {
|
||||
if(base->object->type==type) {
|
||||
if(base->object != ob) {
|
||||
|
||||
cu= base->object->data;
|
||||
|
||||
if(cu->nurb.first) {
|
||||
/* watch it: switch order here really goes wrong */
|
||||
Mat4MulMat4(cmat, base->object->obmat, imat);
|
||||
CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
|
||||
if(base->object->type==ob->type) {
|
||||
if(base->object != ob) {
|
||||
|
||||
cu= base->object->data;
|
||||
|
||||
if(cu->nurb.first) {
|
||||
/* watch it: switch order here really goes wrong */
|
||||
Mat4MulMat4(cmat, base->object->obmat, imat);
|
||||
|
||||
nu= cu->nurb.first;
|
||||
while(nu) {
|
||||
newnu= duplicateNurb(nu);
|
||||
BLI_addtail(&tempbase, newnu);
|
||||
|
||||
nu= cu->nurb.first;
|
||||
while(nu) {
|
||||
newnu= duplicateNurb(nu);
|
||||
BLI_addtail(&tempbase, newnu);
|
||||
|
||||
if( (bezt= newnu->bezt) ) {
|
||||
a= newnu->pntsu;
|
||||
while(a--) {
|
||||
Mat4MulVecfl(cmat, bezt->vec[0]);
|
||||
Mat4MulVecfl(cmat, bezt->vec[1]);
|
||||
Mat4MulVecfl(cmat, bezt->vec[2]);
|
||||
bezt++;
|
||||
}
|
||||
if( (bezt= newnu->bezt) ) {
|
||||
a= newnu->pntsu;
|
||||
while(a--) {
|
||||
Mat4MulVecfl(cmat, bezt->vec[0]);
|
||||
Mat4MulVecfl(cmat, bezt->vec[1]);
|
||||
Mat4MulVecfl(cmat, bezt->vec[2]);
|
||||
bezt++;
|
||||
}
|
||||
if( (bp= newnu->bp) ) {
|
||||
a= newnu->pntsu*nu->pntsv;
|
||||
while(a--) {
|
||||
Mat4MulVecfl(cmat, bp->vec);
|
||||
bp++;
|
||||
}
|
||||
}
|
||||
nu= nu->next;
|
||||
}
|
||||
if( (bp= newnu->bp) ) {
|
||||
a= newnu->pntsu*nu->pntsv;
|
||||
while(a--) {
|
||||
Mat4MulVecfl(cmat, bp->vec);
|
||||
bp++;
|
||||
}
|
||||
}
|
||||
nu= nu->next;
|
||||
}
|
||||
|
||||
ED_base_object_free_and_unlink(scene, base);
|
||||
}
|
||||
|
||||
ED_base_object_free_and_unlink(scene, base);
|
||||
}
|
||||
}
|
||||
}
|
||||
CTX_DATA_END;
|
||||
|
||||
cu= ob->data;
|
||||
addlisttolist(&cu->nurb, &tempbase);
|
||||
|
@ -4674,8 +4659,8 @@ int join_curve(bContext *C, wmOperator *op, int type)
|
|||
|
||||
ED_object_enter_editmode(C, EM_WAITCURSOR);
|
||||
ED_object_exit_editmode(C, EM_FREEDATA|EM_WAITCURSOR);
|
||||
|
||||
// BIF_undo_push("Join");
|
||||
|
||||
WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ struct Base;
|
|||
struct Bone;
|
||||
struct bArmature;
|
||||
struct bPoseChannel;
|
||||
struct wmOperator;
|
||||
struct wmWindowManager;
|
||||
struct ListBase;
|
||||
struct View3D;
|
||||
|
@ -100,6 +101,7 @@ void ED_armature_edit_remake(struct Object *obedit);
|
|||
int ED_do_pose_selectbuffer(struct Scene *scene, struct Base *base, unsigned int *buffer,
|
||||
short hits, short extend);
|
||||
void mouse_armature(struct bContext *C, short mval[2], int extend);
|
||||
int join_armature_exec(struct bContext *C, struct wmOperator *op);
|
||||
struct Bone *get_indexed_bone (struct Object *ob, int index);
|
||||
float ED_rollBoneToVector(EditBone *bone, float new_up_axis[3]);
|
||||
EditBone *ED_armature_bone_get_mirrored(struct ListBase *edbo, EditBone *ebo); // XXX this is needed for populating the context iterators
|
||||
|
|
|
@ -35,6 +35,7 @@ struct Object;
|
|||
struct Scene;
|
||||
struct Text;
|
||||
struct View3D;
|
||||
struct wmOperator;
|
||||
struct wmWindowManager;
|
||||
|
||||
/* curve_ops.c */
|
||||
|
@ -55,6 +56,8 @@ struct Nurb *add_nurbs_primitive(struct bContext *C, int type, int newname);
|
|||
|
||||
int isNurbsel (struct Nurb *nu);;
|
||||
|
||||
int join_curve_exec (struct bContext *C, struct wmOperator *op);
|
||||
|
||||
/* editfont.h */
|
||||
void undo_push_font (struct bContext *C, char *name);
|
||||
void make_editText (struct Object *obedit);
|
||||
|
|
|
@ -36,6 +36,7 @@ struct EditVert;
|
|||
struct EditEdge;
|
||||
struct EditFace;
|
||||
struct bContext;
|
||||
struct wmOperator;
|
||||
struct wmWindowManager;
|
||||
struct EditSelection;
|
||||
struct ViewContext;
|
||||
|
@ -76,6 +77,8 @@ struct EditVert *editmesh_get_x_mirror_vert(struct Object *ob, struct EditMesh
|
|||
int mesh_get_x_mirror_vert(struct Object *ob, int index);
|
||||
int *mesh_get_x_mirror_faces(struct Object *ob, struct EditMesh *em);
|
||||
|
||||
int join_mesh_exec(struct bContext *C, struct wmOperator *op);
|
||||
|
||||
/* mesh_ops.c */
|
||||
void ED_operatortypes_mesh(void);
|
||||
void ED_keymap_mesh(struct wmWindowManager *wm);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
/* ******************* Registration Function ********************** */
|
||||
|
||||
struct wmWindowManager;
|
||||
struct wmOperatorType;
|
||||
struct ListBase;
|
||||
struct wmEvent;
|
||||
struct bContext;
|
||||
|
|
|
@ -1132,7 +1132,7 @@ void load_editMesh(Scene *scene, Object *ob)
|
|||
else
|
||||
VECCOPY(mvert->co, eve->co);
|
||||
|
||||
mvert->mat_nr= 255; /* what was this for, halos? */
|
||||
mvert->mat_nr= 32767; /* what was this for, halos? */
|
||||
|
||||
/* vertex normal */
|
||||
VECCOPY(nor, eve->no);
|
||||
|
@ -1218,14 +1218,14 @@ void load_editMesh(Scene *scene, Object *ob)
|
|||
/* mat_nr in vertex */
|
||||
if(me->totcol>1) {
|
||||
mvert= me->mvert+mface->v1;
|
||||
if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr;
|
||||
if(mvert->mat_nr == (char)32767) mvert->mat_nr= mface->mat_nr;
|
||||
mvert= me->mvert+mface->v2;
|
||||
if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr;
|
||||
if(mvert->mat_nr == (char)32767) mvert->mat_nr= mface->mat_nr;
|
||||
mvert= me->mvert+mface->v3;
|
||||
if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr;
|
||||
if(mvert->mat_nr == (char)32767) mvert->mat_nr= mface->mat_nr;
|
||||
if(mface->v4) {
|
||||
mvert= me->mvert+mface->v4;
|
||||
if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr;
|
||||
if(mvert->mat_nr == (char)32767) mvert->mat_nr= mface->mat_nr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1669,8 +1669,8 @@ typedef struct EditEdgeC
|
|||
typedef struct EditFaceC
|
||||
{
|
||||
int v1, v2, v3, v4;
|
||||
unsigned char mat_nr, flag, f, h, fgonf;
|
||||
short pad1;
|
||||
unsigned char flag, f, h, fgonf, pad1;
|
||||
short mat_nr;
|
||||
} EditFaceC;
|
||||
|
||||
typedef struct EditSelectionC{
|
||||
|
|
|
@ -38,16 +38,17 @@
|
|||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_image_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
#include "DNA_world_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
#include "DNA_world_types.h"
|
||||
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_blenlib.h"
|
||||
|
@ -58,10 +59,12 @@
|
|||
|
||||
|
||||
#include "BKE_blender.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_mesh.h"
|
||||
|
@ -86,15 +89,13 @@
|
|||
#include "ED_object.h"
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
/* own include */
|
||||
#include "mesh_intern.h"
|
||||
|
||||
|
||||
/* from rendercode.c */
|
||||
#define VECMUL(dest, f) dest[0]*= f; dest[1]*= f; dest[2]*= f
|
||||
|
||||
/* XXX */
|
||||
static void BIF_undo_push() {}
|
||||
static void waitcursor() {}
|
||||
static void error() {}
|
||||
static int pupmenu() {return 0;}
|
||||
|
@ -103,145 +104,189 @@ static int pupmenu() {return 0;}
|
|||
|
||||
/* * ********************** no editmode!!! *********** */
|
||||
|
||||
/*********************** JOIN ***************************/
|
||||
|
||||
/* join selected meshes into the active mesh, context sensitive
|
||||
return 0 if no join is made (error) and 1 of the join is done */
|
||||
|
||||
// XXX NOTE to whoever ports this:
|
||||
// Check the version of this code in the animsys2 branch, which has been nicely commented,
|
||||
// but more importantly has proper support for handling meshes with shapekeys (instead of lamely bailing out)!
|
||||
// -- Aligorith, July 2009
|
||||
int join_mesh(Scene *scene, View3D *v3d, wmOperator *op)
|
||||
int join_mesh_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Base *base, *nextb;
|
||||
Object *ob;
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
Object *ob= CTX_data_active_object(C);
|
||||
Material **matar, *ma;
|
||||
Mesh *me;
|
||||
MVert *mvert, *mvertmain;
|
||||
MVert *mvert, *mv, *mvertmain;
|
||||
MEdge *medge = NULL, *medgemain;
|
||||
MFace *mface = NULL, *mfacemain;
|
||||
float imat[4][4], cmat[4][4];
|
||||
int a, b, totcol, totedge=0, totvert=0, totface=0, ok=0, vertofs, map[MAXMAT];
|
||||
int i, j, index, haskey=0, hasmulti=0, edgeofs, faceofs;
|
||||
Key *key, *nkey=NULL;
|
||||
KeyBlock *kb, *okb, *kbn;
|
||||
float imat[4][4], cmat[4][4], *fp1, *fp2, curpos;
|
||||
int a, b, totcol, totmat=0, totedge=0, totvert=0, totface=0, ok=0;
|
||||
int vertofs, *matmap;
|
||||
int i, j, index, haskey=0, edgeofs, faceofs;
|
||||
bDeformGroup *dg, *odg;
|
||||
MDeformVert *dvert;
|
||||
CustomData vdata, edata, fdata;
|
||||
|
||||
if(scene->obedit) return 0;
|
||||
if(scene->obedit)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
ob= OBACT;
|
||||
if(!ob || ob->type!=OB_MESH) return 0;
|
||||
/* ob is the object we are adding geometry to */
|
||||
if(!ob || ob->type!=OB_MESH)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
if (object_data_is_libdata(ob)) {
|
||||
// XXX error_libdata();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* count & check */
|
||||
base= FIRSTBASE;
|
||||
while(base) {
|
||||
if(TESTBASELIB_BGMODE(base)) { /* BGMODE since python can access */
|
||||
if(base->object->type==OB_MESH) {
|
||||
me= base->object->data;
|
||||
totvert+= me->totvert;
|
||||
totface+= me->totface;
|
||||
|
||||
if(base->object == ob) ok= 1;
|
||||
|
||||
if(me->key) {
|
||||
haskey= 1;
|
||||
break;
|
||||
}
|
||||
if(me->mr) {
|
||||
hasmulti= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
|
||||
if(base->object->type==OB_MESH) {
|
||||
me= base->object->data;
|
||||
|
||||
totvert+= me->totvert;
|
||||
totedge+= me->totedge;
|
||||
totface+= me->totface;
|
||||
totmat+= base->object->totcol;
|
||||
|
||||
if(base->object == ob)
|
||||
ok= 1;
|
||||
|
||||
/* check for shapekeys */
|
||||
if(me->key)
|
||||
haskey++;
|
||||
}
|
||||
base= base->next;
|
||||
}
|
||||
CTX_DATA_END;
|
||||
|
||||
if(haskey) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Can't join meshes with vertex keys");
|
||||
return 0;
|
||||
}
|
||||
if(hasmulti) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Can't join meshes with Multires");
|
||||
return 0;
|
||||
}
|
||||
/* that way the active object is always selected */
|
||||
if(ok==0) return 0;
|
||||
if(ok==0)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
if(totvert==0 || totvert>MESH_MAX_VERTS) return 0;
|
||||
|
||||
/* if needed add edges to other meshes */
|
||||
for(base= FIRSTBASE; base; base= base->next) {
|
||||
if(TESTBASELIB_BGMODE(base)) {
|
||||
if(base->object->type==OB_MESH) {
|
||||
me= base->object->data;
|
||||
totedge += me->totedge;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* only join meshes if there are verts to join, there aren't too many, and we only had one mesh selected */
|
||||
me= (Mesh *)ob->data;
|
||||
key= me->key;
|
||||
if(totvert==0 || totvert>MESH_MAX_VERTS || totvert==me->totvert)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
/* new material indices and material array */
|
||||
matar= MEM_callocN(sizeof(void *)*MAXMAT, "join_mesh");
|
||||
matar= MEM_callocN(sizeof(void*)*totmat, "join_mesh matar");
|
||||
matmap= MEM_callocN(sizeof(int)*totmat, "join_mesh matmap");
|
||||
totcol= ob->totcol;
|
||||
|
||||
/* obact materials in new main array, is nicer start! */
|
||||
for(a=1; a<=ob->totcol; a++) {
|
||||
matar[a-1]= give_current_material(ob, a);
|
||||
id_us_plus((ID *)matar[a-1]);
|
||||
for(a=0; a<ob->totcol; a++) {
|
||||
matar[a]= give_current_material(ob, a+1);
|
||||
id_us_plus((ID *)matar[a]);
|
||||
/* increase id->us : will be lowered later */
|
||||
}
|
||||
|
||||
base= FIRSTBASE;
|
||||
while(base) {
|
||||
if(TESTBASELIB_BGMODE(base)) {
|
||||
if(ob!=base->object && base->object->type==OB_MESH) {
|
||||
me= base->object->data;
|
||||
|
||||
// Join this object's vertex groups to the base one's
|
||||
for (dg=base->object->defbase.first; dg; dg=dg->next){
|
||||
/* See if this group exists in the object */
|
||||
for (odg=ob->defbase.first; odg; odg=odg->next){
|
||||
if (!strcmp(odg->name, dg->name)){
|
||||
break;
|
||||
}
|
||||
/* - if destination mesh had shapekeys, move them somewhere safe, and set up placeholders
|
||||
* with arrays that are large enough to hold shapekey data for all meshes
|
||||
* - if destination mesh didn't have shapekeys, but we encountered some in the meshes we're
|
||||
* joining, set up a new keyblock and assign to the mesh
|
||||
*/
|
||||
if(key) {
|
||||
/* make a duplicate copy that will only be used here... (must remember to free it!) */
|
||||
nkey= copy_key(key);
|
||||
|
||||
/* for all keys in old block, clear data-arrays */
|
||||
for(kb= key->block.first; kb; kb= kb->next) {
|
||||
if(kb->data) MEM_freeN(kb->data);
|
||||
kb->data= MEM_callocN(sizeof(float)*3*totvert, "join_shapekey");
|
||||
kb->totelem= totvert;
|
||||
kb->weights= NULL;
|
||||
}
|
||||
}
|
||||
else if(haskey) {
|
||||
/* add a new key-block and add to the mesh */
|
||||
key= me->key= add_key((ID *)me);
|
||||
key->type = KEY_RELATIVE;
|
||||
}
|
||||
|
||||
/* first pass over objects - copying materials and vertexgroups across */
|
||||
CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
|
||||
/* only act if a mesh, and not the one we're joining to */
|
||||
if((ob!=base->object) && (base->object->type==OB_MESH)) {
|
||||
me= base->object->data;
|
||||
|
||||
/* Join this object's vertex groups to the base one's */
|
||||
for(dg=base->object->defbase.first; dg; dg=dg->next) {
|
||||
/* See if this group exists in the object (if it doesn't, add it to the end) */
|
||||
for(odg=ob->defbase.first; odg; odg=odg->next) {
|
||||
if(!strcmp(odg->name, dg->name)) {
|
||||
break;
|
||||
}
|
||||
if (!odg){
|
||||
odg = MEM_callocN (sizeof(bDeformGroup), "join deformGroup");
|
||||
memcpy (odg, dg, sizeof(bDeformGroup));
|
||||
BLI_addtail(&ob->defbase, odg);
|
||||
}
|
||||
|
||||
}
|
||||
if (ob->defbase.first && ob->actdef==0)
|
||||
ob->actdef=1;
|
||||
|
||||
if(me->totvert) {
|
||||
if(!odg) {
|
||||
odg = MEM_callocN(sizeof(bDeformGroup), "join deformGroup");
|
||||
memcpy(odg, dg, sizeof(bDeformGroup));
|
||||
BLI_addtail(&ob->defbase, odg);
|
||||
}
|
||||
}
|
||||
if(ob->defbase.first && ob->actdef==0)
|
||||
ob->actdef=1;
|
||||
|
||||
|
||||
if(me->totvert) {
|
||||
/* Add this object's materials to the base one's if they don't exist already (but only if limits not exceeded yet) */
|
||||
if(totcol < MAXMAT-1) {
|
||||
for(a=1; a<=base->object->totcol; a++) {
|
||||
ma= give_current_material(base->object, a);
|
||||
if(ma) {
|
||||
for(b=0; b<totcol; b++) {
|
||||
if(ma == matar[b]) break;
|
||||
}
|
||||
if(b==totcol) {
|
||||
matar[b]= ma;
|
||||
|
||||
for(b=0; b<totcol; b++) {
|
||||
if(ma == matar[b]) break;
|
||||
}
|
||||
if(b==totcol) {
|
||||
matar[b]= ma;
|
||||
if(ma)
|
||||
ma->id.us++;
|
||||
totcol++;
|
||||
totcol++;
|
||||
}
|
||||
if(totcol>=MAXMAT-1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if this mesh has shapekeys, check if destination mesh already has matching entries too */
|
||||
if(me->key && key) {
|
||||
for(kb= me->key->block.first; kb; kb= kb->next) {
|
||||
/* if key doesn't exist in destination mesh, add it */
|
||||
if(key_get_named_keyblock(key, kb->name) == NULL) {
|
||||
/* copy this existing one over to the new shapekey block */
|
||||
kbn= MEM_dupallocN(kb);
|
||||
kbn->prev= kbn->next= NULL;
|
||||
|
||||
/* adjust adrcode and other settings to fit (allocate a new data-array) */
|
||||
kbn->data= MEM_callocN(sizeof(float)*3*totvert, "joined_shapekey");
|
||||
kbn->totelem= totvert;
|
||||
kbn->weights= NULL;
|
||||
|
||||
okb= key->block.last;
|
||||
curpos= (okb) ? okb->pos : -0.1f;
|
||||
if(key->type == KEY_RELATIVE)
|
||||
kbn->pos= curpos + 0.1f;
|
||||
else
|
||||
kbn->pos= curpos;
|
||||
|
||||
BLI_addtail(&key->block, kbn);
|
||||
kbn->adrcode= key->totkey;
|
||||
key->totkey++;
|
||||
if(key->totkey==1) key->refkey= kbn;
|
||||
|
||||
// XXX 2.5 Animato
|
||||
#if 0
|
||||
/* also, copy corresponding ipo-curve to ipo-block if applicable */
|
||||
if(me->key->ipo && key->ipo) {
|
||||
// FIXME... this is a luxury item!
|
||||
puts("FIXME: ignoring IPO's when joining shapekeys on Meshes for now...");
|
||||
}
|
||||
if(totcol>=MAXMAT-1) break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(totcol>=MAXMAT-1) break;
|
||||
}
|
||||
base= base->next;
|
||||
}
|
||||
|
||||
me= ob->data;
|
||||
|
||||
CTX_DATA_END;
|
||||
|
||||
/* setup new data for destination mesh */
|
||||
memset(&vdata, 0, sizeof(vdata));
|
||||
memset(&edata, 0, sizeof(edata));
|
||||
memset(&fdata, 0, sizeof(fdata));
|
||||
|
@ -249,114 +294,177 @@ int join_mesh(Scene *scene, View3D *v3d, wmOperator *op)
|
|||
mvert= CustomData_add_layer(&vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
|
||||
medge= CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
|
||||
mface= CustomData_add_layer(&fdata, CD_MFACE, CD_CALLOC, NULL, totface);
|
||||
|
||||
|
||||
mvertmain= mvert;
|
||||
medgemain= medge;
|
||||
mfacemain= mface;
|
||||
|
||||
/* inverse transorm all selected meshes in this object */
|
||||
Mat4Invert(imat, ob->obmat);
|
||||
|
||||
|
||||
vertofs= 0;
|
||||
edgeofs= 0;
|
||||
faceofs= 0;
|
||||
base= FIRSTBASE;
|
||||
while(base) {
|
||||
nextb= base->next;
|
||||
if (TESTBASELIB_BGMODE(base)) {
|
||||
if(base->object->type==OB_MESH) {
|
||||
|
||||
/* inverse transform for all selected meshes in this object */
|
||||
Mat4Invert(imat, ob->obmat);
|
||||
|
||||
CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
|
||||
/* only join if this is a mesh */
|
||||
if(base->object->type==OB_MESH) {
|
||||
me= base->object->data;
|
||||
|
||||
if(me->totvert) {
|
||||
/* standard data */
|
||||
CustomData_merge(&me->vdata, &vdata, CD_MASK_MESH, CD_DEFAULT, totvert);
|
||||
CustomData_copy_data(&me->vdata, &vdata, 0, vertofs, me->totvert);
|
||||
|
||||
me= base->object->data;
|
||||
/* vertex groups */
|
||||
dvert= CustomData_get(&vdata, vertofs, CD_MDEFORMVERT);
|
||||
|
||||
if(me->totvert) {
|
||||
CustomData_merge(&me->vdata, &vdata, CD_MASK_MESH, CD_DEFAULT, totvert);
|
||||
CustomData_copy_data(&me->vdata, &vdata, 0, vertofs, me->totvert);
|
||||
|
||||
dvert= CustomData_get(&vdata, vertofs, CD_MDEFORMVERT);
|
||||
|
||||
/* NEW VERSION */
|
||||
if (dvert){
|
||||
for (i=0; i<me->totvert; i++){
|
||||
for (j=0; j<dvert[i].totweight; j++){
|
||||
// Find the old vertex group
|
||||
odg = BLI_findlink (&base->object->defbase, dvert[i].dw[j].def_nr);
|
||||
if(odg) {
|
||||
// Search for a match in the new object
|
||||
for (dg=ob->defbase.first, index=0; dg; dg=dg->next, index++){
|
||||
if (!strcmp(dg->name, odg->name)){
|
||||
dvert[i].dw[j].def_nr = index;
|
||||
break;
|
||||
}
|
||||
/* NB: vertex groups here are new version */
|
||||
if(dvert) {
|
||||
for(i=0; i<me->totvert; i++) {
|
||||
for(j=0; j<dvert[i].totweight; j++) {
|
||||
/* Find the old vertex group */
|
||||
odg = BLI_findlink(&base->object->defbase, dvert[i].dw[j].def_nr);
|
||||
if(odg) {
|
||||
/* Search for a match in the new object, and set new index */
|
||||
for(dg=ob->defbase.first, index=0; dg; dg=dg->next, index++) {
|
||||
if(!strcmp(dg->name, odg->name)) {
|
||||
dvert[i].dw[j].def_nr = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(base->object != ob) {
|
||||
/* watch this: switch matmul order really goes wrong */
|
||||
Mat4MulMat4(cmat, base->object->obmat, imat);
|
||||
|
||||
a= me->totvert;
|
||||
while(a--) {
|
||||
Mat4MulVecfl(cmat, mvert->co);
|
||||
mvert++;
|
||||
}
|
||||
}
|
||||
else mvert+= me->totvert;
|
||||
}
|
||||
if(me->totface) {
|
||||
|
||||
/* make mapping for materials */
|
||||
memset(map, 0, 4*MAXMAT);
|
||||
for(a=1; a<=base->object->totcol; a++) {
|
||||
ma= give_current_material(base->object, a);
|
||||
if(ma) {
|
||||
for(b=0; b<totcol; b++) {
|
||||
if(ma == matar[b]) {
|
||||
map[a-1]= b;
|
||||
break;
|
||||
/* if this is the object we're merging into, no need to do anything */
|
||||
if(base->object != ob) {
|
||||
/* watch this: switch matmul order really goes wrong */
|
||||
Mat4MulMat4(cmat, base->object->obmat, imat);
|
||||
|
||||
/* transform vertex coordinates into new space */
|
||||
for(a=0, mv=mvert; a < me->totvert; a++, mv++) {
|
||||
Mat4MulVecfl(cmat, mv->co);
|
||||
}
|
||||
|
||||
/* for each shapekey in destination mesh:
|
||||
* - if there's a matching one, copy it across (will need to transform vertices into new space...)
|
||||
* - otherwise, just copy own coordinates of mesh (no need to transform vertex coordinates into new space)
|
||||
*/
|
||||
if(key) {
|
||||
/* if this mesh has any shapekeys, check first, otherwise just copy coordinates */
|
||||
for(kb= key->block.first; kb; kb= kb->next) {
|
||||
/* get pointer to where to write data for this mesh in shapekey's data array */
|
||||
fp1= ((float *)kb->data) + (vertofs*3);
|
||||
|
||||
/* check if this mesh has such a shapekey */
|
||||
okb= key_get_named_keyblock(me->key, kb->name);
|
||||
if(okb) {
|
||||
/* copy this mesh's shapekey to the destination shapekey (need to transform first) */
|
||||
fp2= ((float *)(okb->data));
|
||||
for(a=0; a < me->totvert; a++, fp1+=3, fp2+=3) {
|
||||
VECCOPY(fp1, fp2);
|
||||
Mat4MulVecfl(cmat, fp1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* copy this mesh's vertex coordinates to the destination shapekey */
|
||||
mv= mvert;
|
||||
for(a=0; a < me->totvert; a++, fp1+=3, mv++) {
|
||||
VECCOPY(fp1, mv->co);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CustomData_merge(&me->fdata, &fdata, CD_MASK_MESH, CD_DEFAULT, totface);
|
||||
CustomData_copy_data(&me->fdata, &fdata, 0, faceofs, me->totface);
|
||||
|
||||
for(a=0; a<me->totface; a++, mface++) {
|
||||
mface->v1+= vertofs;
|
||||
mface->v2+= vertofs;
|
||||
mface->v3+= vertofs;
|
||||
if(mface->v4) mface->v4+= vertofs;
|
||||
|
||||
mface->mat_nr= map[(int)mface->mat_nr];
|
||||
}
|
||||
else {
|
||||
/* for each shapekey in destination mesh:
|
||||
* - if it was an 'original', copy the appropriate data from nkey
|
||||
* - otherwise, copy across plain coordinates (no need to transform coordinates)
|
||||
*/
|
||||
if(key) {
|
||||
for(kb= key->block.first; kb; kb= kb->next) {
|
||||
/* get pointer to where to write data for this mesh in shapekey's data array */
|
||||
fp1= ((float *)kb->data) + (vertofs*3);
|
||||
|
||||
/* check if this was one of the original shapekeys */
|
||||
okb= key_get_named_keyblock(nkey, kb->name);
|
||||
if(okb) {
|
||||
/* copy this mesh's shapekey to the destination shapekey */
|
||||
fp2= ((float *)(okb->data));
|
||||
for(a=0; a < me->totvert; a++, fp1+=3, fp2+=3) {
|
||||
VECCOPY(fp1, fp2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* copy base-coordinates to the destination shapekey */
|
||||
mv= mvert;
|
||||
for(a=0; a < me->totvert; a++, fp1+=3, mv++) {
|
||||
VECCOPY(fp1, mv->co);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
faceofs += me->totface;
|
||||
}
|
||||
|
||||
if(me->totedge) {
|
||||
CustomData_merge(&me->edata, &edata, CD_MASK_MESH, CD_DEFAULT, totedge);
|
||||
CustomData_copy_data(&me->edata, &edata, 0, edgeofs, me->totedge);
|
||||
|
||||
for(a=0; a<me->totedge; a++, medge++) {
|
||||
medge->v1+= vertofs;
|
||||
medge->v2+= vertofs;
|
||||
}
|
||||
|
||||
edgeofs += me->totedge;
|
||||
}
|
||||
|
||||
vertofs += me->totvert;
|
||||
|
||||
if(base->object!=ob)
|
||||
ED_base_object_free_and_unlink(scene, base);
|
||||
/* advance mvert pointer to end of base mesh's data */
|
||||
mvert+= me->totvert;
|
||||
}
|
||||
|
||||
if(me->totface) {
|
||||
/* make mapping for materials */
|
||||
for(a=1; a<=base->object->totcol; a++) {
|
||||
ma= give_current_material(base->object, a);
|
||||
|
||||
for(b=0; b<totcol; b++) {
|
||||
if(ma == matar[b]) {
|
||||
matmap[a-1]= b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CustomData_merge(&me->fdata, &fdata, CD_MASK_MESH, CD_DEFAULT, totface);
|
||||
CustomData_copy_data(&me->fdata, &fdata, 0, faceofs, me->totface);
|
||||
|
||||
for(a=0; a<me->totface; a++, mface++) {
|
||||
mface->v1+= vertofs;
|
||||
mface->v2+= vertofs;
|
||||
mface->v3+= vertofs;
|
||||
if(mface->v4) mface->v4+= vertofs;
|
||||
|
||||
mface->mat_nr= matmap[(int)mface->mat_nr];
|
||||
}
|
||||
|
||||
faceofs += me->totface;
|
||||
}
|
||||
|
||||
if(me->totedge) {
|
||||
CustomData_merge(&me->edata, &edata, CD_MASK_MESH, CD_DEFAULT, totedge);
|
||||
CustomData_copy_data(&me->edata, &edata, 0, edgeofs, me->totedge);
|
||||
|
||||
for(a=0; a<me->totedge; a++, medge++) {
|
||||
medge->v1+= vertofs;
|
||||
medge->v2+= vertofs;
|
||||
}
|
||||
|
||||
edgeofs += me->totedge;
|
||||
}
|
||||
|
||||
/* vertofs is used to help newly added verts be reattached to their edge/face
|
||||
* (cannot be set earlier, or else reattaching goes wrong)
|
||||
*/
|
||||
vertofs += me->totvert;
|
||||
|
||||
/* free base, now that data is merged */
|
||||
if(base->object != ob)
|
||||
ED_base_object_free_and_unlink(scene, base);
|
||||
}
|
||||
base= nextb;
|
||||
}
|
||||
CTX_DATA_END;
|
||||
|
||||
/* return to mesh we're merging to */
|
||||
me= ob->data;
|
||||
|
||||
CustomData_free(&me->vdata, me->totvert);
|
||||
|
@ -383,30 +491,53 @@ int join_mesh(Scene *scene, View3D *v3d, wmOperator *op)
|
|||
if(ma) ma->id.us--;
|
||||
}
|
||||
if(ob->mat) MEM_freeN(ob->mat);
|
||||
if(ob->matbits) MEM_freeN(ob->matbits);
|
||||
if(me->mat) MEM_freeN(me->mat);
|
||||
ob->mat= me->mat= 0;
|
||||
ob->mat= me->mat= NULL;
|
||||
ob->matbits= NULL;
|
||||
|
||||
if(totcol) {
|
||||
me->mat= matar;
|
||||
ob->mat= MEM_callocN(sizeof(void *)*totcol, "join obmatar");
|
||||
ob->matbits= MEM_callocN(sizeof(char)*totcol, "join obmatbits");
|
||||
}
|
||||
else MEM_freeN(matar);
|
||||
else
|
||||
MEM_freeN(matar);
|
||||
|
||||
ob->totcol= me->totcol= totcol;
|
||||
ob->colbits= 0;
|
||||
|
||||
MEM_freeN(matmap);
|
||||
|
||||
/* other mesh users */
|
||||
test_object_materials((ID *)me);
|
||||
|
||||
/* free temp copy of destination shapekeys (if applicable) */
|
||||
if(nkey) {
|
||||
// XXX 2.5 Animato
|
||||
#if 0
|
||||
/* free it's ipo too - both are not actually freed from memory yet as ID-blocks */
|
||||
if(nkey->ipo) {
|
||||
free_ipo(nkey->ipo);
|
||||
BLI_remlink(&G.main->ipo, nkey->ipo);
|
||||
MEM_freeN(nkey->ipo);
|
||||
}
|
||||
#endif
|
||||
|
||||
free_key(nkey);
|
||||
BLI_remlink(&G.main->key, nkey);
|
||||
MEM_freeN(nkey);
|
||||
}
|
||||
|
||||
DAG_scene_sort(scene); // removed objects, need to rebuild dag before editmode call
|
||||
|
||||
// XXX enter_editmode(EM_WAITCURSOR);
|
||||
// exit_editmode(EM_FREEDATA|EM_WAITCURSOR); // freedata, but no undo
|
||||
|
||||
BIF_undo_push("Join Mesh");
|
||||
return 1;
|
||||
}
|
||||
ED_object_enter_editmode(C, EM_WAITCURSOR);
|
||||
ED_object_exit_editmode(C, EM_FREEDATA|EM_WAITCURSOR);
|
||||
|
||||
WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
/* ********************** SORT FACES ******************* */
|
||||
|
||||
|
@ -520,14 +651,14 @@ void sort_faces(Scene *scene, View3D *v3d)
|
|||
else face_sort_floats[i] = reverse;
|
||||
} else {
|
||||
/* find the faces center */
|
||||
VECADD(vec, (me->mvert+mf->v1)->co, (me->mvert+mf->v2)->co);
|
||||
VecAddf(vec, (me->mvert+mf->v1)->co, (me->mvert+mf->v2)->co);
|
||||
if (mf->v4) {
|
||||
VECADD(vec, vec, (me->mvert+mf->v3)->co);
|
||||
VECADD(vec, vec, (me->mvert+mf->v4)->co);
|
||||
VECMUL(vec, 0.25f);
|
||||
VecAddf(vec, vec, (me->mvert+mf->v3)->co);
|
||||
VecAddf(vec, vec, (me->mvert+mf->v4)->co);
|
||||
VecMulf(vec, 0.25f);
|
||||
} else {
|
||||
VECADD(vec, vec, (me->mvert+mf->v3)->co);
|
||||
VECMUL(vec, 1.0f/3.0f);
|
||||
VecAddf(vec, vec, (me->mvert+mf->v3)->co);
|
||||
VecMulf(vec, 1.0f/3.0f);
|
||||
} /* done */
|
||||
|
||||
if (event == 1) { /* sort on view axis */
|
||||
|
|
|
@ -1755,7 +1755,6 @@ static short select_grouped_parent(bContext *C) /* Makes parent active and de-se
|
|||
static short select_grouped_group(bContext *C, Object *ob) /* Select objects in the same group as the active */
|
||||
{
|
||||
short changed = 0;
|
||||
Base *base;
|
||||
Group *group, *ob_groups[GROUP_MENU_MAX];
|
||||
//char str[10 + (24*GROUP_MENU_MAX)];
|
||||
//char *p = str;
|
||||
|
@ -6326,6 +6325,53 @@ void OBJECT_OT_duplicate(wmOperatorType *ot)
|
|||
RNA_def_int(ot->srna, "mode", TFM_TRANSLATION, 0, INT_MAX, "Mode", "", 0, INT_MAX);
|
||||
}
|
||||
|
||||
/* ************************** JOIN *********************** */
|
||||
|
||||
static int join_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
Object *ob= CTX_data_active_object(C);
|
||||
|
||||
if(scene->obedit) {
|
||||
BKE_report(op->reports, RPT_ERROR, "This data does not support joining in editmode.");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
else if(!ob) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Can't join unless there is an active object.");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
else if(object_data_is_libdata(ob)) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Can't edit external libdata.");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if(ob->type == OB_MESH)
|
||||
return join_mesh_exec(C, op);
|
||||
else if(ELEM(ob->type, OB_CURVE, OB_SURF))
|
||||
return join_curve_exec(C, op);
|
||||
else if(ob->type == OB_ARMATURE)
|
||||
return join_armature_exec(C, op);
|
||||
|
||||
BKE_report(op->reports, RPT_ERROR, "This object type doesn't support joining.");
|
||||
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_join(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Join";
|
||||
ot->description = "Join selected objects into active object.";
|
||||
ot->idname= "OBJECT_OT_join";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= join_exec;
|
||||
ot->poll= ED_operator_scene_editable;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
/* ********************** */
|
||||
|
||||
void image_aspect(Scene *scene, View3D *v3d)
|
||||
|
|
|
@ -64,6 +64,7 @@ void OBJECT_OT_duplicates_make_real(struct wmOperatorType *ot);
|
|||
void OBJECT_OT_object_add(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_duplicate(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_delete(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_join(struct wmOperatorType *ot);
|
||||
|
||||
void OBJECT_OT_mesh_add(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_curve_add(struct wmOperatorType *ot);
|
||||
|
|
|
@ -86,6 +86,7 @@ void ED_operatortypes_object(void)
|
|||
WM_operatortype_append(OBJECT_OT_center_set);
|
||||
WM_operatortype_append(OBJECT_OT_duplicates_make_real);
|
||||
WM_operatortype_append(OBJECT_OT_duplicate);
|
||||
WM_operatortype_append(OBJECT_OT_join);
|
||||
WM_operatortype_append(GROUP_OT_group_create);
|
||||
WM_operatortype_append(GROUP_OT_objects_remove);
|
||||
WM_operatortype_append(GROUP_OT_objects_add_active);
|
||||
|
@ -170,6 +171,7 @@ void ED_keymap_object(wmWindowManager *wm)
|
|||
WM_keymap_verify_item(keymap, "OBJECT_OT_primitive_add", AKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
WM_keymap_add_item(keymap, "OBJECT_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_duplicate", DKEY, KM_PRESS, KM_ALT, 0)->ptr, "linked", 1);
|
||||
WM_keymap_add_item(keymap, "OBJECT_OT_join", JKEY, KM_PRESS, KM_CTRL, 0);
|
||||
|
||||
// XXX this should probably be in screen instead... here for testing purposes in the meantime... - Aligorith
|
||||
WM_keymap_verify_item(keymap, "ANIM_OT_insert_keyframe_menu", IKEY, KM_PRESS, 0, 0);
|
||||
|
|
|
@ -387,7 +387,6 @@ static int view_all_exec(bContext *C, wmOperator *op)
|
|||
ARegion *ar;
|
||||
Scene *scene;
|
||||
Object *obedit;
|
||||
Image *ima;
|
||||
ImBuf *ibuf;
|
||||
float aspx, aspy, zoomx, zoomy, w, h;
|
||||
int width, height;
|
||||
|
@ -398,7 +397,6 @@ static int view_all_exec(bContext *C, wmOperator *op)
|
|||
scene= (Scene*)CTX_data_scene(C);
|
||||
obedit= CTX_data_edit_object(C);
|
||||
|
||||
ima= ED_space_image(sima);
|
||||
ibuf= ED_space_image_buffer(sima);
|
||||
ED_space_image_size(sima, &width, &height);
|
||||
ED_space_image_aspect(sima, &aspx, &aspy);
|
||||
|
|
|
@ -1700,22 +1700,24 @@ static int tree_element_active_material(Scene *scene, SpaceOops *soops, TreeElem
|
|||
if(tes->idcode==ID_OB) {
|
||||
if(set) {
|
||||
ob->actcol= te->index+1;
|
||||
ob->colbits |= (1<<te->index); // make ob material active too
|
||||
ob->matbits[te->index]= 1; // make ob material active too
|
||||
ob->colbits |= (1<<te->index);
|
||||
}
|
||||
else {
|
||||
if(ob->actcol == te->index+1)
|
||||
if(ob->colbits & (1<<te->index)) return 1;
|
||||
if(ob->matbits[te->index]) return 1;
|
||||
}
|
||||
}
|
||||
/* or we search for obdata material */
|
||||
else {
|
||||
if(set) {
|
||||
ob->actcol= te->index+1;
|
||||
ob->colbits &= ~(1<<te->index); // make obdata material active too
|
||||
ob->matbits[te->index]= 0; // make obdata material active too
|
||||
ob->colbits &= ~(1<<te->index);
|
||||
}
|
||||
else {
|
||||
if(ob->actcol == te->index+1)
|
||||
if( (ob->colbits & (1<<te->index))==0 ) return 1;
|
||||
if(ob->matbits[te->index]==0) return 1;
|
||||
}
|
||||
}
|
||||
if(set) {
|
||||
|
|
|
@ -2463,11 +2463,13 @@ static int draw_mesh_object(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
|
|||
if(dt>OB_WIRE) {
|
||||
// no transp in editmode, the fancy draw over goes bad then
|
||||
glsl = draw_glsl_material(scene, ob, v3d, dt);
|
||||
GPU_set_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
|
||||
GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
|
||||
}
|
||||
|
||||
draw_em_fancy(scene, v3d, rv3d, ob, em, cageDM, finalDM, dt);
|
||||
|
||||
GPU_end_object_materials();
|
||||
|
||||
if (obedit!=ob && finalDM)
|
||||
finalDM->release(finalDM);
|
||||
}
|
||||
|
@ -2482,17 +2484,19 @@ static int draw_mesh_object(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
|
|||
check_alpha = check_material_alpha(base, me, glsl);
|
||||
|
||||
if(dt==OB_SOLID || glsl) {
|
||||
GPU_set_object_materials(v3d, rv3d, scene, ob, glsl,
|
||||
GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl,
|
||||
(check_alpha)? &do_alpha_pass: NULL);
|
||||
}
|
||||
|
||||
draw_mesh_fancy(scene, v3d, rv3d, base, dt, flag);
|
||||
|
||||
GPU_end_object_materials();
|
||||
|
||||
if(me->totvert==0) retval= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* GPU_set_object_materials checked if this is needed */
|
||||
/* GPU_begin_object_materials checked if this is needed */
|
||||
if(do_alpha_pass) add_view3d_after(v3d, base, V3D_TRANSP, flag);
|
||||
|
||||
return retval;
|
||||
|
@ -2670,7 +2674,6 @@ static void drawDispListsolid(ListBase *lb, Object *ob, int glsl)
|
|||
glVertexPointer(3, GL_FLOAT, 0, dl->verts);
|
||||
glNormalPointer(GL_FLOAT, 0, dl->nors);
|
||||
glDrawElements(GL_QUADS, 4*dl->totindex, GL_UNSIGNED_INT, dl->index);
|
||||
GPU_disable_material();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2688,7 +2691,6 @@ static void drawDispListsolid(ListBase *lb, Object *ob, int glsl)
|
|||
glNormalPointer(GL_FLOAT, 0, dl->nors);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, 3*dl->parts, GL_UNSIGNED_INT, dl->index);
|
||||
GPU_disable_material();
|
||||
|
||||
if(index3_nors_incr==0)
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
|
@ -2702,8 +2704,6 @@ static void drawDispListsolid(ListBase *lb, Object *ob, int glsl)
|
|||
glNormalPointer(GL_FLOAT, 0, dl->nors);
|
||||
glDrawElements(GL_QUADS, 4*dl->parts, GL_UNSIGNED_INT, dl->index);
|
||||
|
||||
GPU_disable_material();
|
||||
|
||||
break;
|
||||
}
|
||||
dl= dl->next;
|
||||
|
@ -2797,17 +2797,19 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
|
|||
}
|
||||
else {
|
||||
if(draw_glsl_material(scene, ob, v3d, dt)) {
|
||||
GPU_set_object_materials(v3d, rv3d, scene, ob, 1, NULL);
|
||||
GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL);
|
||||
drawDispListsolid(lb, ob, 1);
|
||||
GPU_end_object_materials();
|
||||
}
|
||||
else if(dt == OB_SHADED) {
|
||||
if(ob->disp.first==0) shadeDispList(scene, base);
|
||||
drawDispListshaded(lb, ob);
|
||||
}
|
||||
else {
|
||||
GPU_set_object_materials(v3d, rv3d, scene, ob, 0, NULL);
|
||||
GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL);
|
||||
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
|
||||
drawDispListsolid(lb, ob, 0);
|
||||
GPU_end_object_materials();
|
||||
}
|
||||
if(cu->editnurb && cu->bevobj==NULL && cu->taperobj==NULL && cu->ext1 == 0.0 && cu->ext2 == 0.0) {
|
||||
cpack(0);
|
||||
|
@ -2835,18 +2837,19 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
|
|||
if(dl->nors==NULL) addnormalsDispList(ob, lb);
|
||||
|
||||
if(draw_glsl_material(scene, ob, v3d, dt)) {
|
||||
GPU_set_object_materials(v3d, rv3d, scene, ob, 1, NULL);
|
||||
GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL);
|
||||
drawDispListsolid(lb, ob, 1);
|
||||
GPU_end_object_materials();
|
||||
}
|
||||
else if(dt==OB_SHADED) {
|
||||
if(ob->disp.first==NULL) shadeDispList(scene, base);
|
||||
drawDispListshaded(lb, ob);
|
||||
}
|
||||
else {
|
||||
GPU_set_object_materials(v3d, rv3d, scene, ob, 0, NULL);
|
||||
GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL);
|
||||
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
|
||||
|
||||
drawDispListsolid(lb, ob, 0);
|
||||
GPU_end_object_materials();
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -2863,8 +2866,9 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
|
|||
if(solid) {
|
||||
|
||||
if(draw_glsl_material(scene, ob, v3d, dt)) {
|
||||
GPU_set_object_materials(v3d, rv3d, scene, ob, 1, NULL);
|
||||
GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL);
|
||||
drawDispListsolid(lb, ob, 1);
|
||||
GPU_end_object_materials();
|
||||
}
|
||||
else if(dt == OB_SHADED) {
|
||||
dl= lb->first;
|
||||
|
@ -2872,10 +2876,10 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
|
|||
drawDispListshaded(lb, ob);
|
||||
}
|
||||
else {
|
||||
GPU_set_object_materials(v3d, rv3d, scene, ob, 0, NULL);
|
||||
GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL);
|
||||
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
|
||||
|
||||
drawDispListsolid(lb, ob, 0);
|
||||
GPU_end_object_materials();
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
@ -5615,7 +5619,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r
|
|||
|
||||
if(dm) {
|
||||
glsl = draw_glsl_material(scene, ob, v3d, dt);
|
||||
GPU_set_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
|
||||
GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
|
||||
}
|
||||
else {
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
|
@ -5629,7 +5633,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r
|
|||
|
||||
if(dm) {
|
||||
dm->drawFacesSolid(dm, GPU_enable_material);
|
||||
GPU_disable_material();
|
||||
GPU_end_object_materials();
|
||||
}
|
||||
else if(edm)
|
||||
edm->drawMappedFaces(edm, NULL, NULL, 0);
|
||||
|
|
|
@ -63,8 +63,10 @@ void GPU_state_init(void);
|
|||
* GPU_enable_material returns 0 if drawing should be skipped
|
||||
* - after drawing, the material must be disabled again */
|
||||
|
||||
void GPU_set_object_materials(struct View3D *v3d, struct RegionView3D *rv3d,
|
||||
void GPU_begin_object_materials(struct View3D *v3d, struct RegionView3D *rv3d,
|
||||
struct Scene *scene, struct Object *ob, int glsl, int *do_alpha_pass);
|
||||
void GPU_end_object_materials(void);
|
||||
|
||||
int GPU_enable_material(int nr, void *attribs);
|
||||
void GPU_disable_material(void);
|
||||
|
||||
|
|
|
@ -776,16 +776,17 @@ void GPU_free_images(void)
|
|||
|
||||
/* OpenGL Materials */
|
||||
|
||||
/* materials start counting at # one.... */
|
||||
#define MAXMATBUF (MAXMAT+1)
|
||||
#define FIXEDMAT 8
|
||||
|
||||
/* OpenGL state caching for materials */
|
||||
|
||||
static struct GPUMaterialState {
|
||||
float matbuf[MAXMATBUF][2][4];
|
||||
float (*matbuf)[2][4];
|
||||
float matbuf_fixed[FIXEDMAT][2][4];
|
||||
int totmat;
|
||||
|
||||
Material *gmatbuf[MAXMATBUF];
|
||||
Material **gmatbuf;
|
||||
Material *gmatbuf_fixed[FIXEDMAT];
|
||||
Material *gboundmat;
|
||||
Object *gob;
|
||||
Scene *gscene;
|
||||
|
@ -793,7 +794,8 @@ static struct GPUMaterialState {
|
|||
float (*gviewmat)[4];
|
||||
float (*gviewinv)[4];
|
||||
|
||||
GPUBlendMode blendmode[MAXMATBUF];
|
||||
GPUBlendMode *blendmode;
|
||||
GPUBlendMode blendmode_fixed[FIXEDMAT];
|
||||
int alphapass;
|
||||
|
||||
int lastmatnr, lastretval;
|
||||
|
@ -814,7 +816,7 @@ Material *gpu_active_node_material(Material *ma)
|
|||
return ma;
|
||||
}
|
||||
|
||||
void GPU_set_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, Object *ob, int glsl, int *do_alpha_pass)
|
||||
void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, Object *ob, int glsl, int *do_alpha_pass)
|
||||
{
|
||||
extern Material defmaterial; /* from material.c */
|
||||
Material *ma;
|
||||
|
@ -830,7 +832,7 @@ void GPU_set_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, Obj
|
|||
|
||||
GMS.gob = ob;
|
||||
GMS.gscene = scene;
|
||||
GMS.totmat= ob->totcol;
|
||||
GMS.totmat= ob->totcol+1; /* materials start from 1, default material is 0 */
|
||||
GMS.glay= v3d->lay;
|
||||
GMS.gviewmat= rv3d->viewmat;
|
||||
GMS.gviewinv= rv3d->viewinv;
|
||||
|
@ -838,6 +840,17 @@ void GPU_set_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, Obj
|
|||
GMS.alphapass = (v3d && v3d->transp);
|
||||
if(do_alpha_pass)
|
||||
*do_alpha_pass = 0;
|
||||
|
||||
if(GMS.totmat > FIXEDMAT) {
|
||||
GMS.matbuf= MEM_callocN(sizeof(*GMS.matbuf)*GMS.totmat, "GMS.matbuf");
|
||||
GMS.gmatbuf= MEM_callocN(sizeof(*GMS.gmatbuf)*GMS.totmat, "GMS.matbuf");
|
||||
GMS.blendmode= MEM_callocN(sizeof(*GMS.blendmode)*GMS.totmat, "GMS.matbuf");
|
||||
}
|
||||
else {
|
||||
GMS.matbuf= GMS.matbuf_fixed;
|
||||
GMS.gmatbuf= GMS.gmatbuf_fixed;
|
||||
GMS.blendmode= GMS.blendmode_fixed;
|
||||
}
|
||||
|
||||
/* no materials assigned? */
|
||||
if(ob->totcol==0) {
|
||||
|
@ -870,10 +883,6 @@ void GPU_set_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, Obj
|
|||
if(!glsl) ma= gpu_active_node_material(ma);
|
||||
if(ma==NULL) ma= &defmaterial;
|
||||
|
||||
/* this shouldn't happen .. */
|
||||
if(a>=MAXMATBUF)
|
||||
continue;
|
||||
|
||||
/* create glsl material if requested */
|
||||
gpumat = (glsl)? GPU_material_from_blender(GMS.gscene, ma): NULL;
|
||||
|
||||
|
@ -926,14 +935,14 @@ int GPU_enable_material(int nr, void *attribs)
|
|||
GPUBlendMode blendmode;
|
||||
|
||||
/* prevent index to use un-initialized array items */
|
||||
if(nr>GMS.totmat)
|
||||
nr= GMS.totmat;
|
||||
if(nr>=GMS.totmat)
|
||||
nr= 0;
|
||||
|
||||
if(gattribs)
|
||||
memset(gattribs, 0, sizeof(*gattribs));
|
||||
|
||||
/* keep current material */
|
||||
if(nr>=MAXMATBUF || nr==GMS.lastmatnr)
|
||||
if(nr==GMS.lastmatnr)
|
||||
return GMS.lastretval;
|
||||
|
||||
/* unbind glsl material */
|
||||
|
@ -1004,6 +1013,21 @@ void GPU_disable_material(void)
|
|||
GPU_set_material_blend_mode(GPU_BLEND_SOLID);
|
||||
}
|
||||
|
||||
void GPU_end_object_materials(void)
|
||||
{
|
||||
GPU_disable_material();
|
||||
|
||||
if(GMS.matbuf && GMS.matbuf != GMS.matbuf_fixed) {
|
||||
MEM_freeN(GMS.matbuf);
|
||||
MEM_freeN(GMS.gmatbuf);
|
||||
MEM_freeN(GMS.blendmode);
|
||||
|
||||
GMS.matbuf= NULL;
|
||||
GMS.gmatbuf= NULL;
|
||||
GMS.blendmode= NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Lights */
|
||||
|
||||
int GPU_default_lights(void)
|
||||
|
|
|
@ -142,10 +142,10 @@ typedef struct Material {
|
|||
|
||||
/* **************** MATERIAL ********************* */
|
||||
|
||||
/* maximum number of materials per material array
|
||||
* (on object, mesh, lamp, etc.)
|
||||
*/
|
||||
#define MAXMAT 16
|
||||
/* maximum number of materials per material array.
|
||||
* (on object, mesh, lamp, etc.). limited by
|
||||
* short mat_nr in verts, faces. */
|
||||
#define MAXMAT 32767
|
||||
|
||||
/* material_type */
|
||||
#define MA_TYPE_SURFACE 0
|
||||
|
|
|
@ -37,7 +37,7 @@ struct Image;
|
|||
|
||||
typedef struct MFace {
|
||||
unsigned int v1, v2, v3, v4;
|
||||
char pad, mat_nr;
|
||||
short mat_nr;
|
||||
char edcode, flag; /* we keep edcode, for conversion to edges draw flags in old files */
|
||||
} MFace;
|
||||
|
||||
|
@ -61,7 +61,8 @@ typedef struct MDeformVert {
|
|||
typedef struct MVert {
|
||||
float co[3];
|
||||
short no[3];
|
||||
char flag, mat_nr, bweight, pad[3];
|
||||
short mat_nr;
|
||||
char flag, bweight, pad[2];
|
||||
} MVert;
|
||||
|
||||
/* at the moment alpha is abused for vertex painting
|
||||
|
@ -134,7 +135,7 @@ typedef struct MultiresColFace {
|
|||
} MultiresColFace;
|
||||
typedef struct MultiresFace {
|
||||
unsigned int v[4];
|
||||
unsigned int mid;
|
||||
unsigned int mid;
|
||||
char flag, mat_nr, pad[2];
|
||||
} MultiresFace;
|
||||
typedef struct MultiresEdge {
|
||||
|
|
|
@ -113,8 +113,12 @@ typedef struct Object {
|
|||
ListBase disp;
|
||||
ListBase defbase;
|
||||
ListBase modifiers; /* list of ModifierData structures */
|
||||
|
||||
struct Material **mat;
|
||||
|
||||
/* materials */
|
||||
struct Material **mat; /* material slots */
|
||||
char *matbits; /* 1 if material linked to object */
|
||||
int totcol; /* copy of mesh or curve or meta */
|
||||
int actcol; /* currently selected material in the UI */
|
||||
|
||||
/* rot en drot have to be together! (transform('r' en 's')) */
|
||||
float loc[3], dloc[3], orig[3];
|
||||
|
@ -129,7 +133,7 @@ typedef struct Object {
|
|||
unsigned int lay; /* copy of Base */
|
||||
|
||||
short flag; /* copy of Base */
|
||||
short colbits; /* when zero, from obdata */
|
||||
short colbits; /* deprecated */
|
||||
|
||||
short transflag, protectflag; /* transformation settings and transform locks */
|
||||
short trackflag, upflag;
|
||||
|
@ -164,9 +168,7 @@ typedef struct Object {
|
|||
float m_contactProcessingThreshold;
|
||||
|
||||
char dt, dtx;
|
||||
char totcol; /* copy of mesh or curve or meta */
|
||||
char actcol; /* currently selected material in the user interface */
|
||||
char empty_drawtype, pad1[3];
|
||||
char empty_drawtype, pad1[5];
|
||||
float empty_drawsize;
|
||||
float dupfacesca; /* dupliface scale */
|
||||
|
||||
|
|
|
@ -701,7 +701,6 @@ static void rna_def_curve_nurb(BlenderRNA *brna)
|
|||
prop= RNA_def_property(srna, "material_index", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_int_sdna(prop, NULL, "mat_nr");
|
||||
RNA_def_property_ui_text(prop, "Material Index", "");
|
||||
RNA_def_property_range(prop, 0, MAXMAT-1);
|
||||
RNA_def_property_int_funcs(prop, NULL, NULL, "rna_Curve_material_index_range");
|
||||
|
||||
prop= RNA_def_property(srna, "character_index", PROP_INT, PROP_UNSIGNED);
|
||||
|
|
|
@ -879,7 +879,6 @@ static void rna_def_mface(BlenderRNA *brna)
|
|||
prop= RNA_def_property(srna, "material_index", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_int_sdna(prop, NULL, "mat_nr");
|
||||
RNA_def_property_ui_text(prop, "Material Index", "");
|
||||
RNA_def_property_range(prop, 0, MAXMAT-1);
|
||||
RNA_def_property_int_funcs(prop, NULL, NULL, "rna_MeshFace_material_index_range");
|
||||
|
||||
prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE);
|
||||
|
|
|
@ -331,7 +331,7 @@ static int rna_MaterialSlot_link_get(PointerRNA *ptr)
|
|||
Object *ob= (Object*)ptr->id.data;
|
||||
int index= (Material**)ptr->data - ob->mat;
|
||||
|
||||
return (ob->colbits & (1<<index)) != 0;
|
||||
return ob->matbits[index] != 0;
|
||||
}
|
||||
|
||||
static void rna_MaterialSlot_link_set(PointerRNA *ptr, int value)
|
||||
|
@ -339,10 +339,14 @@ static void rna_MaterialSlot_link_set(PointerRNA *ptr, int value)
|
|||
Object *ob= (Object*)ptr->id.data;
|
||||
int index= (Material**)ptr->data - ob->mat;
|
||||
|
||||
if(value)
|
||||
if(value) {
|
||||
ob->matbits[index]= 1;
|
||||
ob->colbits |= (1<<index);
|
||||
else
|
||||
}
|
||||
else {
|
||||
ob->matbits[index]= 0;
|
||||
ob->colbits &= ~(1<<index);
|
||||
}
|
||||
}
|
||||
|
||||
static int rna_MaterialSlot_name_length(PointerRNA *ptr)
|
||||
|
@ -523,8 +527,8 @@ static void rna_def_material_slot(BlenderRNA *brna)
|
|||
PropertyRNA *prop;
|
||||
|
||||
static EnumPropertyItem link_items[] = {
|
||||
{0, "DATA", 0, "Data", ""},
|
||||
{1, "OBJECT", 0, "Object", ""},
|
||||
{0, "DATA", 0, "Data", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
/* NOTE: there is no MaterialSlot equivalent in DNA, so the internal
|
||||
|
|
|
@ -2582,9 +2582,9 @@ static void init_render_surf(Render *re, ObjectRen *obr)
|
|||
Curve *cu;
|
||||
ListBase displist;
|
||||
DispList *dl;
|
||||
Material *matar[32];
|
||||
Material **matar;
|
||||
float *orco=NULL, *orcobase=NULL, mat[4][4];
|
||||
int a, need_orco=0;
|
||||
int a, totmat, need_orco=0;
|
||||
|
||||
cu= ob->data;
|
||||
nu= cu->nurb.first;
|
||||
|
@ -2594,13 +2594,14 @@ static void init_render_surf(Render *re, ObjectRen *obr)
|
|||
MTC_Mat4Invert(ob->imat, mat);
|
||||
|
||||
/* material array */
|
||||
memset(matar, 0, 4*32);
|
||||
matar[0]= give_render_material(re, ob, 0);
|
||||
for(a=0; a<ob->totcol; a++) {
|
||||
totmat= ob->totcol+1;
|
||||
matar= MEM_callocN(sizeof(Material*)*totmat, "init_render_surf matar");
|
||||
|
||||
for(a=0; a<totmat; a++) {
|
||||
matar[a]= give_render_material(re, ob, a+1);
|
||||
if(matar[a] && matar[a]->texco & TEXCO_ORCO) {
|
||||
|
||||
if(matar[a] && matar[a]->texco & TEXCO_ORCO)
|
||||
need_orco= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(ob->parent && (ob->parent->type==OB_LATTICE)) need_orco= 1;
|
||||
|
@ -2610,17 +2611,15 @@ static void init_render_surf(Render *re, ObjectRen *obr)
|
|||
displist.first= displist.last= 0;
|
||||
makeDispListSurf(re->scene, ob, &displist, 1, 0);
|
||||
|
||||
dl= displist.first;
|
||||
/* walk along displaylist and create rendervertices/-faces */
|
||||
while(dl) {
|
||||
/* watch out: u ^= y, v ^= x !! */
|
||||
if(dl->type==DL_SURF) {
|
||||
for(dl=displist.first; dl; dl=dl->next) {
|
||||
/* watch out: u ^= y, v ^= x !! */
|
||||
if(dl->type==DL_SURF)
|
||||
orco+= 3*dl_surf_to_renderdata(obr, dl, matar, orco, mat);
|
||||
}
|
||||
|
||||
dl= dl->next;
|
||||
}
|
||||
|
||||
freedisplist(&displist);
|
||||
MEM_freeN(matar);
|
||||
}
|
||||
|
||||
static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
|
||||
|
@ -2631,11 +2630,11 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
|
|||
VlakRen *vlr;
|
||||
DispList *dl;
|
||||
ListBase olddl={NULL, NULL};
|
||||
Material *matar[32];
|
||||
Material **matar;
|
||||
float len, *data, *fp, *orco=NULL, *orcobase= NULL;
|
||||
float n[3], mat[4][4];
|
||||
int nr, startvert, startvlak, a, b;
|
||||
int frontside, need_orco=0;
|
||||
int frontside, need_orco=0, totmat;
|
||||
|
||||
cu= ob->data;
|
||||
if(ob->type==OB_FONT && cu->str==NULL) return;
|
||||
|
@ -2656,13 +2655,14 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
|
|||
MTC_Mat4Invert(ob->imat, mat);
|
||||
|
||||
/* material array */
|
||||
memset(matar, 0, 4*32);
|
||||
matar[0]= give_render_material(re, ob, 0);
|
||||
for(a=0; a<ob->totcol; a++) {
|
||||
totmat= ob->totcol+1;
|
||||
matar= MEM_callocN(sizeof(Material*)*totmat, "init_render_surf matar");
|
||||
|
||||
for(a=0; a<totmat; a++) {
|
||||
matar[a]= give_render_material(re, ob, a+1);
|
||||
if(matar[a]->texco & TEXCO_ORCO) {
|
||||
|
||||
if(matar[a] && matar[a]->texco & TEXCO_ORCO)
|
||||
need_orco= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(need_orco) orcobase=orco= get_object_orco(re, ob);
|
||||
|
@ -2840,6 +2840,8 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
|
|||
freedisplist(&cu->disp);
|
||||
SWAP(ListBase, olddl, cu->disp);
|
||||
}
|
||||
|
||||
MEM_freeN(matar);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
|
Loading…
Reference in New Issue