Skip to main content
 首页 » 编程设计

python之使用搅拌器创建平铺 map

2025年05月04日25shangdawei

我正在研究基于 Blender 中制作的 3D 模型创建 map 图 block ,

map 在 blender 中为 16 x 16。

我有 4 个不同的缩放级别,每个图 block 为 100 x 100 像素。最大缩小级别的整个 map 是 4 x 4 block ,构成 400 x 400 的图像。

最大的放大级别是 256 x 256 显然构建了 25600 x 25600 的图像

我需要的是一个用于 blender 的脚本,它可以从模型中创建瓷砖。

我以前从未用 python 编写过,所以我一直在尝试改编一些已经存在的脚本。

到目前为止,我已经想出了一个脚本,但效果不是很好。我很难让瓷砖无缝排列。我不太关心更改相机的高度,因为我始终可以创建 6400 x 6400 图像的相同缩小图 block 并将生成的图像拆分为正确的图 block 。

这是我到目前为止所得到的......

#!BPY 
 
""" 
Name: 'Export Map Tiles' 
Blender: '242' 
Group: 'Export' 
Tip: 'Export to Map' 
""" 
 
import Blender 
from Blender import Scene,sys 
from Blender.Scene import Render 
 
def init(): 
        thumbsize = 200 
        CameraHeight = 4.4 
        YStart = -8 
        YMove = 4 
        XStart = -8 
        XMove = 4 
        ZoomLevel = 1 
        Path = "/Images/Map/" 
        Blender.drawmap = [thumbsize,CameraHeight,YStart,YMove,XStart,XMove,ZoomLevel,Path] 
 
 
def show_prefs(): 
        buttonthumbsize = Blender.Draw.Create(Blender.drawmap[0]); 
        buttonCameraHeight = Blender.Draw.Create(Blender.drawmap[1]) 
        buttonYStart = Blender.Draw.Create(Blender.drawmap[2]) 
        buttonYMove = Blender.Draw.Create(Blender.drawmap[3]) 
        buttonXStart = Blender.Draw.Create(Blender.drawmap[4]) 
        buttonXMove = Blender.Draw.Create(Blender.drawmap[5]) 
        buttonZoomLevel = Blender.Draw.Create(Blender.drawmap[6]) 
        buttonPath = Blender.Draw.Create(Blender.drawmap[7]) 
 
    block = [] 
    block.append(("Image Size", buttonthumbsize, 0, 500)) 
    block.append(("Camera Height", buttonCameraHeight, -0, 10)) 
    block.append(("Y Start", buttonYStart, -10, 10)) 
    block.append(("Y Move", buttonYMove, 0, 5)) 
    block.append(("X Start", buttonXStart,-10, 10)) 
    block.append(("X Move", buttonXMove, 0, 5)) 
    block.append(("Zoom Level", buttonZoomLevel, 1, 10)) 
    block.append(("Export Path", buttonPath,0,200,"The Path to save the tiles")) 
 
    retval = Blender.Draw.PupBlock("Draw Map: Preferences" , block) 
 
    if retval: 
        Blender.drawmap[0] = buttonthumbsize.val 
        Blender.drawmap[1] = buttonCameraHeight.val 
        Blender.drawmap[2] = buttonYStart.val 
        Blender.drawmap[3] = buttonYMove.val 
        Blender.drawmap[4] = buttonXStart.val 
        Blender.drawmap[5] = buttonXMove.val 
        Blender.drawmap[6] = buttonZoomLevel.val 
        Blender.drawmap[7] = buttonPath.val 
        Export() 
 
def Export(): 
    scn = Scene.GetCurrent() 
    context = scn.getRenderingContext() 
 
    def cutStr(str): #cut off path leaving name 
        c = str.find("\\") 
        while c != -1: 
            c = c + 1 
            str = str[c:] 
            c = str.find("\\") 
 
        str = str[:-6] 
        return str 
 
    #variables from gui: 
    thumbsize,CameraHeight,YStart,YMove,XStart,XMove,ZoomLevel,Path = Blender.drawmap 
 
 
    XMove = XMove / ZoomLevel 
    YMove = YMove / ZoomLevel 
    Camera = Scene.GetCurrent().getCurrentCamera() 
    Camera.LocZ = CameraHeight / ZoomLevel 
    YStart = YStart + (YMove / 2) 
    XStart = XStart + (XMove / 2) 
 
    #Point it straight down 
    Camera.RotX = 0 
    Camera.RotY = 0 
    Camera.RotZ = 0 
    TileCount = 4**ZoomLevel 
    #Because the first thing we do is move the camera, start it off the map 
    Camera.LocY = YStart - YMove 
    for i in range(0,TileCount): 
        Camera.LocY = Camera.LocY + YMove 
        Camera.LocX = XStart - XMove 
        for j in range(0,TileCount): 
            Camera.LocX = Camera.LocX + XMove 
            Render.EnableDispWin() 
            context.extensions = True 
            context.renderPath = Path 
 
            #setting thumbsize 
            context.imageSizeX(thumbsize) 
            context.imageSizeY(thumbsize) 
 
            #could be put into a gui. 
            context.imageType = Render.PNG 
            context.enableOversampling(0) 
 
            #render 
            context.render() 
 
            #save image 
            ZasString = '%s' %(int(ZoomLevel)) 
            XasString = '%s' %(int(j+1)) 
            YasString = '%s' %(int((3-i)+1)) 
            context.saveRenderedImage("Z" + ZasString + "X" + XasString + "Y" + YasString) 
 
            #close the windows 
 
            Render.CloseRenderWindow() 
 
try: 
        type(Blender.drawmap) 
except: 
        #print 'initialize extern variables' 
        init() 
show_prefs()     

请您参考如下方法:

这最终还是比较简单的。

我按比例放大了模型,使 map 上的 1 个图 block 在 blender 中变成了 1 个网格。

将相机设置为正交。

将相机上的比例设置为 1 表示最高变焦,4 表示下一个,16 表示下一个,依此类推。

相应地更新了起始坐标和移动值。