Made it so blender has an active render layer for Uv and Vertex color mesh layers.
authorCampbell Barton <ideasman42@gmail.com>
Wed, 2 May 2007 00:01:23 +0000 (00:01 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 2 May 2007 00:01:23 +0000 (00:01 +0000)
This means changing the active UV/VCol layers wont change what renders.
needed to adjust the minor version so old files will copy the active layer to the render-uv/vcol layer.

boxpack2d.py - redoen in C now, dont need python version.

release/scripts/bpymodules/boxpack2d.py [deleted file]
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/BKE_customdata.h
source/blender/blenkernel/intern/customdata.c
source/blender/blenloader/intern/readfile.c
source/blender/include/butspace.h
source/blender/makesdna/DNA_customdata_types.h
source/blender/render/intern/source/convertblender.c
source/blender/src/buttons_editing.c

diff --git a/release/scripts/bpymodules/boxpack2d.py b/release/scripts/bpymodules/boxpack2d.py
deleted file mode 100644 (file)
index 2268b91..0000000
+++ /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
index a96c1b4317096406ee0c9ea716e1f9ffafc06597..b40ef215a53dd98b4091d12b1b19e3542337add3 100644 (file)
@@ -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
index b41c06f046fb5f258e61d951799115ec93e1132a..4a486e6795f936dd0e544d860e62355e5d3226e5 100644 (file)
@@ -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);
index 68319b799a2ed5325b14ac16da990340fc964888..e239583c4eb13e66337eaa4874381502623400ab 100644 (file)
@@ -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)
index ceab6863aa696146480b4620728d67e6fb995f62..ace436cf04c65d50e6230b660441176433eea2d2 100644 (file)
@@ -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! */
index bde3db333769827cc5faeb578a097ebf98a74322..142d2ae1d0bd1aafd202e592f31bcd842974e7a6 100644 (file)
@@ -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
index 921554552ef6cd720a22d6a1c4d796e8aa892f75..b9f6ab0e60b70091d3adecbf2bd6453b13ef1490 100644 (file)
@@ -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;
index 29773d5152b7b6584da05d9d71790d1581b75786..e93a509efd1160ef1f60dc0b75a14d04a8231db0 100644 (file)
@@ -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);
index 3700dc1798025af0b578e27419a8d50f09123238..b68d81b510dbd6b0313645712473ea11cf944a8c 100644 (file)
 
 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();