chiark / gitweb /
Updates to the SVG class (still unused), fixed some minor things.
authordaid <daid303@gmail.com>
Fri, 18 Oct 2013 08:06:25 +0000 (10:06 +0200)
committerdaid <daid303@gmail.com>
Fri, 18 Oct 2013 08:06:25 +0000 (10:06 +0200)
Cura/gui/sceneView.py
Cura/util/drawingLoader/drawing.py
Cura/util/mesh.py

index ead30869d5db2188824e5b36815c223f5fba5088..d9956f4ede5bd4e609eb777ca252224da4c5398a 100644 (file)
@@ -565,7 +565,7 @@ class SceneView(openglGui.glGuiPanel):
                        self.updateProfileToControls()
                        self.updateToolButtons()
                if zoom and obj is not None:
                        self.updateProfileToControls()
                        self.updateToolButtons()
                if zoom and obj is not None:
-                       newViewPos = numpy.array([obj.getPosition()[0], obj.getPosition()[1], obj.getMaximum()[2] / 2])
+                       newViewPos = numpy.array([obj.getPosition()[0], obj.getPosition()[1], obj.getSize()[2] / 2])
                        self._animView = openglGui.animation(self, self._viewTarget.copy(), newViewPos, 0.5)
                        newZoom = obj.getBoundaryCircle() * 6
                        if newZoom > numpy.max(self._machineSize) * 3:
                        self._animView = openglGui.animation(self, self._viewTarget.copy(), newViewPos, 0.5)
                        newZoom = obj.getBoundaryCircle() * 6
                        if newZoom > numpy.max(self._machineSize) * 3:
@@ -897,7 +897,7 @@ void main(void)
        gl_FragColor = vec4(gl_Color.xyz * light_amount, 1.0-intensity);
 }
                                """)
        gl_FragColor = vec4(gl_Color.xyz * light_amount, 1.0-intensity);
 }
                                """)
-                       if self._objectShader == None or not self._objectShader.isValid():
+                       if self._objectShader is None or not self._objectShader.isValid():
                                self._objectShader = opengl.GLFakeShader()
                                self._objectOverhangShader = opengl.GLFakeShader()
                                self._objectLoadShader = None
                                self._objectShader = opengl.GLFakeShader()
                                self._objectOverhangShader = opengl.GLFakeShader()
                                self._objectLoadShader = None
index 66dedf5829eaa1dbe20a2347233b04dd6c5991b7..509aeffa0a82e1b14cff9a32dbd30cdc5537a70c 100644 (file)
@@ -4,66 +4,28 @@ __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AG
 import math
 import numpy
 
 import math
 import numpy
 
