1 __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
2 from __future__ import absolute_import
10 from wx import glcanvas
12 OpenGL.ERROR_CHECKING = False
13 from OpenGL.GL import *
14 from OpenGL.GLU import *
16 from Cura.gui.util import opengl
17 from Cura.util import mesh
19 class superShape(object):
20 def __init__(self, a1, b1, m1, n11, n21, n31, a2, b2, m2, n12, n22, n32):
23 self._m1 = math.floor(m1)
36 for n in xrange(-cnt, cnt):
39 f1 = n * math.pi / cnt
41 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))
44 for m in xrange(0, cnt):
45 f2 = m * math.pi / ((cnt*2) - 2)
47 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))
51 x = r1 * math.cos(f1) * r2 * math.cos(f2)
52 y = r1 * math.sin(f1) * r2 * math.cos(f2)
57 self._obj = mesh.printableObject()
58 objMesh = self._obj._addMesh()
59 objMesh._prepareFaceCount(len(points) * (len(points[0]) - 1) * 2)
61 for n in xrange(-1, len(points) - 1):
64 for m in xrange(0, len(row1) - 1):
70 objMesh._addFace(p0[0], p0[1], p0[2], p2[0], p2[1], p2[2], p1[0], p1[1], p1[2])
71 objMesh._addFace(p1[0], p1[1], p1[2], p2[0], p2[1], p2[2], p3[0], p3[1], p3[2])
73 self._obj._postProcessAfterLoad()
76 size = self._obj.getSize()
77 if size[0] / size[2] > 10:
82 for m in self._obj._meshList:
84 m.vbo = opengl.GLVBO(m.vertexes, m.normal)
87 class superformulaEvolver(wx.Frame):
88 def __init__(self, parent):
89 super(superformulaEvolver, self).__init__(parent, title='Cura - Superformula')
91 self._t0 = time.time()
96 attribList = (glcanvas.WX_GL_RGBA, glcanvas.WX_GL_DOUBLEBUFFER, glcanvas.WX_GL_DEPTH_SIZE, 32, glcanvas.WX_GL_STENCIL_SIZE, 8)
97 self._glCanvas = glcanvas.GLCanvas(self, style=wx.WANTS_CHARS, attribList = attribList)
98 self._glCanvas.SetMinSize((800,600))
99 sizer.Add(self._glCanvas, 1, flag=wx.EXPAND)
100 self._context = glcanvas.GLContext(self._glCanvas)
102 wx.EVT_PAINT(self._glCanvas, self._OnPaint)
103 wx.EVT_SIZE(self._glCanvas, self._OnSize)
104 wx.EVT_ERASE_BACKGROUND(self._glCanvas, self._OnEraseBackground)
105 wx.EVT_IDLE(self, self._OnIdle)
107 wx.EVT_LEFT_DOWN(self._glCanvas, self._OnMouseDown)
109 self._shapes = [None] * 12
110 self._releaseList = []
116 def _OnMouseDown(self, e):
117 size = self._glCanvas.GetSize()
118 sel = e.GetX() / (size.GetWidth() / 4) + (size.GetHeight() - e.GetY()) / (size.GetHeight() / 3) * 4
119 shape = self._shapes[sel]
120 for n in xrange(0, len(self._shapes)):
123 for m in self._shapes[n]._obj._meshList:
124 if m.vbo is not None:
125 self._releaseList.append(m.vbo)
129 self._shapes[n] = superShape(
130 shape._a1 + random.uniform(-f, f) / 2.0,
131 shape._b1 + random.uniform(-f, f) / 2.0,
132 shape._m1 + random.uniform(-f, f) * 2.0,
133 shape._n11 + random.uniform(-f, f),
134 shape._n21 + random.uniform(-f, f),
135 shape._n31 + random.uniform(-f, f),
136 shape._a2 + random.uniform(-f, f) / 2.0,
137 shape._b2 + random.uniform(-f, f) / 2.0,
138 shape._m2 + random.uniform(-f, f),
139 shape._n12 + random.uniform(-f, f),
140 shape._n22 + random.uniform(-f, f),
141 shape._n32 + random.uniform(-f, f))
142 update = not self._shapes[n].isValid()
144 def _randomize(self):
145 for shape in self._shapes:
146 if shape is not None:
147 for m in shape._obj._meshList:
148 if m.vbo is not None:
149 self._releaseList.append(m.vbo)
150 for n in xrange(0, len(self._shapes)):
153 self._shapes[n] = superShape(
154 random.uniform(0.5, 5.0),
155 random.uniform(0.5, 5.0),
156 random.uniform(0.5, 20.0),
157 random.uniform(0.5, 10.0),
158 random.uniform(0.5, 10.0),
159 random.uniform(0.5, 10.0),
160 random.uniform(0.5, 5.0),
161 random.uniform(0.5, 5.0),
162 random.uniform(0.5, 10.0),
163 random.uniform(0.5, 10.0),
164 random.uniform(0.5, 10.0),
165 random.uniform(0.5, 10.0))
166 update = not self._shapes[n].isValid()
168 def _OnEraseBackground(self,event):
169 #Workaround for windows background redraw flicker.
172 def _OnSize(self, e):
175 def _OnIdle(self, e):
176 self._glCanvas.Refresh()
178 def _OnPaint(self, e):
179 dc = wx.PaintDC(self._glCanvas)
181 self._glCanvas.SetCurrent(self._context)
182 for obj in self._releaseList:
184 self._releaseList = []
186 size = self._glCanvas.GetSize()
187 glViewport(0, 0, size.GetWidth(), size.GetHeight())
190 glLightfv(GL_LIGHT0, GL_POSITION, [0.2, 0.2, 1.0, 0.0])
192 glDisable(GL_RESCALE_NORMAL)
193 glDisable(GL_LIGHTING)
195 glEnable(GL_DEPTH_TEST)
196 glDisable(GL_CULL_FACE)
198 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
200 glClearColor(0.0, 0.0, 0.0, 1.0)
204 glMatrixMode(GL_PROJECTION)
206 aspect = float(size.GetWidth()) / float(size.GetHeight())
207 gluPerspective(30.0, aspect, 1.0, 1000.0)
209 glMatrixMode(GL_MODELVIEW)
211 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
213 glTranslate(0,0,-2.0)
214 glRotate(-45 - math.sin(self._rotate/50.0) * 30, 1, 0, 0)
215 glRotate(self._rotate, 0, 0, 1)
216 self._rotate += (self._t0 - time.time()) * 20
217 self._t0 = time.time()
219 glEnable(GL_LIGHTING)
221 glLightfv(GL_LIGHT0, GL_POSITION, [0.2, 0.2, 1.0, 0.0])
222 glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.8,1.0,0.8,0])
223 glLightfv(GL_LIGHT0, GL_AMBIENT, [0.3,0.3,0.3,0])
225 glLightfv(GL_LIGHT1, GL_POSITION, [1.2, 0.2, 0.2, 0.0])
226 glLightfv(GL_LIGHT1, GL_DIFFUSE, [0.5,0.3,0.2,0])
227 glLightfv(GL_LIGHT1, GL_AMBIENT, [0.0,0.0,0.0,0])
229 for n in xrange(0, len(self._shapes)):
230 shape = self._shapes[n]
231 scale = 1.0/numpy.max(shape._obj.getSize())
233 glScalef(scale, scale, scale)
234 glEnable(GL_NORMALIZE)
235 glViewport(size.GetWidth() / 4 * (n % 4), size.GetHeight() / 3 * (n / 4), size.GetWidth() / 4, size.GetHeight() / 3)
240 self._glCanvas.SwapBuffers()
242 class superformulaWindow(wx.Frame):
243 def __init__(self, parent):
244 super(superformulaWindow, self).__init__(parent, title='Cura - Superformula')
246 self._t0 = time.time()
248 self.panel = wx.Panel(self, -1)
249 self.SetSizer(wx.BoxSizer())
250 self.GetSizer().Add(self.panel, 1, wx.EXPAND)
252 sizer = wx.GridBagSizer(2, 2)
254 sizer.Add(wx.StaticText(self.panel, -1, 'A1'), pos=(0,0))
255 self.sliderA1 = wx.Slider(self.panel, -1, 10, 5, 50, size=(150, -1))
256 sizer.Add(self.sliderA1, pos=(0,1))
257 sizer.Add(wx.StaticText(self.panel, -1, 'B1'), pos=(1,0))
258 self.sliderB1 = wx.Slider(self.panel, -1, 10, 5, 50, size=(150, -1))
259 sizer.Add(self.sliderB1, pos=(1,1))
260 sizer.Add(wx.StaticText(self.panel, -1, 'M1'), pos=(2,0))
261 self.sliderM1 = wx.Slider(self.panel, -1, 50, 5, 200, size=(150, -1))
262 sizer.Add(self.sliderM1, pos=(2,1))
263 sizer.Add(wx.StaticText(self.panel, -1, 'N11'), pos=(3,0))
264 self.sliderN11 = wx.Slider(self.panel, -1, 20, 5, 100, size=(150, -1))
265 sizer.Add(self.sliderN11, pos=(3,1))
266 sizer.Add(wx.StaticText(self.panel, -1, 'N21'), pos=(4,0))
267 self.sliderN21 = wx.Slider(self.panel, -1, 20, 5, 100, size=(150, -1))
268 sizer.Add(self.sliderN21, pos=(4,1))
269 sizer.Add(wx.StaticText(self.panel, -1, 'N31'), pos=(5,0))
270 self.sliderN31 = wx.Slider(self.panel, -1, 20, 5, 100, size=(150, -1))
271 sizer.Add(self.sliderN31, pos=(5,1))
273 sizer.Add(wx.StaticText(self.panel, -1, 'A2'), pos=(6,0))
274 self.sliderA2 = wx.Slider(self.panel, -1, 10, 5, 50, size=(150, -1))
275 sizer.Add(self.sliderA2, pos=(6,1))
276 sizer.Add(wx.StaticText(self.panel, -1, 'B2'), pos=(7,0))
277 self.sliderB2 = wx.Slider(self.panel, -1, 10, 5, 50, size=(150, -1))
278 sizer.Add(self.sliderB2, pos=(7,1))
279 sizer.Add(wx.StaticText(self.panel, -1, 'M2'), pos=(8,0))
280 self.sliderM2 = wx.Slider(self.panel, -1, 20, 5, 100, size=(150, -1))
281 sizer.Add(self.sliderM2, pos=(8,1))
282 sizer.Add(wx.StaticText(self.panel, -1, 'N12'), pos=(9,0))
283 self.sliderN12 = wx.Slider(self.panel, -1, 20, 5, 100, size=(150, -1))
284 sizer.Add(self.sliderN12, pos=(9,1))
285 sizer.Add(wx.StaticText(self.panel, -1, 'N22'), pos=(10,0))
286 self.sliderN22 = wx.Slider(self.panel, -1, 20, 5, 100, size=(150, -1))
287 sizer.Add(self.sliderN22, pos=(10,1))
288 sizer.Add(wx.StaticText(self.panel, -1, 'N32'), pos=(11,0))
289 self.sliderN32 = wx.Slider(self.panel, -1, 20, 5, 100, size=(150, -1))
290 sizer.Add(self.sliderN32, pos=(11,1))
292 self.randomButton = wx.Button(self.panel, -1, 'Randomize')
293 sizer.Add(self.randomButton, pos=(12,1))
294 self.addButton = wx.Button(self.panel, -1, 'Add to print')
295 sizer.Add(self.addButton, pos=(13,1))
297 attribList = (glcanvas.WX_GL_RGBA, glcanvas.WX_GL_DOUBLEBUFFER, glcanvas.WX_GL_DEPTH_SIZE, 32, glcanvas.WX_GL_STENCIL_SIZE, 8)
298 self._glCanvas = glcanvas.GLCanvas(self.panel, style=wx.WANTS_CHARS, attribList = attribList)
299 self._glCanvas.SetMinSize((800,600))
300 sizer.Add(self._glCanvas, pos=(0,2), span=(14,1), flag=wx.EXPAND)
301 self._context = glcanvas.GLContext(self._glCanvas)
303 sizer.AddGrowableRow(13)
304 sizer.AddGrowableCol(2)
305 self.panel.SetSizer(sizer)
309 wx.EVT_PAINT(self._glCanvas, self._OnPaint)
310 wx.EVT_SIZE(self._glCanvas, self._OnSize)
311 wx.EVT_ERASE_BACKGROUND(self._glCanvas, self._OnEraseBackground)
312 wx.EVT_IDLE(self, self._OnIdle)
314 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderA1)
315 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderB1)
316 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderM1)
317 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderN11)
318 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderN21)
319 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderN31)
321 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderA2)
322 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderB2)
323 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderM2)
324 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderN12)
325 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderN22)
326 self.Bind(wx.EVT_SLIDER, lambda e: self._updateShape(), self.sliderN32)
328 self.Bind(wx.EVT_BUTTON, lambda e: self.onRandom(), self.randomButton)
329 self.Bind(wx.EVT_BUTTON, lambda e: self.onAdd(), self.addButton)
332 self._releaseList = []
339 self.sliderA1.SetValue(random.randint(self.sliderA1.GetMin(), self.sliderA1.GetMax()))
340 self.sliderB1.SetValue(random.randint(self.sliderB1.GetMin(), self.sliderB1.GetMax()))
341 self.sliderM1.SetValue(random.randint(self.sliderM1.GetMin(), self.sliderM1.GetMax()))
342 self.sliderN11.SetValue(random.randint(self.sliderN11.GetMin(), self.sliderN11.GetMax()))
343 self.sliderN21.SetValue(random.randint(self.sliderN21.GetMin(), self.sliderN21.GetMax()))
344 self.sliderN31.SetValue(random.randint(self.sliderN31.GetMin(), self.sliderN31.GetMax()))
345 self.sliderA2.SetValue(random.randint(self.sliderA2.GetMin(), self.sliderA2.GetMax()))
346 self.sliderB2.SetValue(random.randint(self.sliderB2.GetMin(), self.sliderB2.GetMax()))
347 self.sliderM2.SetValue(random.randint(self.sliderM2.GetMin(), self.sliderM2.GetMax()))
348 self.sliderN12.SetValue(random.randint(self.sliderN12.GetMin(), self.sliderN12.GetMax()))
349 self.sliderN22.SetValue(random.randint(self.sliderN22.GetMin(), self.sliderN22.GetMax()))
350 self.sliderN32.SetValue(random.randint(self.sliderN32.GetMin(), self.sliderN32.GetMax()))
352 if not self._shape.isValid():
356 scale = 1.0/numpy.max(self._shape._obj.getSize()) * 50
358 obj = mesh.printableObject()
360 m._prepareFaceCount(self._shape._obj._meshList[0].vertexCount / 3)
361 m.vertexes = self._shape._obj._meshList[0].vertexes * scale
362 m.vertexCount = self._shape._obj._meshList[0].vertexCount
363 obj._postProcessAfterLoad()
364 self.GetParent().scene._scene.add(obj)
365 self.GetParent().scene.sceneUpdated()
367 def _updateShape(self):
368 if self._shape is not None:
369 for m in self._shape._obj._meshList:
370 if m.vbo is not None:
371 self._releaseList.append(m.vbo)
372 self._shape = superShape(
373 float(self.sliderA1.GetValue()) / 10.0,
374 float(self.sliderB1.GetValue()) / 10.0,
375 float(self.sliderM1.GetValue()) / 10.0,
377 float(self.sliderN11.GetValue()) / 10.0,
378 float(self.sliderN21.GetValue()) / 10.0,
379 float(self.sliderN31.GetValue()) / 10.0,
381 float(self.sliderA2.GetValue()) / 10.0,
382 float(self.sliderB2.GetValue()) / 10.0,
383 float(self.sliderM2.GetValue()) / 10.0,
385 float(self.sliderN12.GetValue()) / 10.0,
386 float(self.sliderN22.GetValue()) / 10.0,
387 float(self.sliderN32.GetValue()) / 10.0,
390 def _OnEraseBackground(self,event):
391 #Workaround for windows background redraw flicker.
394 def _OnSize(self, e):
397 def _OnIdle(self, e):
398 self._glCanvas.Refresh()
400 def _OnPaint(self, e):
401 dc = wx.PaintDC(self._glCanvas)
403 self._glCanvas.SetCurrent(self._context)
404 for obj in self._releaseList:
406 self._releaseList = []
408 size = self._glCanvas.GetSize()
409 glViewport(0, 0, size.GetWidth(), size.GetHeight())
412 glLightfv(GL_LIGHT0, GL_POSITION, [0.2, 0.2, 1.0, 0.0])
414 glDisable(GL_RESCALE_NORMAL)
415 glDisable(GL_LIGHTING)
417 glEnable(GL_DEPTH_TEST)
418 glDisable(GL_CULL_FACE)
420 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
422 glClearColor(0.0, 0.0, 0.0, 1.0)
426 glMatrixMode(GL_PROJECTION)
428 aspect = float(size.GetWidth()) / float(size.GetHeight())
429 gluPerspective(45.0, aspect, 1.0, 1000.0)
431 glMatrixMode(GL_MODELVIEW)
433 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
436 glRotate(-45 - math.sin(self._rotate/50.0) * 30, 1, 0, 0)
437 glRotate(self._rotate, 0, 0, 1)
438 self._rotate += (self._t0 - time.time()) * 20
439 self._t0 = time.time()
441 glEnable(GL_LIGHTING)
443 glLightfv(GL_LIGHT0, GL_POSITION, [0.2, 0.2, 1.0, 0.0])
444 glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.8,1.0,0.8,0])
445 glLightfv(GL_LIGHT0, GL_AMBIENT, [0.3,0.3,0.3,0])
447 glLightfv(GL_LIGHT1, GL_POSITION, [1.2, 0.2, 0.2, 0.0])
448 glLightfv(GL_LIGHT1, GL_DIFFUSE, [0.5,0.3,0.2,0])
449 glLightfv(GL_LIGHT1, GL_AMBIENT, [0.0,0.0,0.0,0])
451 scale = 1.0/numpy.max(self._shape._obj.getSize())
452 glScalef(scale, scale, scale)
453 glEnable(GL_NORMALIZE)
458 self._glCanvas.SwapBuffers()