diff options
-rw-r--r-- | release/scripts/bpymodules/boxpack2d.py | 498 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_blender.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_customdata.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 41 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 19 | ||||
-rw-r--r-- | source/blender/include/butspace.h | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_customdata_types.h | 2 | ||||
-rw-r--r-- | source/blender/render/intern/source/convertblender.c | 8 | ||||
-rw-r--r-- | source/blender/src/buttons_editing.c | 66 |
9 files changed, 118 insertions, 522 deletions
diff --git a/release/scripts/bpymodules/boxpack2d.py b/release/scripts/bpymodules/boxpack2d.py deleted file mode 100644 index 2268b9154dc..00000000000 --- a/release/scripts/bpymodules/boxpack2d.py +++ /dev/null @@ -1,498 +0,0 @@ -''' -# 2D Box packing function used by archimap -# packs any list of 2d boxes into a square and returns a list of packed boxes. -# Example of usage. -import boxpack2d - -# Build boxe list. -# the unique ID is not used. -# just the width and height. -boxes2Pack = [] -anyUniqueID = 0; w = 2.2; h = 3.8 -boxes2Pack.append([anyUniqueID, w,h]) -anyUniqueID = 1; w = 4.1; h = 1.2 -boxes2Pack.append([anyUniqueID, w,h]) -anyUniqueID = 2; w = 5.2; h = 9.2 -boxes2Pack.append([anyUniqueID, w,h]) -anyUniqueID = 3; w = 8.3; h = 7.3 -boxes2Pack.append([anyUniqueID, w,h]) -anyUniqueID = 4; w = 1.1; h = 5.1 -boxes2Pack.append([anyUniqueID, w,h]) -anyUniqueID = 5; w = 2.9; h = 8.1 -boxes2Pack.append([anyUniqueID, w,h]) -anyUniqueID = 6; w = 4.2; h = 6.2 -boxes2Pack.append([anyUniqueID, w,h]) -# packedLs is a list of [(anyUniqueID, left, bottom, width, height)...] -packWidth, packHeight, packedLs = boxpack2d.boxPackIter(boxes2Pack) -''' - -from Blender import NMesh, Window, Object, Scene -''' -def debug_(x,y,z): - ob = Object.New("Empty") - ob.loc= x,y,z - Scene.GetCurrent().link(ob) -''' - -# a box packing vert -class vt: - def __init__(self, x,y): - self.x, self.y = x, y - - self.free = 15 - - # Set flags so cant test bottom left of 0/0 - #~ BLF = 1; TRF = 2; TLF = 4; BRF = 8 - - #self.users = [] # A list of boxes. - # Rather then users, store Quadrents - self.blb = self.tlb = self.brb = self.trb = None - - - # A hack to remember the box() that last intersectec this vert - self.intersectCache = ([], [], [], []) - -class vertList: - def __init__(self, verts=[]): - self.verts = verts - - def sortCorner(self,w,h): - ''' - Sorts closest first. - uses the box w/h as a bias, - this makes it so its less likely to have lots of poking out bits - that use too much - Lambada based sort - ''' - # self.verts.sort(lambda A, B: cmp(max(A.x+w, A.y+h) , max(B.x+w, B.y+h))) # Reverse area sort - try: self.verts.sort(key = lambda b: max(b.x+w, b.y+h) ) # Reverse area sort - except: self.verts.sort(lambda A, B: cmp(max(A.x+w, A.y+h) , max(B.x+w, B.y+h))) # Reverse area sort - - - -class box: - def __init__(self, width, height, id=None): - - self.id= id - - self.area = width * height # real area - self.farea = width + height # fake area - #self.farea = float(min(width, height)) / float(max(width, height)) # fake area - - self.width = width - self.height = height - - # Append 4 new verts - # (BL,TR,TL,BR) / 0,1,2,3 - self.v=v= [vt(0,0), vt(width,height), vt(0,height), vt(width,0)] - - # Set the interior quadrents as used. - v[0].free &= ~TRF - v[1].free &= ~BLF - v[2].free &= ~BRF - v[3].free &= ~TLF - - #for v in self.v: - # v.users.append(self) - v[0].trb = self - v[1].blb = self - v[2].brb = self - v[3].tlb = self - - - def updateV34(self): - ''' - Updates verts 3 & 4 from 1 and 2 - since 3 and 4 are only there foill need is resizing/ rotating of patterns on the fly while I painr new box placement - but may be merged later with other verts - ''' - self.v[TL].x = self.v[BL].x - self.v[TL].y = self.v[TR].y - - self.v[BR].x = self.v[TR].x - self.v[BR].y = self.v[BL].y - - - def setLeft(self, lft): - self.v[TR].x = lft + self.v[TR].x - self.v[BL].x - self.v[BL].x = lft - # update othere verts - self.updateV34() - - def setRight(self, rgt): - self.v[BL].x = rgt - (self.v[TR].x - self.v[BL].x) - self.v[TR].x = rgt - self.updateV34() - - def setBottom(self, btm): - self.v[TR].y = btm + self.v[TR].y - self.v[BL].y - self.v[BL].y = btm - self.updateV34() - - def setTop(self, tp): - self.v[BL].y = tp - (self.v[TR].y - self.v[BL].y) - self.v[TR].y = tp - self.updateV34() - - def getLeft(self): - return self.v[BL].x - - def getRight(self): - return self.v[TR].x - - def getBottom(self): - return self.v[BL].y - - def getTop(self): - return self.v[TR].y - - def overlapAll(self, boxLs, intersectCache): # Flag index lets us know which quadere - ''' Returns none, meaning it didnt overlap any new boxes ''' - v= self.v - if v[BL].x < 0: - return True - elif v[BL].y < 0: - return True - else: - bIdx = len(intersectCache) - while bIdx: - bIdx-=1 - b = intersectCache[bIdx] - if not ( v[TR].y <= b.v[BL].y or\ - v[BL].y >= b.v[TR].y or\ - v[BL].x >= b.v[TR].x or\ - v[TR].x <= b.v[BL].x ): - - return True # Intersection with existing box - #return 0 # Must keep looking - - for b in boxLs.boxes: - if not (v[TR].y <= b.v[BL].y or\ - v[BL].y >= b.v[TR].y or\ - v[BL].x >= b.v[TR].x or\ - v[TR].x <= b.v[BL].x ): - - return b # Intersection with new box. - return False - - - - def place(self, vert, quad): - ''' - Place the box on the free quadrent of the vert - ''' - if quad == BLF: - self.setRight(vert.x) - self.setTop(vert.y) - - elif quad == TRF: - self.setLeft(vert.x) - self.setBottom(vert.y) - - elif quad == TLF: - self.setRight(vert.x) - self.setBottom(vert.y) - - elif quad == BRF: - self.setLeft(vert.x) - self.setTop(vert.y) - - # Trys to lock a box onto another box's verts - # cleans up double verts after - def tryVert(self, boxes, baseVert): - for flagIndex, freeQuad in enumerate(quadFlagLs): - #print 'Testing ', self.width - if baseVert.free & freeQuad: - - self.place(baseVert, freeQuad) - overlapBox = self.overlapAll(boxes, baseVert.intersectCache[flagIndex]) - if overlapBox is False: # There is no overlap - baseVert.free &= ~freeQuad # Removes quad - # Appends all verts but the one that matches. this removes the need for remove doubles - for vIdx in (0,1,2,3): # (BL,TR,TL,BR) / 0,1,2,3 - self_v= self.v[vIdx] # shortcut - if not (self_v.x == baseVert.x and self_v.y == baseVert.y): - boxList.packedVerts.verts.append(self_v) - else: - baseVert.free &= self_v.free # make sure the that any unfree areas are wiped. - - # Inherit used boxes from old verts - if self_v.blb: baseVert.blb = self_v.blb - if self_v.brb: baseVert.brb = self_v.brb #print 'inherit2' - if self_v.tlb: baseVert.tlb = self_v.tlb #print 'inherit3' - if self_v.trb: baseVert.trb = self_v.trb #print 'inherit4' - self.v[vIdx] = baseVert - - - - # Logical checking for used verts by compares box sized and works out verts that may be free. - # Verticle - - if baseVert.tlb and baseVert.trb and\ - (self == baseVert.tlb or self == baseVert.trb): - if baseVert.tlb.height > baseVert.trb.height: - baseVert.trb.v[TL].free &= ~(TLF|BLF) - elif baseVert.tlb.height < baseVert.trb.height: - baseVert.tlb.v[TR].free &= ~(TRF|BRF) - else: # same - baseVert.tlb.v[TR].free &= ~BLF - baseVert.trb.v[TL].free &= ~BRF - - - elif baseVert.blb and baseVert.brb and\ - (self == baseVert.blb or self == baseVert.brb): - if baseVert.blb.height > baseVert.brb.height: - baseVert.brb.v[BL].free &= ~(TLF|BLF) - elif baseVert.blb.height < baseVert.brb.height: - baseVert.blb.v[BR].free &= ~(TRF|BRF) - else: # same - baseVert.blb.v[BR].free &= ~TRF - baseVert.brb.v[BL].free &= ~TLF - - # Horizontal - if baseVert.tlb and baseVert.blb and\ - (self == baseVert.tlb or self == baseVert.blb): - if baseVert.tlb.width > baseVert.blb.width: - baseVert.blb.v[TL].free &= ~(TLF|TRF) - elif baseVert.tlb.width < baseVert.blb.width: - baseVert.tlb.v[BL].free &= ~(BLF|BRF) - else: # same - baseVert.blb.v[TL].free &= ~TRF - baseVert.tlb.v[BL].free &= ~BRF - - - elif baseVert.trb and baseVert.brb and\ - (self == baseVert.trb or self == baseVert.brb): - if baseVert.trb.width > baseVert.brb.width: - baseVert.brb.v[TR].free &= ~(TRF|TRF) - elif baseVert.trb.width < baseVert.brb.width: - baseVert.trb.v[BR].free &= ~(BLF|BRF) - else: # same - baseVert.brb.v[TR].free &= ~TLF - baseVert.trb.v[BR].free &= ~BLF - # END LOGICAL VREE SIZE REMOVAL - - - - - return 1 # Working - - # We have a box that intersects that quadrent. - elif overlapBox is not False and overlapBox is not True: # True is used for a box thats alredt in the freq list or out of bounds error. - # There was an overlap, add this box to the verts list - #quadFlagLs = (BLF,BRF,TLF,TRF) - baseVert.intersectCache[flagIndex].append(overlapBox) - - # Limit the cache size - if len(baseVert.intersectCache[flagIndex]) > 8: - del baseVert.intersectCache[flagIndex][0] - - return 0 - - -class boxList: - #Global vert pool, stores used lists - packedVerts = vertList() # will be vertList() - - def __init__(self, boxes): - self.boxes = boxes - - # keep a running update of the width and height so we know the area - # initialize with first box, fixes but where we whwere only packing 1 box - # At the moment we only start with 1 box so the code below will loop over 1. but thats ok. - width = height = 0.0 - if boxes: - for b in boxes: - if width < b.width: width= b.width - if height < b.height: height= b.height - self.width= width - self.height= height - - # boxArea is the total area of all boxes in the list, - # can be used with packArea() to determine waistage. - self.boxArea = 0 # incremented with addBox() - - - # Just like MyBoxLs.boxes.append(), but sets bounds - def addBoxPack(self, box): - '''Adds the box to the boxlist and resized the main bounds and adds area. ''' - self.width = max(self.width, box.getRight()) - self.height = max(self.height, box.getTop()) - - self.boxArea += box.area - - # iterate through these - #~ quadFlagLs = (1,8,4,2) - #~ # Flags for vert idx used quads - #~ BLF = 1; TRF = 2; TLF = 4; BRF = 8 - #~ quadFlagLs = (BLF,BRF,TLF,TRF) - - # Look through all the free vert quads and see if there are some we can remove - # - - for v in box.v: - - # Is my bottom being used. - - if v.free & BLF and v.free & BRF: # BLF and BRF - for b in self.boxes: - if b.v[TR].y == v.y: - if b.v[TR].x > v.x: - if b.v[BL].x < v.x: - v.free &= ~(BLF|BRF) # Removes quad - - # Is my left being used. - if v.free & BLF and v.free & TLF: - for b in self.boxes: - if b.v[TR].x == v.x: - if b.v[TR].y > v.y: - if b.v[BL].y < v.y: - v.free &= ~(BLF|TLF) # Removes quad - - if v.free & TRF and v.free & TLF: - # Is my top being used. - for b in self.boxes: - if b.v[BL].y == v.y: - if b.v[TR].x > v.x: - if b.v[BL].x < v.x: - v.free &= ~(TLF|TRF) # Removes quad - - - # Is my right being used. - if v.free & TRF and v.free & BRF: - for b in self.boxes: - if b.v[BL].x == v.x: - if b.v[TR].y > v.y: - if b.v[BL].y < v.y: - v.free &= ~(BRF|TRF) # Removes quad - - - self.boxes.append(box) - - - - # Just like MyBoxLs.boxes.append(), but sets bounds - def addBox(self, box): - self.boxes.append(box) - self.boxArea += box.area - - # The area of the backing bounds. - def packedArea(self): - return self.width * self.height - - # Sort boxes by area - def sortArea(self): - try: self.boxes.sort(key=lambda b: b.area ) - except: self.boxes.sort(lambda A, B: cmp(A.area, B.area) ) - - - # BLENDER only - def draw(self): - m = NMesh.GetRaw() - - - for b in self.boxes: - z = min(b.width, b.height ) / max(b.width, b.height ) - #z = b.farea - #z=0 - f = NMesh.Face() - m.verts.append(NMesh.Vert(b.getLeft(), b.getBottom(), z)) - f.v.append(m.verts[-1]) - m.verts.append(NMesh.Vert(b.getRight(), b.getBottom(), z)) - f.v.append(m.verts[-1]) - m.verts.append(NMesh.Vert(b.getRight(), b.getTop(), z)) - f.v.append(m.verts[-1]) - m.verts.append(NMesh.Vert(b.getLeft(), b.getTop(), z)) - f.v.append(m.verts[-1]) - m.faces.append(f) - NMesh.PutRaw(m, 's') - Window.Redraw(1) - - def pack(self): - self.sortArea() - - if not self.boxes: - return - - packedboxes = boxList([self.boxes[-1]]) - - # Remove verts we KNOW cant be added to - - unpackedboxes = self.boxes[:-1] - - # Start with this box, the biggest box - boxList.packedVerts.verts.extend(packedboxes.boxes[0].v) - - while unpackedboxes: # != [] - while the list of unpacked boxes is not empty. - - freeBoxIdx = len(unpackedboxes) - while freeBoxIdx: - freeBoxIdx-=1 - freeBoxContext= unpackedboxes[freeBoxIdx] - # Sort the verts with this boxes dimensions as a bias, so less poky out bits are made. - boxList.packedVerts.sortCorner(freeBoxContext.width, freeBoxContext.height) - - vertIdx = 0 - - for baseVert in boxList.packedVerts.verts: - if baseVert.free: # != 0 - # This will lock the box if its possibel - if freeBoxContext.tryVert(packedboxes, baseVert): - packedboxes.addBoxPack( unpackedboxes.pop(freeBoxIdx) ) # same as freeBoxContext. but may as well pop at the same time. - freeBoxIdx = -1 - break - - freeBoxIdx +=1 - - boxList.packedVerts.verts = [] # Free the list, so it dosent use ram between runs. - - self.width = packedboxes.width - self.height = packedboxes.height - # - def list(self): - ''' Once packed, return a list of all boxes as a list of tuples - (X/Y/WIDTH/HEIGHT) ''' - return [(b.id, b.getLeft(), b.getBottom(), b.width, b.height ) for b in self.boxes] - - -''' Define all globals here ''' -# vert IDX's, make references easier to understand. -BL = 0; TR = 1; TL = 2; BR = 3 - -# iterate through these -# Flags for vert idx used quads -BLF = 1; TRF = 2; TLF = 4; BRF = 8 -quadFlagLs = (BLF,BRF,TLF,TRF) - - -# Packs a list w/h's into box types and places then #Iter times -def boxPackIter(boxLs, iter=1, draw=0): - iterIdx = 0 - bestArea = None - # Iterate over packing the boxes to get the best FIT! - while iterIdx < iter: - myBoxLs = boxList([]) - for b in boxLs: - myBoxLs.addBox( box(b[1], b[2], b[0]) ) # w/h/id - - myBoxLs.pack() - # myBoxLs.draw() # Draw as we go? - - newArea = myBoxLs.packedArea() - - #print 'pack test %s of %s, area:%.2f' % (iterIdx, iter, newArea) - - # First time? - if bestArea == None: - bestArea = newArea - bestBoxLs = myBoxLs - elif newArea < bestArea: - bestArea = newArea - bestBoxLs = myBoxLs - iterIdx+=1 - - - if draw: - bestBoxLs.draw() - - #print 'best area: %.4f, %.2f%% efficient' % (bestArea, (float(bestBoxLs.boxArea) / (bestArea+0.000001))*100) - - return bestBoxLs.width, bestBoxLs.height, bestBoxLs.list()
\ No newline at end of file diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index a96c1b43170..b40ef215a53 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -44,7 +44,7 @@ struct ListBase; struct MemFile; #define BLENDER_VERSION 243 -#define BLENDER_SUBVERSION 1 +#define BLENDER_SUBVERSION 2 #define BLENDER_MINVERSION 240 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index b41c06f046f..4a486e6795f 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -184,6 +184,7 @@ void *CustomData_get_layer_named(const struct CustomData *data, int type, int CustomData_get_layer_index(const struct CustomData *data, int type); int CustomData_get_named_layer_index(const struct CustomData *data, int type, char *name); int CustomData_get_active_layer_index(const struct CustomData *data, int type); +int CustomData_get_render_layer_index(const struct CustomData *data, int type); /* copies the data from source to the data element at index in the first * layer of type @@ -204,6 +205,7 @@ void *CustomData_set_layer_n(const struct CustomData *data, int type, int n, voi /* sets the nth layer of type as active */ void CustomData_set_layer_active(struct CustomData *data, int type, int n); +void CustomData_set_layer_render(struct CustomData *data, int type, int n); /* adds flag to the layer flags */ void CustomData_set_layer_flag(struct CustomData *data, int type, int flag); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 68319b799a2..e239583c4eb 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -410,7 +410,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, { const LayerTypeInfo *typeInfo; CustomDataLayer *layer, *newlayer; - int i, type, number = 0, lasttype = -1, lastactive = 0; + int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0; for(i = 0; i < source->totlayer; ++i) { layer = &source->layers[i]; @@ -421,6 +421,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, if (type != lasttype) { number = 0; lastactive = layer->active; + lastrender = layer->active_rnd; lasttype = type; } else @@ -437,8 +438,10 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, newlayer = customData_add_layer__internal(dest, type, alloctype, layer->data, totelem, layer->name); - if(newlayer) + if(newlayer) { newlayer->active = lastactive; + newlayer->active_rnd = lastrender; + } } } @@ -526,6 +529,17 @@ int CustomData_get_active_layer_index(const CustomData *data, int type) return -1; } +int CustomData_get_render_layer_index(const CustomData *data, int type) +{ + int i; + + for(i=0; i < data->totlayer; ++i) + if(data->layers[i].type == type) + return i + data->layers[i].active_rnd; + + return -1; +} + void CustomData_set_layer_active(CustomData *data, int type, int n) { int i; @@ -535,6 +549,16 @@ void CustomData_set_layer_active(CustomData *data, int type, int n) data->layers[i].active = n; } +void CustomData_set_layer_render(CustomData *data, int type, int n) +{ + int i; + + for(i=0; i < data->totlayer; ++i) + if(data->layers[i].type == type) + data->layers[i].active_rnd = n; +} + + void CustomData_set_layer_flag(struct CustomData *data, int type, int flag) { int i; @@ -617,11 +641,14 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data, else data->layers[index].name[0] = '\0'; - if(index > 0 && data->layers[index-1].type == type) + if(index > 0 && data->layers[index-1].type == type) { data->layers[index].active = data->layers[index-1].active; - else + data->layers[index].active_rnd = data->layers[index-1].active_rnd; + } else { data->layers[index].active = 0; - + data->layers[index].active_rnd = 0; + } + customData_update_offsets(data); return &data->layers[index]; @@ -679,8 +706,10 @@ int CustomData_free_layer(CustomData *data, int type, int totelem, int index) i = CustomData_get_layer_index(data, type); if (i >= 0) - for (; i < data->totlayer && data->layers[i].type == type; i++) + for (; i < data->totlayer && data->layers[i].type == type; i++) { data->layers[i].active--; + data->layers[i].active_rnd--; + } } if (data->totlayer <= data->maxlayer-CUSTOMDATA_GROW) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index ceab6863aa6..ace436cf04c 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4316,6 +4316,18 @@ static void customdata_version_242(Mesh *me) mesh_update_customdata_pointers(me); } +/*only copy render texface layer from active*/ +static void customdata_version_243(Mesh *me) +{ + CustomDataLayer *layer; + int a; + + for (a=0; a < me->fdata.totlayer; a++) { + layer= &me->fdata.layers[a]; + layer->active_rnd = layer->active; + } +} + /* struct NodeImageAnim moved to ImageUser, and we make it default available */ static void do_version_ntree_242_2(bNodeTree *ntree) { @@ -6416,6 +6428,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } } + + /* render layer added, this is not the active layer */ + if(main->versionfile <= 243 || main->subversionfile < 2) { + Mesh *me; + for(me=main->mesh.first; me; me=me->id.next) + customdata_version_243(me); + } } /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index bde3db33376..142d2ae1d0b 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -406,6 +406,8 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la #define B_SETTFACE 2079 #define B_SETMCOL 2080 #define B_JOINTRIA 2081 +#define B_SETTFACE_RND 2082 +#define B_SETMCOL_RND 2083 /* *********************** */ #define B_VGROUPBUTS 2100 diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 921554552ef..b9f6ab0e60b 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -38,6 +38,8 @@ typedef struct CustomDataLayer { int offset; /* in editmode, offset of layer in block */ int flag; /* general purpose flag */ int active; /* number of the active layer of this type */ + int active_rnd; /* number of the layer to render*/ + char pad[4]; char name[32]; /* layer name */ void *data; /* layer data */ } CustomDataLayer; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 29773d5152b..e93a509efd1 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -1757,7 +1757,7 @@ static void use_mesh_edge_lookup(Render *re, DerivedMesh *dm, MEdge *medge, Vlak if(layer->type == CD_MTFACE && mtfn < MAX_MTFACE) { mtface= &((MTFace*)layer->data)[edp->f]; - n= vlakren_customdata_layer_num(mtfn++, layer->active); + n= vlakren_customdata_layer_num(mtfn++, layer->active_rnd); mtf= RE_vlakren_get_tface(re, vlr, n, &name, 1); *mtf= *mtface; @@ -1769,7 +1769,7 @@ static void use_mesh_edge_lookup(Render *re, DerivedMesh *dm, MEdge *medge, Vlak } else if(layer->type == CD_MCOL && mcn < MAX_MCOL) { mcol= &((MCol*)layer->data)[edp->f*4]; - n= vlakren_customdata_layer_num(mcn++, layer->active); + n= vlakren_customdata_layer_num(mcn++, layer->active_rnd); mc= RE_vlakren_get_mcol(re, vlr, n, &name, 1); mc[0]= mcol[edp->i1]; @@ -1996,13 +1996,13 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts name= layer->name; if(layer->type == CD_MTFACE && mtfn < MAX_MTFACE) { - n= vlakren_customdata_layer_num(mtfn++, layer->active); + n= vlakren_customdata_layer_num(mtfn++, layer->active_rnd); mtf= RE_vlakren_get_tface(re, vlr, n, &name, 1); mtface= (MTFace*)layer->data; *mtf= mtface[a]; } else if(layer->type == CD_MCOL && mcn < MAX_MCOL) { - n= vlakren_customdata_layer_num(mcn++, layer->active); + n= vlakren_customdata_layer_num(mcn++, layer->active_rnd); mc= RE_vlakren_get_mcol(re, vlr, n, &name, 1); mcol= (MCol*)layer->data; memcpy(mc, &mcol[a*4], sizeof(MCol)*4); diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 3700dc17980..b68d81b510d 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -172,7 +172,7 @@ static float editbutweight= 1.0; float editbutvweight= 1; -static int actmcol= 0, acttface= 0; +static int actmcol= 0, acttface= 0, acttface_rnd = 0, actmcol_rnd = 0; extern ListBase editNurb; @@ -691,10 +691,10 @@ static void delete_customdata_layer(void *data1, void *data2) Mesh *me= (Mesh*)data1; CustomData *data= (G.obedit)? &G.editMesh->fdata: &me->fdata; CustomDataLayer *layer= (CustomDataLayer*)data2; - void *actlayerdata, *layerdata=layer->data; + void *actlayerdata, *rndlayerdata, *layerdata=layer->data; int type= layer->type; int index= CustomData_get_layer_index(data, type); - int i, actindex; + int i, actindex, rndindex; /*ok, deleting a non-active layer needs to preserve the active layer indices. to do this, we store a pointer to the .data member of both layer and the active layer, @@ -704,6 +704,7 @@ static void delete_customdata_layer(void *data1, void *data2) this is necassary because the deletion functions only support deleting the active layer. */ actlayerdata = data->layers[CustomData_get_active_layer_index(data, type)].data; + rndlayerdata = data->layers[CustomData_get_render_layer_index(data, type)].data; CustomData_set_layer_active(data, type, layer - &data->layers[index]); /* Multires is handled seperately because the display data is separate @@ -741,6 +742,21 @@ static void delete_customdata_layer(void *data1, void *data2) CustomData_set_layer_active(data, type, actindex); } + if (rndlayerdata != layerdata) { + /*find index. . .*/ + rndindex = CustomData_get_layer_index(data, type); + for (i=rndindex; i<data->totlayer; i++) { + if (data->layers[i].data == rndlayerdata) { + rndindex = i - rndindex; + break; + } + } + + /*set index. . .*/ + CustomData_set_layer_render(data, type, rndindex); + } + + DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); if(type == CD_MTFACE) @@ -753,7 +769,12 @@ static void delete_customdata_layer(void *data1, void *data2) allqueue(REDRAWBUTSEDIT, 0); } -static int customdata_buttons(uiBlock *block, Mesh *me, CustomData *data, int type, int *activep, int setevt, int newevt, char *label, char *shortlabel, char *browsetip, char *newtip, char *deltip, int x, int y) +static int customdata_buttons( + uiBlock *block, Mesh *me, CustomData *data, + int type, int *activep, int *renderp, + int setevt, int setevt_rnd, int newevt, + char *label, char *shortlabel, char *browsetip, char *browsetip_rnd, + char *newtip, char *deltip, int x, int y) { CustomDataLayer *layer; uiBut *but; @@ -777,9 +798,11 @@ static int customdata_buttons(uiBlock *block, Mesh *me, CustomData *data, int ty if(layer->type == type) { *activep= layer->active + 1; + *renderp= layer->active_rnd + 1; - uiDefButI(block, ROW, setevt, "", x,y,25,19, activep, 1.0, count, 0, 0, browsetip); - but=uiDefBut(block, TEX, setevt, "", x+25,y,170,19, layer->name, 0.0, 31.0, 0, 0, label); + uiDefButI(block, ROW, setevt, "A", x,y,25,19, activep, 1.0, count, 0, 0, browsetip); + uiDefButI(block, ROW, setevt_rnd, "R", x+25,y,25,19, renderp, 1.0, count, 0, 0, browsetip_rnd); + but=uiDefBut(block, TEX, setevt, "", x+50,y,145,19, layer->name, 0.0, 31.0, 0, 0, label); uiButSetFunc(but, verify_customdata_name_func, data, layer); but= uiDefIconBut(block, BUT, B_NOP, VICON_X, x+195,y,25,19, NULL, 0.0, 0.0, 0.0, 0.0, deltip); uiButSetFunc(but, delete_customdata_layer, me, layer); @@ -848,14 +871,14 @@ static void editing_panel_mesh_type(Object *ob, Mesh *me) uiBlockEndAlign(block); fdata= (G.obedit)? &G.editMesh->fdata: &me->fdata; - yco= customdata_buttons(block, me, fdata, CD_MTFACE, &acttface, - B_SETTFACE, B_NEWTFACE, "UV Texture", "UV Texture:", - "Set active UV texture", "Creates a new UV texture layer", + yco= customdata_buttons(block, me, fdata, CD_MTFACE, &acttface, &acttface_rnd, + B_SETTFACE, B_SETTFACE_RND, B_NEWTFACE, "UV Texture", "UV Texture:", + "Set active UV texture", "Set rendering UV texture", "Creates a new UV texture layer", "Removes the current UV texture layer", 190, 130); - yco= customdata_buttons(block, me, fdata, CD_MCOL, &actmcol, - B_SETMCOL, B_NEWMCOL, "Vertex Color", "Vertex Color:", - "Sets active vertex color layer", "Creates a new vertex color layer", + yco= customdata_buttons(block, me, fdata, CD_MCOL, &actmcol, &actmcol_rnd, + B_SETMCOL, B_SETMCOL_RND, B_NEWMCOL, "Vertex Color", "Vertex Color:", + "Sets active vertex color layer", "Sets rendering vertex color layer", "Creates a new vertex color layer", "Removes the current vertex color layer", 190, yco-5); if(yco < 0) @@ -4147,6 +4170,15 @@ void do_meshbuts(unsigned short event) allqueue(REDRAWBUTSEDIT, 0); } break; + case B_SETMCOL_RND: + if (G.obedit || me) { + CustomData *fdata= (G.obedit)? &em->fdata: &me->fdata; + CustomData_set_layer_render(fdata, CD_MCOL, actmcol_rnd-1); + + BIF_undo_push("Set Render Vertex Color"); + allqueue(REDRAWBUTSEDIT, 0); + } + break; case B_NEWTFACE: if(me) @@ -4197,7 +4229,15 @@ void do_meshbuts(unsigned short event) allqueue(REDRAWIMAGE, 0); } break; - + case B_SETTFACE_RND: + if (G.obedit || me) { + CustomData *fdata= (G.obedit)? &em->fdata: &me->fdata; + CustomData_set_layer_render(fdata, CD_MTFACE, acttface_rnd-1); + BIF_undo_push("Set Render UV Texture"); + allqueue(REDRAWBUTSEDIT, 0); + } + break; + case B_FLIPNORM: if(G.obedit) { flip_editnormals(); |