1 from __future__ import absolute_import
2 __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
9 from Cura.util import mesh
10 from Cura.util.meshLoaders import stl
11 from Cura.util.pymclevel import mclevel
14 return os.path.isdir(mclevel.saveFileDir)
16 class minecraftImportWindow(wx.Frame):
17 def __init__(self, parent):
18 super(minecraftImportWindow, self).__init__(parent, title='Cura - Minecraft import')
20 saveFileList = map(os.path.basename, glob.glob(mclevel.saveFileDir + "/*"))
22 self.panel = wx.Panel(self, -1)
23 self.SetSizer(wx.BoxSizer())
24 self.GetSizer().Add(self.panel, 1, wx.EXPAND)
26 sizer = wx.GridBagSizer(2, 2)
28 self.saveListBox = wx.ListBox(self.panel, -1, choices=saveFileList)
29 sizer.Add(self.saveListBox, (0,0), span=(2,1), flag=wx.EXPAND)
30 self.playerListBox = wx.ListBox(self.panel, -1, choices=[])
31 sizer.Add(self.playerListBox, (0,1), span=(2,1), flag=wx.EXPAND)
33 self.previewPanel = wx.Panel(self.panel, -1)
34 self.previewPanel.SetMinSize((512, 512))
35 sizer.Add(self.previewPanel, (0,2), flag=wx.EXPAND)
37 self.importButton = wx.Button(self.panel, -1, 'Import')
38 sizer.Add(self.importButton, (1,2))
40 sizer.AddGrowableRow(1)
42 self.panel.SetSizer(sizer)
44 self.saveListBox.Bind(wx.EVT_LISTBOX, self.OnSaveSelect)
45 self.playerListBox.Bind(wx.EVT_LISTBOX, self.OnPlayerSelect)
46 self.importButton.Bind(wx.EVT_BUTTON, self.OnImport)
48 self.previewPanel.Bind(wx.EVT_PAINT, self.OnPaintPreview)
49 self.previewPanel.Bind(wx.EVT_SIZE, self.OnSizePreview)
50 self.previewPanel.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackgroundPreview)
51 self.previewPanel.Bind(wx.EVT_MOTION, self.OnMotion)
54 self.previewImage = None
56 self.selectArea = None
57 self.draggingArea = False
62 self.gravelPen = wx.Pen(wx.Colour(128, 128, 128))
63 self.sandPen = wx.Pen(wx.Colour(192, 192, 0))
66 for z in xrange(0, 256):
67 self.waterPen.append(wx.Pen(wx.Colour(0,0,min(z+64, 255))))
68 self.grassPen.append(wx.Pen(wx.Colour(0,min(64+z,255),0)))
70 self.isSolid = [True] * 256
71 self.isSolid[0] = False #Air
72 self.isSolid[8] = False #Water
73 self.isSolid[9] = False #Water
74 self.isSolid[10] = False #Lava
75 self.isSolid[11] = False #Lava
76 self.isSolid[50] = False #Torch
77 self.isSolid[51] = False #Fire
79 def OnSaveSelect(self, e):
80 if self.saveListBox.Selection < 0:
82 self.level = mclevel.loadWorld(self.saveListBox.GetItems()[self.saveListBox.Selection])
83 self.playerListBox.Clear()
84 for player in self.level.players:
85 self.playerListBox.Append(player)
87 def OnPlayerSelect(self, e):
88 playerName = self.playerListBox.GetItems()[self.playerListBox.Selection]
89 self.playerPos = map(lambda n: int(n / 16), self.level.getPlayerPosition(playerName))[0::2]
91 self.previewImage = wx.EmptyBitmap(512, 512)
92 for i in xrange(0, 16):
93 for j in xrange(1, i * 2 + 1):
94 self.renderList.insert(0, (15 - i, 16 + i - j))
95 for j in xrange(0, i * 2 + 1):
96 self.renderList.insert(0, (15 + j - i, 15 - i))
97 for j in xrange(0, i * 2 + 1):
98 self.renderList.insert(0, (16 + i, 15 + j - i))
99 for j in xrange(0, i * 2 + 2):
100 self.renderList.insert(0, (16 + i - j, 16 + i))
101 self.previewPanel.Refresh()
103 def OnPaintPreview(self, e):
104 if len(self.renderList) > 0:
105 cx, cy = self.renderList.pop()
107 dc.SelectObject(self.previewImage)
108 chunk = self.level.getChunk(cx + self.playerPos[0] - 16, cy + self.playerPos[1] - 16)
109 dc.SetPen(wx.Pen(wx.Colour(255,0,0)))
110 for x in xrange(0, 16):
111 for y in xrange(0, 16):
112 z = numpy.max(numpy.where(chunk.Blocks[x, y] != 0))
113 type = chunk.Blocks[x, y, z]
115 dc.SetPen(wx.Pen(wx.Colour(z,z,z)))
116 elif type == 2: #Grass
117 dc.SetPen(self.grassPen[z])
118 elif type == 8 or type == 9: #Water
119 dc.SetPen(self.waterPen[z])
120 elif type == 10 or type == 11: #Lava
121 dc.SetPen(wx.Pen(wx.Colour(min(z+64, 255),0,0)))
122 elif type == 12 or type == 24: #Sand/Standstone
123 dc.SetPen(self.sandPen)
124 elif type == 13: #Gravel
125 dc.SetPen(self.gravelPen)
126 elif type == 18: #Leaves
127 dc.SetPen(wx.Pen(wx.Colour(0,max(z-32, 0),0)))
129 dc.SetPen(wx.Pen(wx.Colour(z,z,z)))
130 dc.DrawPoint(cx * 16 + x, cy * 16 + y)
131 dc.SelectObject(wx.NullBitmap)
132 wx.CallAfter(self.previewPanel.Refresh)
134 dc = wx.BufferedPaintDC(self.previewPanel)
135 dc.SetBackground(wx.Brush(wx.BLACK))
137 if self.previewImage is not None:
138 dc.DrawBitmap(self.previewImage, 0, 0)
139 if self.selectArea is not None:
140 dc.SetPen(wx.Pen(wx.Colour(255,0,0)))
141 dc.SetBrush(wx.Brush(None, style=wx.TRANSPARENT))
142 dc.DrawRectangle(self.selectArea[0], self.selectArea[1], self.selectArea[2] - self.selectArea[0] + 1, self.selectArea[3] - self.selectArea[1] + 1)
144 def OnSizePreview(self, e):
145 self.previewPanel.Refresh()
146 self.previewPanel.Update()
148 def OnEraseBackgroundPreview(self, e):
151 def OnMotion(self, e):
153 if not self.draggingArea:
154 self.draggingArea = True
155 self.selectArea = [e.GetX(), e.GetY(), e.GetX(), e.GetY()]
156 self.selectArea[2] = e.GetX()
157 self.selectArea[3] = e.GetY()
158 self.previewPanel.Refresh()
160 self.draggingArea = False
162 def OnImport(self, e):
163 if self.level is None or self.selectArea is None:
166 xMin = min(self.selectArea[0], self.selectArea[2]) + (self.playerPos[0] - 16) * 16
167 xMax = max(self.selectArea[0], self.selectArea[2]) + (self.playerPos[0] - 16) * 16
168 yMin = min(self.selectArea[1], self.selectArea[3]) + (self.playerPos[1] - 16) * 16
169 yMax = max(self.selectArea[1], self.selectArea[3]) + (self.playerPos[1] - 16) * 16
171 sx = (xMax - xMin + 1)
172 sy = (yMax - yMin + 1)
173 blocks = numpy.zeros((sx, sy, 256), numpy.int32)
175 cxMin = int(xMin / 16)
176 cxMax = int((xMax + 15) / 16)
177 cyMin = int(yMin / 16)
178 cyMax = int((yMax + 15) / 16)
180 for cx in xrange(cxMin, cxMax + 1):
181 for cy in xrange(cyMin, cyMax + 1):
182 chunk = self.level.getChunk(cx, cy)
183 for x in xrange(0, 16):
185 if xMin <= bx <= xMax:
186 for y in xrange(0, 16):
188 if yMin <= by <= yMax:
189 blocks[bx - xMin, by - yMin] = chunk.Blocks[x, y]
192 for x in xrange(0, sx):
193 for y in xrange(0, sy):
194 minZ = min(minZ, numpy.max(numpy.where(blocks[x, y] != 0)))
195 maxZ = max(maxZ, numpy.max(numpy.where(blocks[x, y] != 0)))
199 for x in xrange(0, sx):
200 for y in xrange(0, sy):
201 for z in xrange(minZ, maxZ + 1):
202 if self.isSolid[blocks[x, y, z]]:
203 if z == maxZ or not self.isSolid[blocks[x, y, z + 1]]:
205 if z == minZ or not self.isSolid[blocks[x, y, z - 1]]:
207 if x == 0 or not self.isSolid[blocks[x - 1, y, z]]:
209 if x == sx - 1 or not self.isSolid[blocks[x + 1, y, z]]:
211 if y == 0 or not self.isSolid[blocks[x, y - 1, z]]:
213 if y == sy - 1 or not self.isSolid[blocks[x, y + 1, z]]:
216 obj = mesh.printableObject(None)
218 m._prepareFaceCount(faceCount * 2)
219 for x in xrange(0, sx):
220 for y in xrange(0, sy):
221 for z in xrange(minZ, maxZ + 1):
222 if self.isSolid[blocks[x, y, z]]:
223 if z == maxZ or not self.isSolid[blocks[x, y, z + 1]]:
224 m._addFace(x, y, z+1, x+1, y, z+1, x, y+1, z+1)
226 m._addFace(x+1, y+1, z+1, x, y+1, z+1, x+1, y, z+1)
228 if z == minZ or not self.isSolid[blocks[x, y, z - 1]]:
229 m._addFace(x, y, z, x, y+1, z, x+1, y, z)
231 m._addFace(x+1, y+1, z, x+1, y, z, x, y+1, z)
233 if x == 0 or not self.isSolid[blocks[x - 1, y, z]]:
234 m._addFace(x, y, z, x, y, z+1, x, y+1, z)
236 m._addFace(x, y+1, z+1, x, y+1, z, x, y, z+1)
238 if x == sx - 1 or not self.isSolid[blocks[x + 1, y, z]]:
239 m._addFace(x+1, y, z, x+1, y+1, z, x+1, y, z+1)
241 m._addFace(x+1, y+1, z+1, x+1, y, z+1, x+1, y+1, z)
243 if y == 0 or not self.isSolid[blocks[x, y - 1, z]]:
244 m._addFace(x, y, z, x+1, y, z, x, y, z+1)
246 m._addFace(x+1, y, z+1, x, y, z+1, x+1, y, z)
248 if y == sy - 1 or not self.isSolid[blocks[x, y + 1, z]]:
249 m._addFace(x, y+1, z, x, y+1, z+1, x+1, y+1, z)
251 m._addFace(x+1, y+1, z+1, x+1, y+1, z, x, y+1, z+1)
253 obj._postProcessAfterLoad()
254 self.GetParent().scene._scene.add(obj)