-class Drawing(object):
-       def __init__(self):
-               self.paths = []
-
-       def addPath(self, x, y, matrix=numpy.matrix(numpy.identity(3, numpy.float64))):
-               p = Path(x, y, matrix)
-               self.paths.append(p)
-               return p
-
-       def _postProcessPaths(self):
-               for path in self.paths:
-                       if not path.isClosed():
-                               if abs(self._nodes[-1]['p'] - self._startPoint) < 0.001:
-                                       self._isClosed = True
-
-       def saveAsHtml(self, filename):
-               f = open(filename, "w")
-
-               posMax = complex(-1000, -1000)
-               posMin = complex( 1000,  1000)
-               for path in self.paths:
-                       points = path.getPoints()
-                       for p in points:
-                               if p.real > posMax.real:
-                                       posMax = complex(p.real, posMax.imag)
-                               if p.imag > posMax.imag:
-                                       posMax = complex(posMax.real, p.imag)
-                               if p.real < posMin.real:
-                                       posMin = complex(p.real, posMin.imag)
-                               if p.imag < posMin.imag:
-                                       posMin = complex(posMin.real, p.imag)
+class Node(object):
+       LINE = 0
+       ARC = 1
+       CURVE = 2
 
 
-               f.write("<!DOCTYPE html><html><body>\n")
-               f.write("<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" style='width:%dpx;height:%dpx'>\n" % ((posMax - posMin).real, (posMax - posMin).imag))
-               f.write("<g fill-rule='evenodd' style=\"fill: gray; stroke:black;stroke-width:2\">\n")
-               f.write("<path d=\"")
-               for path in self.paths:
-                       points = path.getPoints()
-                       f.write("M %f %f " % (points[0].real - posMin.real, points[0].imag - posMin.imag))
-                       for point in points[1:]:
-                               f.write("L %f %f " % (point.real - posMin.real, point.imag - posMin.imag))
-               f.write("\"/>")
-               f.write("</g>\n")
+       def __init__(self, type, position):
+               self.type = type
+               self.position = position
 
 
-               f.write("<g style=\"fill: none; stroke:red;stroke-width:1\">\n")
-               f.write("<path d=\"")
-               for path in self.paths:
-                       f.write(path.getSVGPath())
-               f.write("\"/>")
-               f.write("</g>\n")
+class LineNode(Node):
+       def __init__(self, position):
+               super(LineNode, self).__init__(Node.LINE, position)
 
 
-               f.write("</svg>\n")
-               f.write("</body></html>")
-               f.close()
+class ArcNode(Node):
+       def __init__(self, position, rotation, radius, large, sweep):
+               super(ArcNode, self).__init__(Node.ARC, position)
+               self.rotation = rotation
+               self.radius = radius
+               self.large = large
+               self.sweep = sweep
 
 class Path(object):
 
 class Path(object):
-       LINE = 0
-       ARC = 1
-       CURVE = 2
-
        def __init__(self, x, y, matrix=numpy.matrix(numpy.identity(3, numpy.float64))):
                self._matrix = matrix
                self._relMatrix = numpy.matrix([[matrix[0,0],matrix[1,0]],[matrix[0,1],matrix[1,1]]], numpy.float64)
        def __init__(self, x, y, matrix=numpy.matrix(numpy.identity(3, numpy.float64))):
                self._matrix = matrix
                self._relMatrix = numpy.matrix([[matrix[0,0],matrix[1,0]],[matrix[0,1],matrix[1,1]]], numpy.float64)
@@ -72,89 +34,97 @@ class Path(object):
                self._isClosed = False
 
        def addLineTo(self, x, y):
                self._isClosed = False
 
        def addLineTo(self, x, y):
-               self._nodes.append({'type': Path.LINE, 'p': self._m(complex(x, y))})
-
-       def addArcTo(self, x, y, rot, rx, ry, large, sweep):
-               self._nodes.append({
-                       'type': Path.ARC,
-                       'p': self._m(complex(x, y)),
-                       'rot': rot,
-                       'radius': self._r(complex(rx, ry)),
-                       'large': large,
-                       'sweep': sweep
-               })
+               self._nodes.append(LineNode(self._m(complex(x, y))))
+
+       def addArcTo(self, x, y, rotation, rx, ry, large, sweep):
+               self._nodes.append(ArcNode(self._m(complex(x, y)), rotation, self._r(complex(rx, ry)), large, sweep))
 
        def addCurveTo(self, x, y, cp1x, cp1y, cp2x, cp2y):
 
        def addCurveTo(self, x, y, cp1x, cp1y, cp2x, cp2y):
-               self._nodes.append({
-                       'type': Path.CURVE,
-                       'p': self._m(complex(x, y)),
-                       'cp1': self._m(complex(cp1x, cp1y)),
-                       'cp2': self._m(complex(cp2x, cp2y))
-               })
+               node = Node(Node.CURVE, self._m(complex(x, y)))
+               node.cp1 = self._m(complex(cp1x, cp1y))
+               node.cp2 = self._m(complex(cp2x, cp2y))
+               self._nodes.append(node)
 
        def isClosed(self):
                return self._isClosed
 
        def closePath(self):
 
        def isClosed(self):
                return self._isClosed
 
        def closePath(self):
-               self._nodes.append({'type': Path.LINE, 'p': self._startPoint})
+               if abs(self._nodes[-1].position - self._startPoint) > 0.01:
+                       self._nodes.append(Node(Node.LINE, self._startPoint))
                self._isClosed = True
 
                self._isClosed = True
 
-       def getPoints(self, accuracy = 1):
-               pointList = [self._startPoint]
+       def getArcInfo(self, node):
+               p1 = self._startPoint
+               if self._nodes[0] != node:
+                       p1 = self._nodes[self._nodes.index(node) - 1].position
+
+               p2 = node.position
+               rot = math.radians(node.rotation)
+               r = node.radius
+
+               #http://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpointToCenter
+               diff = (p1 - p2) / 2
+               p1alt = diff #TODO: apply rot
+               p2alt = -diff #TODO: apply rot
+               rx2 = r.real*r.real
+               ry2 = r.imag*r.imag
+               x1alt2 = p1alt.real*p1alt.real
+               y1alt2 = p1alt.imag*p1alt.imag
+
+               f = x1alt2 / rx2 + y1alt2 / ry2
+               if f >= 1.0:
+                       r *= math.sqrt(f+0.000001)
+                       rx2 = r.real*r.real
+                       ry2 = r.imag*r.imag
+
+               if rx2*y1alt2+ry2*x1alt2 == 0.0:
+                       f = 0
+               else:
+                       f = math.sqrt((rx2*ry2 - rx2*y1alt2 - ry2*x1alt2) / (rx2*y1alt2+ry2*x1alt2))
+               if node.large == node.sweep:
+                       f = -f
+               cAlt = f * complex(r.real*p1alt.imag/r.imag, -r.imag*p1alt.real/r.real)
+
+               c = cAlt + (p1 + p2) / 2 #TODO: apply rot
+
+               a1 = math.atan2((p1alt.imag - cAlt.imag) / r.imag, (p1alt.real - cAlt.real) / r.real)
+               a2 = math.atan2((p2alt.imag - cAlt.imag) / r.imag, (p2alt.real - cAlt.real) / r.real)
+
+               large = abs(a2 - a1) > math.pi
+               if large != node.large:
+                       if a1 < a2:
+                               a1 += math.pi * 2
+                       else:
+                               a2 += math.pi * 2
+
+               return c, a1, a2, r
+
+       def getPoints(self, accuracy = 1.0):
+               pointList = [(self._startPoint, -1)]
                p1 = self._startPoint
                p1 = self._startPoint
-               for p in self._nodes:
-                       if p['type'] == Path.LINE:
-                               p1 = p['p']
-                               pointList.append(p1)
-                       elif p['type'] == Path.ARC:
-                               p2 = p['p']
-                               rot = math.radians(p['rot'])
-                               r = p['radius']
-
-                               #http://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpointToCenter
-                               diff = (p1 - p2) / 2
-                               p1alt = diff #TODO: apply rot
-                               p2alt = -diff #TODO: apply rot
-                               rx2 = r.real*r.real
-                               ry2 = r.imag*r.imag
-                               x1alt2 = p1alt.real*p1alt.real
-                               y1alt2 = p1alt.imag*p1alt.imag
-
-                               f = x1alt2 / rx2 + y1alt2 / ry2
-                               if f >= 1.0:
-                                       r *= math.sqrt(f+0.000001)
-                                       rx2 = r.real*r.real
-                                       ry2 = r.imag*r.imag
-
-                               f = math.sqrt((rx2*ry2 - rx2*y1alt2 - ry2*x1alt2) / (rx2*y1alt2+ry2*x1alt2))
-                               if p['large'] == p['sweep']:
-                                       f = -f
-                               cAlt = f * complex(r.real*p1alt.imag/r.imag, -r.imag*p1alt.real/r.real)
-
-                               c = cAlt + (p1 + p2) / 2 #TODO: apply rot
-
-                               a1 = math.atan2((p1alt.imag - cAlt.imag) / r.imag, (p1alt.real - cAlt.real) / r.real)
-                               a2 = math.atan2((p2alt.imag - cAlt.imag) / r.imag, (p2alt.real - cAlt.real) / r.real)
-
-                               large = abs(a2 - a1) > math.pi
-                               if large != p['large']:
-                                       if a1 < a2:
-                                               a1 += math.pi * 2
-                                       else:
-                                               a2 += math.pi * 2
+               idx = -1
+               for node in self._nodes:
+                       idx += 1
+                       if node.type == Node.LINE:
+                               p1 = node.position
+                               pointList.append((p1, idx))
+                       elif node.type == Node.ARC:
+                               p2 = node.position
+                               c, a1, a2, r = self.getArcInfo(node)
 
                                pCenter = c + complex(math.cos(a1 + 0.5*(a2-a1)) * r.real, math.sin(a1 + 0.5*(a2-a1)) * r.imag)
                                dist = abs(pCenter - p1) + abs(pCenter - p2)
                                segments = int(dist / accuracy) + 1
                                for n in xrange(1, segments):
 
                                pCenter = c + complex(math.cos(a1 + 0.5*(a2-a1)) * r.real, math.sin(a1 + 0.5*(a2-a1)) * r.imag)
                                dist = abs(pCenter - p1) + abs(pCenter - p2)
                                segments = int(dist / accuracy) + 1
                                for n in xrange(1, segments):
-                                       pointList.append(c + complex(math.cos(a1 + n*(a2-a1)/segments) * r.real, math.sin(a1 + n*(a2-a1)/segments) * r.imag))
+                                       p = c + complex(math.cos(a1 + n*(a2-a1)/segments) * r.real, math.sin(a1 + n*(a2-a1)/segments) * r.imag)
+                                       pointList.append((p, idx))
 
 
-                               pointList.append(p2)
+                               pointList.append((p2, idx))
                                p1 = p2
                                p1 = p2
-                       elif p['type'] == Path.CURVE:
-                               p2 = p['p']
-                               cp1 = p['cp1']
-                               cp2 = p['cp2']
+                       elif node.type == Node.CURVE:
+                               p2 = node.position
+                               cp1 = node.cp1
+                               cp2 = node.cp2
 
                                pCenter = p1*0.5*0.5*0.5 + cp1*3.0*0.5*0.5*0.5 + cp2*3.0*0.5*0.5*0.5 + p2*0.5*0.5*0.5
                                dist = abs(pCenter - p1) + abs(pCenter - p2)
 
                                pCenter = p1*0.5*0.5*0.5 + cp1*3.0*0.5*0.5*0.5 + cp2*3.0*0.5*0.5*0.5 + p2*0.5*0.5*0.5
                                dist = abs(pCenter - p1) + abs(pCenter - p2)
@@ -163,10 +133,10 @@ class Path(object):
                                        f = n / float(segments)
                                        g = 1.0-f
                                        point = p1*g*g*g + cp1*3.0*g*g*f + cp2*3.0*g*f*f + p2*f*f*f
                                        f = n / float(segments)
                                        g = 1.0-f
                                        point = p1*g*g*g + cp1*3.0*g*g*f + cp2*3.0*g*f*f + p2*f*f*f
-                                       pointList.append(point)
+                                       pointList.append((point, idx))
 
 
-                               pointList.append(p2)
-                               p1 = p['p']
+                               pointList.append((p2, idx))
+                               p1 = p2
 
                return pointList
 
 
                return pointList
 
@@ -174,22 +144,33 @@ class Path(object):
        def getSVGPath(self):
                p0 = self._startPoint
                ret = 'M %f %f ' % (p0.real, p0.imag)
        def getSVGPath(self):
                p0 = self._startPoint
                ret = 'M %f %f ' % (p0.real, p0.imag)
-               for p in self._nodes:
-                       if p['type'] == Path.LINE:
-                               p0 = p['p']
+               for node in self._nodes:
+                       if node.type == Node.LINE:
+                               p0 = node.position
                                ret += 'L %f %f' % (p0.real, p0.imag)
                                ret += 'L %f %f' % (p0.real, p0.imag)
-                       elif p['type'] == Path.ARC:
-                               p0 = p['p']
-                               radius = p['radius']
-                               ret += 'A %f %f 0 %d %d %f %f' % (radius.real, radius.imag, 1 if p['large'] else 0, 1 if p['sweep'] else 0, p0.real, p0.imag)
-                       elif p['type'] == Path.CURVE:
-                               p0 = p['p']
-                               cp1 = p['cp1']
-                               cp2 = p['cp2']
+                       elif node.type == Node.ARC:
+                               p0 = node.position
+                               radius = node.radius
+                               ret += 'A %f %f 0 %d %d %f %f' % (radius.real, radius.imag, 1 if node.large else 0, 1 if node.sweep else 0, p0.real, p0.imag)
+                       elif node.type == Node.CURVE:
+                               p0 = node.position
+                               cp1 = node.cp1
+                               cp2 = node.cp2
                                ret += 'C %f %f %f %f %f %f' % (cp1.real, cp1.imag, cp2.real, cp2.imag, p0.real, p0.imag)
 
                return ret
 
                                ret += 'C %f %f %f %f %f %f' % (cp1.real, cp1.imag, cp2.real, cp2.imag, p0.real, p0.imag)
 
                return ret
 
+       def getPathString(self):
+               ret = '%f %f' % (self._startPoint.real, self._startPoint.imag)
+               for node in self._nodes:
+                       if node.type == Node.LINE:
+                               ret += '|L %f %f' % (node.position.real, node.position.imag)
+                       elif node.type == Node.ARC:
+                               ret += '|A %f %f %f %f %d %d' % (node.position.real, node.position.imag, node.radius.real, node.radius.imag, 1 if node.large else 0, 1 if node.sweep else 0)
+                       elif node.type == Node.CURVE:
+                               ret += '|C %f %f %f %f %f %f' % (node.position.real, node.position.imag, node.cp1.real, node.cp1.imag, node.cp2.real, node.cp2.imag)
+               return ret
+
        def _m(self, p):
                tmp = numpy.matrix([p.real, p.imag, 1], numpy.float64) * self._matrix
                return complex(tmp[0,0], tmp[0,1])
        def _m(self, p):
                tmp = numpy.matrix([p.real, p.imag, 1], numpy.float64) * self._matrix
                return complex(tmp[0,0], tmp[0,1])
@@ -197,3 +178,83 @@ class Path(object):
        def _r(self, p):
                tmp = numpy.matrix([p.real, p.imag], numpy.float64) * self._relMatrix
                return complex(tmp[0,0], tmp[0,1])
        def _r(self, p):
                tmp = numpy.matrix([p.real, p.imag], numpy.float64) * self._relMatrix
                return complex(tmp[0,0], tmp[0,1])
+
+class Drawing(object):
+       def __init__(self):
+               self.paths = []
+
+       def addPath(self, x, y, matrix=numpy.matrix(numpy.identity(3, numpy.float64))):
+               p = Path(x, y, matrix)
+               self.paths.append(p)
+               return p
+
+       def _postProcessPaths(self):
+               for path in self.paths:
+                       if not path.isClosed():
+                               if abs(path._nodes[-1].position - path._startPoint) < 0.001:
+                                       path._isClosed = True
+                       if path.isClosed() and len(path._nodes) == 2 and path._nodes[0].type == Node.ARC and path._nodes[1].type == Node.ARC:
+                               if abs(path._nodes[0].radius - path._nodes[1].radius) < 0.001:
+                                       pass
+                                       #path._nodes = []
+
+       def dumpToFile(self, file):
+               file.write("%d\n" % (len(self.paths)))
+               for path in self.paths:
+                       file.write("%s\n" % (path.getPathString()))
+
+       def readFromFile(self, file):
+               self.paths = []
+               pathCount = int(file.readline())
+               for n in xrange(0, pathCount):
+                       line = map(str.split, file.readline().strip().split('|'))
+                       path = Path(float(line[0][0]), float(line[0][1]))
+                       for item in line[1:]:
+                               if item[0] == 'L':
+                                       path.addLineTo(float(item[1]), float(item[2]))
+                               elif item[0] == 'A':
+                                       path.addArcTo(float(item[1]), float(item[2]), 0, float(item[3]), float(item[4]), int(item[5]) != 0, int(item[6]) != 0)
+                               elif item[0] == 'C':
+                                       path.addCurveTo(float(item[1]), float(item[2]), float(item[3]), float(item[4]), float(item[5]), float(item[6]))
+                       self.paths.append(path)
+               self._postProcessPaths()
+
+       def saveAsHtml(self, filename):
+               f = open(filename, "w")
+
+               posMax = complex(-1000, -1000)
+               posMin = complex( 1000,  1000)
+               for path in self.paths:
+                       points = path.getPoints()
+                       for p in points:
+                               if p.real > posMax.real:
+                                       posMax = complex(p.real, posMax.imag)
+                               if p.imag > posMax.imag:
+                                       posMax = complex(posMax.real, p.imag)
+                               if p.real < posMin.real:
+                                       posMin = complex(p.real, posMin.imag)
+                               if p.imag < posMin.imag:
+                                       posMin = complex(posMin.real, p.imag)
+
+               f.write("<!DOCTYPE html><html><body>\n")
+               f.write("<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" style='width:%dpx;height:%dpx'>\n" % ((posMax - posMin).real, (posMax - posMin).imag))
+               f.write("<g fill-rule='evenodd' style=\"fill: gray; stroke:black;stroke-width:2\">\n")
+               f.write("<path d=\"")
+               for path in self.paths:
+                       points = path.getPoints()
+                       f.write("M %f %f " % (points[0].real - posMin.real, points[0].imag - posMin.imag))
+                       for point in points[1:]:
+                               f.write("L %f %f " % (point.real - posMin.real, point.imag - posMin.imag))
+               f.write("\"/>")
+               f.write("</g>\n")
+
+               f.write("<g style=\"fill: none; stroke:red;stroke-width:1\">\n")
+               f.write("<path d=\"")
+               for path in self.paths:
+                       f.write(path.getSVGPath())
+               f.write("\"/>")
+               f.write("</g>\n")
+
+               f.write("</svg>\n")
+               f.write("</body></html>")
+               f.close()
index eacc7076c3984363bf4d6eced1f74402c640cd6a..c4594dbde12f69faa5fa575acb4fa91accfcba2e 100644 (file)
@@ -31,7 +31,7 @@ class printableObject(object):
                ret = printableObject(self._originFilename)
                ret._matrix = self._matrix.copy()
                ret._transformedMin = self._transformedMin.copy()
                ret = printableObject(self._originFilename)
                ret._matrix = self._matrix.copy()
                ret._transformedMin = self._transformedMin.copy()
-               ret._transformedMax = self._transformedMin.copy()
+               ret._transformedMax = self._transformedMax.copy()
                ret._transformedSize = self._transformedSize.copy()
                ret._boundaryCircleSize = self._boundaryCircleSize
                ret._drawOffset = self._drawOffset.copy()
                ret._transformedSize = self._transformedSize.copy()
                ret._boundaryCircleSize = self._boundaryCircleSize
                ret._drawOffset = self._drawOffset.copy()