1 from __future__ import absolute_import
9 from wx import glcanvas
11 OpenGL.ERROR_CHECKING = False
12 from OpenGL.GL import *
13 from OpenGL.GLU import *
15 from Cura.gui.util import opengl
16 from Cura.util import mesh
18 class superShape(object):
19 def __init__(self, a1, b1, m1, n11, n21, n31, a2, b2, m2, n12, n22, n32):
22 self._m1 = math.floor(m1)
35 for n in xrange(-cnt, cnt):
38 f1 = n * math.pi / cnt
40 r1 = math.pow((math.pow(abs(math.cos(m1*f1/4)/a1),n21) + math.pow(abs(math.sin(m1*f1/4)/b1), n31)), -(1/n11))
43 for m in xrange(0, cnt):
44 f2 = m * math.pi / ((cnt*2) - 2)
46 r2 = math.pow((math.pow(abs(math.cos(m2*f2/4)/a2),n22) + math.pow(abs(math.sin(m2*f2/4)/b2), n32)), -(1/n12))
50 x = r1 * math.cos(f1) * r2 * math.cos(f2)
51 y = r1 * math.sin(f1) * r2 * math.cos(f2)
56 self._obj = mesh.printableObject()
57 objMesh = self._obj._addMesh()
58 objMesh._prepareFaceCount(len(points) * (len(points[0]) - 1) * 2)
60 for n in xrange(-1, len(points) - 1):
63 for m in xrange(0, len(row1) - 1):
69 objMesh._addFace(p0[0], p0[1], p0[2], p2[0], p2[1], p2[2], p1[0], p1[1], p1[2])
70 objMesh._addFace(p1[0], p1[1], p1[2], p2[0], p2[1], p2[2], p3[0], p3[1], p3[2])
72 self._obj._postProcessAfterLoad()
75 size = self._obj.getSize()
76 if size[0] / size[2] > 10:
81 for m in self._obj._meshList:
83 m.vbo = opengl.GLVBO(m.vertexes, m.normal)
86 class superformulaEvolver(wx.Frame):
87 def __init__(self, parent):
88 super(superformulaEvolver, self).__init__(parent, title='Cura - Superformula')
90 self._t0 = time.time()
95 attribList = (glcanvas.WX_GL_RGBA, glcanvas.WX_GL_DOUBLEBUFFER, glcanvas.WX_GL_DEPTH_SIZE, 32, glcanvas.WX_GL_STENCIL_SIZE, 8)
96 self._glCanvas = glcanvas.GLCanvas(self, style=wx.WANTS_CHARS, attribList = attribList)
97 self._glCanvas.SetMinSize((800,600))
98 sizer.Add(self._glCanvas, 1, flag=wx.EXPAND)
99 self._context = glcanvas.GLContext(self._glCanvas)
101 wx.EVT_PAINT(self._glCanvas, self._OnPaint)
102 wx.EVT_SIZE(self._glCanvas, self._OnSize)
103 wx.EVT_ERASE_BACKGROUND(self._glCanvas, self._OnEraseBackground)
104 wx.EVT_IDLE(self, self._OnIdle)
106 wx.EVT_LEFT_DOWN(self._glCanvas, self._OnMouseDown)
108 self._shapes = [None] * 12
109 self._releaseList = []
115 def _OnMouseDown(self, e):
116 size = self._glCanvas.GetSize()
117 sel = e.GetX() / (size.GetWidth() / 4) + (size.GetHeight() - e.GetY()) / (size.GetHeight() / 3) * 4
118 shape = self._shapes[sel]
119 for n in xrange(0, len(self._shapes)):
122 for m in self._shapes[n]._obj._meshList:
123 if m.vbo is not None:
124 self._releaseList.append(m.vbo)
128 self._shapes[n] = superShape(
129 shape._a1 + random.uniform(-f, f) / 2.0,
130 shape._b1 + random.uniform(-f, f) / 2.0,
131 shape._m1 + random.uniform(-f, f) * 2.0,
132 shape._n11 + random.uniform(-f, f),
133 shape._n21 + random.uniform(-f, f),
134 shape._n31 + random.uniform(-f, f),
135 shape._a2 + random.uniform(-f, f) / 2.0,
136 shape._b2 + random.uniform(-f, f) / 2.0,
137 shape._m2 + random.uniform(-f, f),
138 shape._n12 + random.uniform(-f, f),
139 shape._n22 + random.uniform(-f, f),
140 shape._n32 + random.uniform(-f, f))
141 update = not self._shapes[n].isValid()
143 def _randomize(self):
144 for shape in self._shapes:
145 if shape is not None:
146 for m in shape._obj._meshList:
147 if m.vbo is not None:
148 self._releaseList.append(m.vbo)
149 for n in xrange(0, len(self._shapes)):
152 self._shapes[n] = superShape(
153 random.uniform(0.5, 5.0),
154 random.uniform(0.5, 5.0),
155 random.uniform(0.5, 20.0),
156 random.uniform(0.5, 10.0),
157 random.uniform(0.5, 10.0),
158 random.uniform(0.5, 10.0),
159 random.uniform(0.5, 5.0),
160 random.uniform(0.5, 5.0),
161 random.uniform(0.5, 10.0),
162 random.uniform(0.5, 10.0),
163 random.uniform(0.5, 10.0),
164 random.uniform(0.5, 10.0))
165 update = not self._shapes[n].isValid()
167 def _OnEraseBackground(self,event):
168 #Workaround for windows background redraw flicker.
171 def _OnSize(self, e):
174 def _OnIdle(self, e):
175 self._glCanvas.Refresh()
177 def _OnPaint(self, e):
178 dc = wx.PaintDC(self._glCanvas)
180 self._glCanvas.SetCurrent(self._context)
181 for obj in self._releaseList:
183 self._releaseList = []
185 size = self._glCanvas.GetSize()
186 glViewport(0, 0, size.GetWidth(), size.GetHeight())
189 glLightfv(GL_LIGHT0, GL_POSITION, [0.2, 0.2, 1.0, 0.0])
191 glDisable(GL_RESCALE_NORMAL)
192 glDisable(GL_LIGHTING)
194 glEnable(GL_DEPTH_TEST)
195 glDisable(GL_CULL_FACE)
197 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
199 glClearColor(0.0, 0.0, 0.0, 1.0)
203 glMatrixMode(GL_PROJECTION)
205 aspect = float(size.GetWidth()) / float(size.GetHeight())
206 gluPerspective(30.0, aspect, 1.0, 1000.0)
208 glMatrixMode(GL_MODELVIEW)
210 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
212 glTranslate(0,0,-2.0)
213 glRotate(-45 - math.sin(self._rotate/50.0) * 30, 1, 0, 0)
214 glRotate(self._rotate, 0, 0, 1)
215 self._rotate += (self._t0 - time.time()) * 20
216 self._t0 = time.time()
218 glEnable(GL_LIGHTING)
220 glLightfv(GL_LIGHT0, GL_POSITION, [0.2, 0.2, 1.0, 0.0])
221 glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.8,1.0,0.8,0])
222 glLightfv(GL_LIGHT0, GL_AMBIENT, [0.3,0.3,0.3,0])
224 glLightfv(GL_LIGHT1, GL_POSITION, [1.2, 0.2, 0.2, 0.0])
225 glLightfv(GL_LIGHT1, GL_DIFFUSE, [0.5,0.3,0.2,0])
226 glLightfv(GL_LIGHT1, GL_AMBIENT, [0.0,0.0,0.0,0])
228 for n in xrange(0, len(self._shapes)):
229 shape = self._shapes[n]
230 scale = 1.0/numpy.max(shape._obj.getSize())
232 glScalef(scale, scale, scale)
233 glEnable(GL_NORMALIZE)
234 glViewport(size.GetWidth() / 4 * (n % 4), size.GetHeight() / 3 * (n / 4), size.GetWidth() / 4, size.GetHeight() / 3)
239 self._glCanvas.SwapBuffers()
241 class superformulaWindow(wx.Frame):
242 def __init__(self, parent):
243 super(superformulaWindow, self).__init__(parent, title='Cura - Superformula')
245 self._t0 = time.time()
247 self.panel = wx.Panel(self, -1)
248 self.SetSizer(wx.BoxSizer())
249 self.GetSizer().Add(self.panel, 1, wx.EXPAND)
251 sizer = wx.GridBagSizer(2, 2)
253 sizer.Add(wx.StaticText(self.panel, -1, 'A1'), pos=(0,0))
254 self.sliderA1 = wx.Slider(self.panel, -1, 10, 5, 50, size=(150, -1))
255 sizer.Add(self.sliderA1, pos=(0,1))
256 sizer.Add(wx.StaticText(self.panel, -1, 'B1'), pos=(1,0))
257 self.sliderB1 = wx.Slider(self.panel, -1, 10, 5, 50, size=(150, -1))
258 sizer.Add(self.sliderB1, pos=(1,1))
259 sizer.Add(wx.StaticText(self.panel, -1, 'M1'), pos=(2,0))
260 self.sliderM1 = wx.Slider(self.panel, -1, 50, 5, 200, size=(150, -1))
261 sizer.Add(self.sliderM1, pos=(2,1))
262 sizer.Add(wx.StaticText(self.panel, -1, 'N11'), pos=(3,0))
263 self.sliderN11 = wx.Slider(self.panel, -1, 20, 5, 100, size=(150, -1))
264 sizer.Add(self.sliderN11, pos=(3,1))
265 sizer.Add(wx.StaticText(self.panel, -1, 'N21'), pos=(4,0))
266 self.sliderN21 = wx.Slider(self.panel, -1, 20, 5, 100, size=(150, -1))
267 sizer.Add(self.sliderN21, pos=(4,1))
268 sizer.Add(wx.StaticText(self.panel, -1, 'N31'), pos=(5,0))
269 self.sliderN31 = wx.Slider(self.panel, -1, 20, 5, 100, size=(150, -1))
270 sizer.Add(self.sliderN31, pos=(5,1))
272 sizer.Add(wx.StaticText(self.panel, -1, 'A2'), pos=(6,0))
273 self.sliderA2 = wx.Slider(self.panel, -1, 10, 5, 50, size=(150, -1))
274 sizer.Add(self.sliderA2, pos=(6,1))
275 sizer.Add(wx.StaticText(self.panel, -1, 'B2'), pos=(7,0))
276 self.sliderB2 = wx.Slider(self.panel, -1, 10, 5, 50, size=(150, -1))
277 sizer.Add(self.sliderB2, pos=(7,1))
278 sizer.Add(wx.StaticText(self.panel, -1, 'M2'), pos=(8,0))
279 self.sliderM2 = wx.Slider(self.panel, -1, 20, 5, 100, size=(150, -1))
280 sizer.Add(self.sliderM2, pos=(8,1))
281 sizer.Add(wx.StaticText(self.panel, -1, 'N12'), pos=(9,0))
282 self.sliderN12 = wx.Slider(self.panel, -1, 20, 5, 100, size=(150, -1))
283 sizer.Add(self.sliderN12, pos=(9,1))
284 sizer.Add(wx.StaticText(self.panel, -1, 'N22'), pos=(10,0))
285 self.sliderN22 = wx.Slider(self.panel, -1, 20, 5, 100, size=(150, -1))
286 sizer.Add(self.sliderN22, pos=(10,1))
287 sizer.Add(wx.StaticText(self.panel, -1, 'N32'), pos=(11,0))
288 self.sliderN32 = wx.Slider(self.panel, -1, 20, 5, 100, size=(150, -1))
289 sizer.Add(self.sliderN32, pos=(11,1))
291 self.randomButton = wx.Button(self.panel, -1, 'Randomize')
292 sizer.Add(self.randomButton, pos=(12,1))
293 self.addButton = wx.Button(self.panel, -1, 'Add to print')
294 sizer.Add(self.addButton, pos=(13,1))
296 attribList = (glcanvas.WX_GL_RGBA, glcanvas.WX_GL_DOUBLEBUFFER, glcanvas.WX_GL_DEPTH_SIZE, 32, glcanvas.WX_GL_STENCIL_SIZE, 8)
297 self._glCanvas = glcanvas.GLCanvas(self.panel, style=wx.WANTS_CHARS, attribList = attribList)
298 self._glCanvas.SetMinSize((800,600))
299 sizer.Add(self._glCanvas, pos=(0,2), span=(14,1), flag=wx.EXPAND)
300 self._context = glcanvas.GLContext(self._glCanvas)
302 sizer.AddGrowableRow(13)
303 sizer.AddGrowableCol(2)
304 self.panel.SetSizer(sizer)
308 wx.EVT_PAINT(self._glCanvas, self._OnPaint)
309 wx.EVT_SIZE(self._glCanvas, self._OnSize)
310 wx.EVT_ERASE_BACKGROUND(self._glCanvas, self._OnEraseBackground)
311 wx.EVT_IDLE(self, self._OnIdle)
313 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderA1)
314 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderB1)
315 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderM1)
316 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderN11)
317 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderN21)
318 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderN31)
320 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderA2)
321 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderB2)
322 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderM2)
323 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderN12)
324 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderN22)
325 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderN32)
327 self.Bind(wx.EVT_BUTTON, lambda e: self.onRandom(), self.randomButton)
328 self.Bind(wx.EVT_BUTTON, lambda e: self.onAdd(), self.addButton)
331 self._releaseList = []
338 self.sliderA1.SetValue(random.randint(self.sliderA1.GetMin(), self.sliderA1.GetMax()))
339 self.sliderB1.SetValue(random.randint(self.sliderB1.GetMin(), self.sliderB1.GetMax()))
340 self.sliderM1.SetValue(random.randint(self.sliderM1.GetMin(), self.sliderM1.GetMax()))
341 self.sliderN11.SetValue(random.randint(self.sliderN11.GetMin(), self.sliderN11.GetMax()))
342 self.sliderN21.SetValue(random.randint(self.sliderN21.GetMin(), self.sliderN21.GetMax()))
343 self.sliderN31.SetValue(random.randint(self.sliderN31.GetMin(), self.sliderN31.GetMax()))
344 self.sliderA2.SetValue(random.randint(self.sliderA2.GetMin(), self.sliderA2.GetMax()))
345 self.sliderB2.SetValue(random.randint(self.sliderB2.GetMin(), self.sliderB2.GetMax()))
346 self.sliderM2.SetValue(random.randint(self.sliderM2.GetMin(), self.sliderM2.GetMax()))
347 self.sliderN12.SetValue(random.randint(self.sliderN12.GetMin(), self.sliderN12.GetMax()))
348 self.sliderN22.SetValue(random.randint(self.sliderN22.GetMin(), self.sliderN22.GetMax()))
349 self.sliderN32.SetValue(random.randint(self.sliderN32.GetMin(), self.sliderN32.GetMax()))
351 if not self._shape.isValid():
355 scale = 1.0/numpy.max(self._shape._obj.getSize()) * 50
357 obj = mesh.printableObject()
359 m._prepareFaceCount(self._shape._obj._meshList[0].vertexCount / 3)
360 m.vertexes = self._shape._obj._meshList[0].vertexes * scale
361 m.vertexCount = self._shape._obj._meshList[0].vertexCount
362 obj._postProcessAfterLoad()
363 self.GetParent().scene._scene.add(obj)
365 def _updateShape(self):
366 if self._shape is not None:
367 for m in self._shape._obj._meshList:
368 if m.vbo is not None:
369 self._releaseList.append(m.vbo)
370 self._shape = superShape(
371 float(self.sliderA1.GetValue()) / 10.0,
372 float(self.sliderB1.GetValue()) / 10.0,
373 float(self.sliderM1.GetValue()) / 10.0,
375 float(self.sliderN11.GetValue()) / 10.0,
376 float(self.sliderN21.GetValue()) / 10.0,
377 float(self.sliderN31.GetValue()) / 10.0,
379 float(self.sliderA2.GetValue()) / 10.0,
380 float(self.sliderB2.GetValue()) / 10.0,
381 float(self.sliderM2.GetValue()) / 10.0,
383 float(self.sliderN12.GetValue()) / 10.0,
384 float(self.sliderN22.GetValue()) / 10.0,
385 float(self.sliderN32.GetValue()) / 10.0,
388 def _OnEraseBackground(self,event):
389 #Workaround for windows background redraw flicker.
392 def _OnSize(self, e):
395 def _OnIdle(self, e):
396 self._glCanvas.Refresh()
398 def _OnPaint(self, e):
399 dc = wx.PaintDC(self._glCanvas)
401 self._glCanvas.SetCurrent(self._context)
402 for obj in self._releaseList:
404 self._releaseList = []
406 size = self._glCanvas.GetSize()
407 glViewport(0, 0, size.GetWidth(), size.GetHeight())
410 glLightfv(GL_LIGHT0, GL_POSITION, [0.2, 0.2, 1.0, 0.0])
412 glDisable(GL_RESCALE_NORMAL)
413 glDisable(GL_LIGHTING)
415 glEnable(GL_DEPTH_TEST)
416 glDisable(GL_CULL_FACE)
418 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
420 glClearColor(0.0, 0.0, 0.0, 1.0)
424 glMatrixMode(GL_PROJECTION)
426 aspect = float(size.GetWidth()) / float(size.GetHeight())
427 gluPerspective(45.0, aspect, 1.0, 1000.0)
429 glMatrixMode(GL_MODELVIEW)
431 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
434 glRotate(-45 - math.sin(self._rotate/50.0) * 30, 1, 0, 0)
435 glRotate(self._rotate, 0, 0, 1)
436 self._rotate += (self._t0 - time.time()) * 20
437 self._t0 = time.time()
439 glEnable(GL_LIGHTING)
441 glLightfv(GL_LIGHT0, GL_POSITION, [0.2, 0.2, 1.0, 0.0])
442 glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.8,1.0,0.8,0])
443 glLightfv(GL_LIGHT0, GL_AMBIENT, [0.3,0.3,0.3,0])
445 glLightfv(GL_LIGHT1, GL_POSITION, [1.2, 0.2, 0.2, 0.0])
446 glLightfv(GL_LIGHT1, GL_DIFFUSE, [0.5,0.3,0.2,0])
447 glLightfv(GL_LIGHT1, GL_AMBIENT, [0.0,0.0,0.0,0])
449 scale = 1.0/numpy.max(self._shape._obj.getSize())
450 glScalef(scale, scale, scale)
451 glEnable(GL_NORMALIZE)
456 self._glCanvas.SwapBuffers()