コード例 #1
0
ファイル: svg_reader.py プロジェクト: clothbot/DotSkeinforge
class SVGReader:
	"An svg carving."
	def __init__( self ):
		"Add empty lists."
		self.bridgeRotation = None
		self.rotatedLoopLayers = []
		self.stopProcessing = False
		self.z = 0.0

	def flipDirectLayer(self, rotatedLoopLayer):
		"Flip the y coordinate of the layer and direct the loops."
		for loop in rotatedLoopLayer.loops:
			for pointIndex, point in enumerate(loop):
				loop[pointIndex] = complex(point.real, -point.imag)
		rotatedLoopLayer.loops = trianglemesh.getLoopsInOrderOfArea(trianglemesh.compareAreaDescending, rotatedLoopLayer.loops)
		for loopIndex, loop in enumerate(rotatedLoopLayer.loops):
			isInsideLoops = euclidean.isPointInsideLoopsZone(rotatedLoopLayer.loops[: loopIndex], euclidean.getLeftPoint(loop))
			booleansolid.directLoop((not isInsideLoops), loop)

	def getRotatedLoopLayer( self ):
		"Return the rotated loop layer."
		if self.z != None:
			rotatedLoopLayer = euclidean.RotatedLoopLayer( self.z )
			self.rotatedLoopLayers.append( rotatedLoopLayer )
			rotatedLoopLayer.rotation = self.bridgeRotation
			self.z = None
		return self.rotatedLoopLayers[ - 1 ]

	def parseSVG( self, fileName, svgText ):
		"Parse SVG text and store the layers."
		self.fileName = fileName
		self.xmlParser = XMLSimpleReader(fileName, None, svgText)
		self.sliceDictionary = svg_writer.getSliceDictionary( self.xmlParser.getRoot() )
		self.yAxisPointingUpward = euclidean.getBooleanFromDictionaryDefault(False, self.sliceDictionary, 'yAxisPointingUpward')
		self.processXMLElement( self.xmlParser.getRoot() )
		if not self.yAxisPointingUpward:
			for rotatedLoopLayer in self.rotatedLoopLayers:
				self.flipDirectLayer(rotatedLoopLayer)

	def processXMLElement( self, xmlElement ):
		"Process the xml element."
		if self.stopProcessing:
			return
		lowerClassName = xmlElement.className.lower()
		global globalProcessSVGElementDictionary
		if lowerClassName in globalProcessSVGElementDictionary:
			try:
				globalProcessSVGElementDictionary[ lowerClassName ]( self, xmlElement )
			except:
				print('Warning, in processXMLElement in svg_reader, could not process:')
				print(xmlElement)
				traceback.print_exc( file = sys.stdout )
		for child in xmlElement.children:
			self.processXMLElement( child )
コード例 #2
0
class FontReader:
	"Class to read a font in the fonts folder."
	def __init__(self, fontFamily):
		"Initialize."
		self.fontFamily = fontFamily
		self.glyphDictionary = {}
		self.glyphXMLElementDictionary = {}
		self.missingGlyph = None
		fileName = os.path.join(getFontsDirectoryPath(), fontFamily + '.svg')
		self.xmlParser = XMLSimpleReader(fileName, None, archive.getFileText(fileName))
		self.fontXMLElement = self.xmlParser.getRoot().getFirstChildWithClassName('defs').getFirstChildWithClassName('font')
		self.fontFaceXMLElement = self.fontXMLElement.getFirstChildWithClassName('font-face')
		self.unitsPerEM = float(self.fontFaceXMLElement.attributeDictionary['units-per-em'])
		glyphXMLElements = self.fontXMLElement.getChildrenWithClassName('glyph')
		for glyphXMLElement in glyphXMLElements:
			self.glyphXMLElementDictionary[glyphXMLElement.attributeDictionary['unicode']] = glyphXMLElement

	def getGlyph(self, character, yAxisPointingUpward):
		"Get the glyph for the character."
		if character not in self.glyphXMLElementDictionary:
			if self.missingGlyph == None:
				missingGlyphXMLElement = self.fontXMLElement.getFirstChildWithClassName('missing-glyph')
				self.missingGlyph = Glyph(self.unitsPerEM, missingGlyphXMLElement, yAxisPointingUpward)
			return self.missingGlyph
		if character not in self.glyphDictionary:
			self.glyphDictionary[character] = Glyph(self.unitsPerEM, self.glyphXMLElementDictionary[character], yAxisPointingUpward)
		return self.glyphDictionary[character]
コード例 #3
0
class FontReader:
	"Class to read a font in the fonts folder."
	def __init__(self, fontFamily):
		"Initialize."
		self.fontFamily = fontFamily
		self.glyphDictionary = {}
		self.glyphXMLElementDictionary = {}
		self.missingGlyph = None
		fileName = os.path.join(getFontsDirectoryPath(), fontFamily + '.svg')
		self.xmlParser = XMLSimpleReader(fileName, None, gcodec.getFileText(fileName))
		self.fontXMLElement = self.xmlParser.getRoot().getFirstChildWithClassName('defs').getFirstChildWithClassName('font')
		self.fontFaceXMLElement = self.fontXMLElement.getFirstChildWithClassName('font-face')
		self.unitsPerEM = float(self.fontFaceXMLElement.attributeDictionary['units-per-em'])
		glyphXMLElements = self.fontXMLElement.getChildrenWithClassName('glyph')
		for glyphXMLElement in glyphXMLElements:
			self.glyphXMLElementDictionary[glyphXMLElement.attributeDictionary['unicode']] = glyphXMLElement

	def getGlyph(self, character, yAxisPointingUpward):
		"Get the glyph for the character."
		if character not in self.glyphXMLElementDictionary:
			if self.missingGlyph == None:
				missingGlyphXMLElement = self.fontXMLElement.getFirstChildWithClassName('missing-glyph')
				self.missingGlyph = Glyph(self.unitsPerEM, missingGlyphXMLElement, yAxisPointingUpward)
			return self.missingGlyph
		if character not in self.glyphDictionary:
			self.glyphDictionary[character] = Glyph(self.unitsPerEM, self.glyphXMLElementDictionary[character], yAxisPointingUpward)
		return self.glyphDictionary[character]
コード例 #4
0
	def parseSVG(self, fileName, svgText):
		"Parse SVG text and store the layers."
		self.fileName = fileName
		xmlParser = XMLSimpleReader(fileName, None, svgText)
		self.root = xmlParser.getRoot()
		if self.root == None:
			print('Warning, root was None in parseSVG in SVGReader, so nothing will be done for:')
			print(fileName)
			return
		self.parseSVGByXMLElement(self.root)
コード例 #5
0
ファイル: xml.py プロジェクト: clothbot/DotSkeinforge
def getCarving( fileName = ''):
	"Get the carving for the xml file."
	xmlText = gcodec.getFileText( fileName )
	if xmlText == '':
		return None
	xmlParser = XMLSimpleReader( fileName, None, xmlText )
	lowerClassName = xmlParser.getRoot().className.lower()
	pluginModule = gcodec.getModuleWithDirectoryPath( getPluginsDirectoryPath(), lowerClassName )
	if pluginModule == None:
		return None
	return pluginModule.getCarvingFromParser( xmlParser )
コード例 #6
0
ファイル: xml.py プロジェクト: aliensr85/skeinforgeGit
def getCarving(fileName=''):
	"Get the carving for the xml file."
	xmlText = archive.getFileText(fileName)
	if xmlText == '':
		return None
	xmlParser = XMLSimpleReader( fileName, None, xmlText )
	lowerClassName = xmlParser.getRoot().className.lower()
	pluginModule = archive.getModuleWithDirectoryPath( getPluginsDirectoryPath(), lowerClassName )
	if pluginModule == None:
		return None
	return pluginModule.getCarvingFromParser( xmlParser )
コード例 #7
0
ファイル: svg_reader.py プロジェクト: CNCBASHER/skeinforge-1
 def parseSVG(self, fileName, svgText):
     "Parse SVG text and store the layers."
     self.fileName = fileName
     xmlParser = XMLSimpleReader(fileName, None, svgText)
     self.root = xmlParser.getRoot()
     if self.root == None:
         print(
             'Warning, root was None in parseSVG in SVGReader, so nothing will be done for:'
         )
         print(fileName)
         return
     self.parseSVGByXMLElement(self.root)
コード例 #8
0
	def getCraftedGcode(self, fileName, repository, svgText):
		"Parse svgText and store the bottom svgText."
		xmlParser = XMLSimpleReader(fileName, None, svgText)
		root = xmlParser.getRoot()
		sliceElements = getSliceElements(root)
		sliceDictionary = svg_writer.getSliceDictionary(root)
		decimalPlacesCarried = int(sliceDictionary['decimalPlacesCarried'])
		layerThickness = float(sliceDictionary['layerThickness'])
		procedures = sliceDictionary['procedureDone'].split(',')
		procedures.append('bottom')
		sliceDictionary['procedureDone'] = ','.join(procedures)
		zMinimum = 987654321.0
		for sliceElement in sliceElements:
			zMinimum = min(getSliceElementZ(sliceElement), zMinimum)
		deltaZ = repository.altitude.value + 0.5 * layerThickness - zMinimum
		for sliceElementIndex, sliceElement in enumerate(sliceElements):
			z = getSliceElementZ(sliceElement) + deltaZ
			setSliceElementZ(decimalPlacesCarried, sliceElement, sliceElementIndex, z)
		output = cStringIO.StringIO()
		root.addXML(0, output)
		return output.getvalue()
コード例 #9
0
class SVGWriter:
    'A base class to get an svg skein from a carving.'

    def __init__(self,
                 addLayerTemplateToSVG,
                 cornerMaximum,
                 cornerMinimum,
                 decimalPlacesCarried,
                 layerThickness,
                 perimeterWidth=None):
        'Initialize.'
        self.addLayerTemplateToSVG = addLayerTemplateToSVG
        self.cornerMaximum = cornerMaximum
        self.cornerMinimum = cornerMinimum
        self.decimalPlacesCarried = decimalPlacesCarried
        self.layerThickness = layerThickness
        self.perimeterWidth = perimeterWidth
        self.textHeight = 22.5
        self.unitScale = 3.7

    def addLayerBegin(self, layerIndex, rotatedLoopLayer):
        'Add the start lines for the layer.'
        zRounded = self.getRounded(rotatedLoopLayer.z)
        self.graphicsCopy = self.graphicsXMLElement.getCopy(
            zRounded, self.graphicsXMLElement.parentNode)
        if self.addLayerTemplateToSVG:
            translateXRounded = self.getRounded(self.controlBoxWidth +
                                                self.margin + self.margin)
            layerTranslateY = self.marginTop
            layerTranslateY += layerIndex * self.textHeight + (
                layerIndex + 1) * (self.extent.y * self.unitScale +
                                   self.margin)
            translateYRounded = self.getRounded(layerTranslateY)
            self.graphicsCopy.attributeDictionary[
                'transform'] = 'translate(%s, %s)' % (translateXRounded,
                                                      translateYRounded)
            layerString = 'Layer %s, z:%s' % (layerIndex, zRounded)
            self.graphicsCopy.getFirstChildByLocalName(
                'text').text = layerString
            self.graphicsCopy.attributeDictionary[
                'inkscape:groupmode'] = 'layer'
            self.graphicsCopy.attributeDictionary[
                'inkscape:label'] = layerString
        self.pathXMLElement = self.graphicsCopy.getFirstChildByLocalName(
            'path')
        self.pathDictionary = self.pathXMLElement.attributeDictionary

    def addOriginalAsComment(self, xmlElement):
        'Add original xmlElement as a comment.'
        if xmlElement == None:
            return
        if xmlElement.localName == 'comment':
            xmlElement.setParentAddToChildNodes(self.svgElement)
            return
        commentElement = xml_simple_reader.XMLElement()
        commentElement.localName = 'comment'
        xmlElementOutput = cStringIO.StringIO()
        xmlElement.addXML(0, xmlElementOutput)
        textLines = archive.getTextLines(xmlElementOutput.getvalue())
        commentElementOutput = cStringIO.StringIO()
        isComment = False
        for textLine in textLines:
            lineStripped = textLine.strip()
            if lineStripped[:len('<!--')] == '<!--':
                isComment = True
            if not isComment:
                if len(textLine) > 0:
                    commentElementOutput.write(textLine + '\n')
            if '-->' in lineStripped:
                isComment = False
        commentElement.text = '%s%s-->\n' % (globalOriginalTextString,
                                             commentElementOutput.getvalue())
        commentElement.setParentAddToChildNodes(self.svgElement)

    def addRotatedLoopLayerToOutput(self, layerIndex, rotatedLoopLayer):
        'Add rotated boundary layer to the output.'
        self.addLayerBegin(layerIndex, rotatedLoopLayer)
        if rotatedLoopLayer.rotation != None:
            self.graphicsCopy.attributeDictionary['bridgeRotation'] = str(
                rotatedLoopLayer.rotation)
        if self.addLayerTemplateToSVG:
            self.pathDictionary['transform'] = self.getTransformString()
        else:
            del self.pathDictionary['transform']
        self.pathDictionary['d'] = self.getSVGStringForLoops(
            rotatedLoopLayer.loops)

    def addRotatedLoopLayersToOutput(self, rotatedLoopLayers):
        'Add rotated boundary layers to the output.'
        for rotatedLoopLayerIndex, rotatedLoopLayer in enumerate(
                rotatedLoopLayers):
            self.addRotatedLoopLayerToOutput(rotatedLoopLayerIndex,
                                             rotatedLoopLayer)

    def getReplacedSVGTemplate(self,
                               fileName,
                               procedureName,
                               rotatedLoopLayers,
                               xmlElement=None):
        'Get the lines of text from the layer_template.svg file.'
        self.extent = self.cornerMaximum - self.cornerMinimum
        svgTemplateText = archive.getFileText(
            archive.getTemplatesPath('layer_template.svg'))
        self.xmlParser = XMLSimpleReader(fileName, None, svgTemplateText)
        self.svgElement = self.xmlParser.getRoot()
        svgElementDictionary = self.svgElement.attributeDictionary
        self.sliceDictionary = getSliceDictionary(self.svgElement)
        self.controlBoxHeight = float(self.sliceDictionary['controlBoxHeight'])
        self.controlBoxWidth = float(self.sliceDictionary['controlBoxWidth'])
        self.margin = float(self.sliceDictionary['margin'])
        self.marginTop = float(self.sliceDictionary['marginTop'])
        self.textHeight = float(self.sliceDictionary['textHeight'])
        self.unitScale = float(self.sliceDictionary['unitScale'])
        svgMinWidth = float(self.sliceDictionary['svgMinWidth'])
        self.controlBoxHeightMargin = self.controlBoxHeight + self.marginTop
        if not self.addLayerTemplateToSVG:
            self.svgElement.getXMLElementByID(
                'layerTextTemplate').removeFromIDNameParent()
            del self.svgElement.getXMLElementByID(
                'sliceElementTemplate').attributeDictionary['transform']
        self.graphicsXMLElement = self.svgElement.getXMLElementByID(
            'sliceElementTemplate')
        self.graphicsXMLElement.attributeDictionary['id'] = 'z:'
        self.addRotatedLoopLayersToOutput(rotatedLoopLayers)
        self.setMetadataNoscriptElement('layerThickness', 'Layer Thickness: ',
                                        self.layerThickness)
        self.setMetadataNoscriptElement('maxX', 'X: ', self.cornerMaximum.x)
        self.setMetadataNoscriptElement('minX', 'X: ', self.cornerMinimum.x)
        self.setMetadataNoscriptElement('maxY', 'Y: ', self.cornerMaximum.y)
        self.setMetadataNoscriptElement('minY', 'Y: ', self.cornerMinimum.y)
        self.setMetadataNoscriptElement('maxZ', 'Z: ', self.cornerMaximum.z)
        self.setMetadataNoscriptElement('minZ', 'Z: ', self.cornerMinimum.z)
        self.textHeight = float(self.sliceDictionary['textHeight'])
        controlTop = len(rotatedLoopLayers) * (
            self.margin + self.extent.y * self.unitScale +
            self.textHeight) + self.marginTop + self.textHeight
        self.svgElement.getFirstChildByLocalName(
            'title').text = os.path.basename(fileName) + ' - Slice Layers'
        svgElementDictionary['height'] = '%spx' % self.getRounded(
            max(controlTop, self.controlBoxHeightMargin))
        width = max(self.extent.x * self.unitScale, svgMinWidth)
        svgElementDictionary['width'] = '%spx' % self.getRounded(width)
        self.sliceDictionary['decimalPlacesCarried'] = str(
            self.decimalPlacesCarried)
        if self.perimeterWidth != None:
            self.sliceDictionary['perimeterWidth'] = self.getRounded(
                self.perimeterWidth)
        self.sliceDictionary['yAxisPointingUpward'] = 'true'
        self.sliceDictionary['procedureName'] = procedureName
        self.setDimensionTexts('dimX', 'X: ' + self.getRounded(self.extent.x))
        self.setDimensionTexts('dimY', 'Y: ' + self.getRounded(self.extent.y))
        self.setDimensionTexts('dimZ', 'Z: ' + self.getRounded(self.extent.z))
        self.setTexts('numberOfLayers',
                      'Number of Layers: %s' % len(rotatedLoopLayers))
        volume = 0.0
        for rotatedLoopLayer in rotatedLoopLayers:
            volume += euclidean.getAreaLoops(rotatedLoopLayer.loops)
        volume *= 0.001
        self.setTexts('volume', 'Volume: %s cm3' % self.getRounded(volume))
        if not self.addLayerTemplateToSVG:
            self.svgElement.getFirstChildByLocalName(
                'script').removeFromIDNameParent()
            self.svgElement.getXMLElementByID(
                'isoControlBox').removeFromIDNameParent()
            self.svgElement.getXMLElementByID(
                'layerControlBox').removeFromIDNameParent()
            self.svgElement.getXMLElementByID(
                'scrollControlBox').removeFromIDNameParent()
        self.graphicsXMLElement.removeFromIDNameParent()
        self.addOriginalAsComment(xmlElement)
        output = cStringIO.StringIO()
        output.write(self.xmlParser.beforeRoot)
        self.svgElement.addXML(0, output)
        return xml_simple_writer.getBeforeRootOutput(self.xmlParser)

    def getRounded(self, number):
        'Get number rounded to the number of carried decimal places as a string.'
        return euclidean.getRoundedToPlacesString(self.decimalPlacesCarried,
                                                  number)

    def getRoundedComplexString(self, point):
        'Get the rounded complex string.'
        return self.getRounded(point.real) + ' ' + self.getRounded(point.imag)

    def getSVGStringForLoop(self, loop):
        'Get the svg loop string.'
        if len(loop) < 1:
            return ''
        return self.getSVGStringForPath(loop) + ' z'

    def getSVGStringForLoops(self, loops):
        'Get the svg loops string.'
        loopString = ''
        if len(loops) > 0:
            loopString += self.getSVGStringForLoop(loops[0])
        for loop in loops[1:]:
            loopString += ' ' + self.getSVGStringForLoop(loop)
        return loopString

    def getSVGStringForPath(self, path):
        'Get the svg path string.'
        svgLoopString = ''
        for point in path:
            stringBeginning = 'M '
            if len(svgLoopString) > 0:
                stringBeginning = ' L '
            svgLoopString += stringBeginning + self.getRoundedComplexString(
                point)
        return svgLoopString

    def setMetadataNoscriptElement(self, key, prefix, value):
        'Set the metadata value and the text.'
        valueString = self.getRounded(value)
        self.sliceDictionary[key] = valueString
        self.setDimensionTexts(key, prefix + valueString)

    def setDimensionTexts(self, key, valueString):
        'Set the texts to the valueString followed by mm.'
        self.setTexts(key, valueString + ' mm')

    def setTexts(self, key, valueString):
        'Set the texts to the valueString.'
        self.svgElement.getXMLElementByID(key + 'Iso').text = valueString
        self.svgElement.getXMLElementByID(key + 'Layer').text = valueString
        self.svgElement.getXMLElementByID(key + 'Scroll').text = valueString

    def getTransformString(self):
        'Get the svg transform string.'
        cornerMinimumXString = self.getRounded(-self.cornerMinimum.x)
        cornerMinimumYString = self.getRounded(-self.cornerMinimum.y)
        return 'scale(%s, %s) translate(%s, %s)' % (
            self.unitScale, -self.unitScale, cornerMinimumXString,
            cornerMinimumYString)
コード例 #10
0
ファイル: svg_writer.py プロジェクト: CNCBASHER/skeinforge-1
class SVGWriter:
	'A base class to get an svg skein from a carving.'
	def __init__(self,
			addLayerTemplateToSVG,
			cornerMaximum,
			cornerMinimum,
			decimalPlacesCarried,
			layerThickness,
			perimeterWidth=None):
		'Initialize.'
		self.addLayerTemplateToSVG = addLayerTemplateToSVG
		self.cornerMaximum = cornerMaximum
		self.cornerMinimum = cornerMinimum
		self.decimalPlacesCarried = decimalPlacesCarried
		self.layerThickness = layerThickness
		self.perimeterWidth = perimeterWidth
		self.textHeight = 22.5
		self.unitScale = 3.7

	def addLayerBegin(self, layerIndex, rotatedLoopLayer):
		'Add the start lines for the layer.'
		zRounded = self.getRounded(rotatedLoopLayer.z)
		self.graphicsCopy = self.graphicsXMLElement.getCopy(zRounded, self.graphicsXMLElement.parent)
		if self.addLayerTemplateToSVG:
			translateXRounded = self.getRounded(self.controlBoxWidth + self.margin + self.margin)
			layerTranslateY = self.marginTop
			layerTranslateY += layerIndex * self.textHeight + (layerIndex + 1) * (self.extent.y * self.unitScale + self.margin)
			translateYRounded = self.getRounded(layerTranslateY)
			self.graphicsCopy.attributeDictionary['transform'] = 'translate(%s, %s)' % (translateXRounded, translateYRounded)
			layerString = 'Layer %s, z:%s' % (layerIndex, zRounded)
			self.graphicsCopy.getFirstChildWithClassName('text').text = layerString
			self.graphicsCopy.attributeDictionary['inkscape:groupmode'] = 'layer'
			self.graphicsCopy.attributeDictionary['inkscape:label'] = layerString
		self.pathXMLElement = self.graphicsCopy.getFirstChildWithClassName('path')
		self.pathDictionary = self.pathXMLElement.attributeDictionary

	def addOriginalAsComment(self, xmlElement):
		'Add original xmlElement as a comment.'
		if xmlElement == None:
			return
		if xmlElement.className == 'comment':
			xmlElement.setParentAddToChildren(self.svgElement)
			return
		commentElement = xml_simple_reader.XMLElement()
		commentElement.className = 'comment'
		xmlElementOutput = cStringIO.StringIO()
		xmlElement.addXML(0, xmlElementOutput)
		textLines = archive.getTextLines(xmlElementOutput.getvalue())
		commentElementOutput = cStringIO.StringIO()
		isComment = False
		for textLine in textLines:
			lineStripped = textLine.strip()
			if lineStripped[: len('<!--')] == '<!--':
				isComment = True
			if not isComment:
				if len(textLine) > 0:
					commentElementOutput.write(textLine + '\n')
			if '-->' in lineStripped:
				isComment = False
		commentElement.text = '%s%s-->\n' % (globalOriginalTextString, commentElementOutput.getvalue())
		commentElement.setParentAddToChildren(self.svgElement)

	def addRotatedLoopLayerToOutput(self, layerIndex, rotatedLoopLayer):
		'Add rotated boundary layer to the output.'
		self.addLayerBegin(layerIndex, rotatedLoopLayer)
		if rotatedLoopLayer.rotation != None:
			self.graphicsCopy.attributeDictionary['bridgeRotation'] = str(rotatedLoopLayer.rotation)
		if self.addLayerTemplateToSVG:
			self.pathDictionary['transform'] = self.getTransformString()
		else:
			del self.pathDictionary['transform']
		self.pathDictionary['d'] = self.getSVGStringForLoops(rotatedLoopLayer.loops)

	def addRotatedLoopLayersToOutput(self, rotatedLoopLayers):
		'Add rotated boundary layers to the output.'
		for rotatedLoopLayerIndex, rotatedLoopLayer in enumerate(rotatedLoopLayers):
			self.addRotatedLoopLayerToOutput(rotatedLoopLayerIndex, rotatedLoopLayer)

	def getReplacedSVGTemplate(self, fileName, procedureName, rotatedLoopLayers, xmlElement=None):
		'Get the lines of text from the layer_template.svg file.'
		self.extent = self.cornerMaximum - self.cornerMinimum
		svgTemplateText = archive.getFileText(archive.getTemplatesPath('layer_template.svg'))
		self.xmlParser = XMLSimpleReader( fileName, None, svgTemplateText )
		self.svgElement = self.xmlParser.getRoot()
		svgElementDictionary = self.svgElement.attributeDictionary
		self.sliceDictionary = getSliceDictionary(self.svgElement)
		self.controlBoxHeight = float(self.sliceDictionary['controlBoxHeight'])
		self.controlBoxWidth = float(self.sliceDictionary['controlBoxWidth'])
		self.margin = float(self.sliceDictionary['margin'])
		self.marginTop = float(self.sliceDictionary['marginTop'])
		self.textHeight = float(self.sliceDictionary['textHeight'])
		self.unitScale = float(self.sliceDictionary['unitScale'])
		svgMinWidth = float(self.sliceDictionary['svgMinWidth'])
		self.controlBoxHeightMargin = self.controlBoxHeight + self.marginTop
		if not self.addLayerTemplateToSVG:
			self.svgElement.getXMLElementByID('layerTextTemplate').removeFromIDNameParent()
			del self.svgElement.getXMLElementByID('sliceElementTemplate').attributeDictionary['transform']
		self.graphicsXMLElement = self.svgElement.getXMLElementByID('sliceElementTemplate')
		self.graphicsXMLElement.attributeDictionary['id'] = 'z:'
		self.addRotatedLoopLayersToOutput(rotatedLoopLayers)
		self.setMetadataNoscriptElement('layerThickness', 'Layer Thickness: ', self.layerThickness)
		self.setMetadataNoscriptElement('maxX', 'X: ', self.cornerMaximum.x)
		self.setMetadataNoscriptElement('minX', 'X: ', self.cornerMinimum.x)
		self.setMetadataNoscriptElement('maxY', 'Y: ', self.cornerMaximum.y)
		self.setMetadataNoscriptElement('minY', 'Y: ', self.cornerMinimum.y)
		self.setMetadataNoscriptElement('maxZ', 'Z: ', self.cornerMaximum.z)
		self.setMetadataNoscriptElement('minZ', 'Z: ', self.cornerMinimum.z)
		self.textHeight = float( self.sliceDictionary['textHeight'] )
		controlTop = len(rotatedLoopLayers) * (self.margin + self.extent.y * self.unitScale + self.textHeight) + self.marginTop + self.textHeight
		self.svgElement.getFirstChildWithClassName('title').text = os.path.basename(fileName) + ' - Slice Layers'
		svgElementDictionary['height'] = '%spx' % self.getRounded(max(controlTop, self.controlBoxHeightMargin))
		width = max(self.extent.x * self.unitScale, svgMinWidth)
		svgElementDictionary['width'] = '%spx' % self.getRounded( width )
		self.sliceDictionary['decimalPlacesCarried'] = str( self.decimalPlacesCarried )
		if self.perimeterWidth != None:
			self.sliceDictionary['perimeterWidth'] = self.getRounded( self.perimeterWidth )
		self.sliceDictionary['yAxisPointingUpward'] = 'true'
		self.sliceDictionary['procedureName'] = procedureName
		self.setDimensionTexts('dimX', 'X: ' + self.getRounded(self.extent.x))
		self.setDimensionTexts('dimY', 'Y: ' + self.getRounded(self.extent.y))
		self.setDimensionTexts('dimZ', 'Z: ' + self.getRounded(self.extent.z))
		self.setTexts('numberOfLayers', 'Number of Layers: %s' % len(rotatedLoopLayers))
		volume = 0.0
		for rotatedLoopLayer in rotatedLoopLayers:
			volume += euclidean.getAreaLoops(rotatedLoopLayer.loops)
		volume *= 0.001
		self.setTexts('volume', 'Volume: %s cm3' % self.getRounded(volume))
		if not self.addLayerTemplateToSVG:
			self.svgElement.getFirstChildWithClassName('script').removeFromIDNameParent()
			self.svgElement.getXMLElementByID('isoControlBox').removeFromIDNameParent()
			self.svgElement.getXMLElementByID('layerControlBox').removeFromIDNameParent()
			self.svgElement.getXMLElementByID('scrollControlBox').removeFromIDNameParent()
		self.graphicsXMLElement.removeFromIDNameParent()
		self.addOriginalAsComment(xmlElement)
		output = cStringIO.StringIO()
		output.write(self.xmlParser.beforeRoot)
		self.svgElement.addXML(0, output)
		return xml_simple_writer.getBeforeRootOutput(self.xmlParser)

	def getRounded(self, number):
		'Get number rounded to the number of carried decimal places as a string.'
		return euclidean.getRoundedToPlacesString(self.decimalPlacesCarried, number)

	def getRoundedComplexString(self, point):
		'Get the rounded complex string.'
		return self.getRounded( point.real ) + ' ' + self.getRounded( point.imag )

	def getSVGStringForLoop( self, loop ):
		'Get the svg loop string.'
		if len(loop) < 1:
			return ''
		return self.getSVGStringForPath(loop) + ' z'

	def getSVGStringForLoops( self, loops ):
		'Get the svg loops string.'
		loopString = ''
		if len(loops) > 0:
			loopString += self.getSVGStringForLoop( loops[0] )
		for loop in loops[1 :]:
			loopString += ' ' + self.getSVGStringForLoop(loop)
		return loopString

	def getSVGStringForPath( self, path ):
		'Get the svg path string.'
		svgLoopString = ''
		for point in path:
			stringBeginning = 'M '
			if len( svgLoopString ) > 0:
				stringBeginning = ' L '
			svgLoopString += stringBeginning + self.getRoundedComplexString(point)
		return svgLoopString

	def setMetadataNoscriptElement(self, key, prefix, value):
		'Set the metadata value and the text.'
		valueString = self.getRounded(value)
		self.sliceDictionary[key] = valueString
		self.setDimensionTexts(key, prefix + valueString)

	def setDimensionTexts(self, key, valueString):
		'Set the texts to the valueString followed by mm.'
		self.setTexts(key, valueString + ' mm')

	def setTexts(self, key, valueString):
		'Set the texts to the valueString.'
		self.svgElement.getXMLElementByID(key + 'Iso').text = valueString
		self.svgElement.getXMLElementByID(key + 'Layer').text = valueString
		self.svgElement.getXMLElementByID(key + 'Scroll').text = valueString

	def getTransformString(self):
		'Get the svg transform string.'
		cornerMinimumXString = self.getRounded(-self.cornerMinimum.x)
		cornerMinimumYString = self.getRounded(-self.cornerMinimum.y)
		return 'scale(%s, %s) translate(%s, %s)' % (self.unitScale, - self.unitScale, cornerMinimumXString, cornerMinimumYString)
コード例 #11
0
ファイル: svg_reader.py プロジェクト: folksjos/RepG
	def parseSVG(self, fileName, svgText):
		"Parse SVG text and store the layers."
		self.fileName = fileName
		xmlParser = XMLSimpleReader(fileName, None, svgText)
		self.parseSVGByXMLElement(xmlParser.getRoot())
コード例 #12
0
	def parseSVG(self, fileName, svgText):
		"Parse SVG text and store the layers."
		self.fileName = fileName
		xmlParser = XMLSimpleReader(fileName, None, svgText)
		self.parseSVGByXMLElement(xmlParser.getRoot())
コード例 #13
0
ファイル: svg_writer.py プロジェクト: mccoyn/SkeinFactory
class SVGWriter:
	"A base class to get an svg skein from a carving."
	def __init__(self, addLayerTemplateToSVG, carving, decimalPlacesCarried, perimeterWidth = None):
		self.addLayerTemplateToSVG = addLayerTemplateToSVG
		self.carving = carving
		self.decimalPlacesCarried = decimalPlacesCarried
		self.margin = 20
		self.perimeterWidth = perimeterWidth
		self.textHeight = 22.5
		self.unitScale = 3.7

	def addLayerBegin(self, layerIndex, rotatedBoundaryLayer):
		"Add the start lines for the layer."
		zRounded = self.getRounded( rotatedBoundaryLayer.z )
		self.graphicsCopy = self.graphicsXMLElement.getCopy(zRounded, self.graphicsXMLElement.parent)
		if self.addLayerTemplateToSVG:
			marginRounded = self.getRounded(self.margin)
			layerTranslateY = layerIndex * self.textHeight + (layerIndex + 1) * (self.extent.y * self.unitScale + self.margin)
			translateYRounded = self.getRounded(layerTranslateY)
			self.graphicsCopy.attributeDictionary['transform'] = 'translate(%s, %s)' % (marginRounded, translateYRounded)
			self.graphicsCopy.getFirstChildWithClassName('text').text = 'Layer %s, z:%s' % (layerIndex, zRounded)
		self.pathXMLElement = self.graphicsCopy.getFirstChildWithClassName('path')
		self.pathDictionary = self.pathXMLElement.attributeDictionary

	def addRotatedLoopLayerToOutput( self, layerIndex, rotatedBoundaryLayer ):
		"Add rotated boundary layer to the output."
		self.addLayerBegin( layerIndex, rotatedBoundaryLayer )
		if rotatedBoundaryLayer.rotation != None:
			self.graphicsCopy.attributeDictionary['bridgeRotation'] = str( rotatedBoundaryLayer.rotation )
		if self.addLayerTemplateToSVG:
			self.pathDictionary['transform'] = self.getTransformString()
		else:
			del self.pathDictionary['transform']
		self.pathDictionary['d'] = self.getSVGStringForLoops(rotatedBoundaryLayer.loops)

	def addRotatedLoopLayersToOutput( self, rotatedBoundaryLayers ):
		"Add rotated boundary layers to the output."
		for rotatedBoundaryLayerIndex, rotatedBoundaryLayer in enumerate( rotatedBoundaryLayers ):
			self.addRotatedLoopLayerToOutput( rotatedBoundaryLayerIndex, rotatedBoundaryLayer )

	def getReplacedSVGTemplate(self, fileName, procedureName, rotatedBoundaryLayers, xmlElement):
		"Get the lines of text from the layer_template.svg file."
#		( layers.length + 1 ) * (margin + sliceDimY * unitScale + txtHeight) + margin + txtHeight + margin + 110
		cornerMaximum = self.carving.getCarveCornerMaximum()
		cornerMinimum = self.carving.getCarveCornerMinimum()
		self.extent = cornerMaximum - cornerMinimum
		svgTemplateText = gcodec.getFileTextInFileDirectory( __file__, os.path.join('templates', 'layer_template.svg') )
		self.xmlParser = XMLSimpleReader( fileName, None, svgTemplateText )
		self.svgElement = self.xmlParser.getRoot()
		if not self.addLayerTemplateToSVG:
			self.svgElement.getXMLElementByID('layerTextTemplate').removeFromIDNameParent()
			del self.svgElement.getXMLElementByID('sliceElementTemplate').attributeDictionary['transform']
		svgElementDictionary = self.svgElement.attributeDictionary
		self.graphicsXMLElement = self.svgElement.getXMLElementByID('sliceElementTemplate')
		self.graphicsXMLElement.attributeDictionary['id'] = 'z:'
		self.addRotatedLoopLayersToOutput( rotatedBoundaryLayers )
		self.sliceDictionary = getSliceDictionary( self.svgElement )
		self.setMetadataNoscriptElement('layerThickness', self.carving.getCarveLayerThickness() )
		self.setMetadataNoscriptElement('maxX', cornerMaximum.x )
		self.setMetadataNoscriptElement('minX', cornerMinimum.x )
		self.setMetadataNoscriptElement('maxY', cornerMaximum.y )
		self.setMetadataNoscriptElement('minY', cornerMinimum.y )
		self.setMetadataNoscriptElement('maxZ', cornerMaximum.z )
		self.setMetadataNoscriptElement('minZ', cornerMinimum.z )
		self.margin = float( self.sliceDictionary['margin'] )
		self.textHeight = float( self.sliceDictionary['textHeight'] )
		javascriptControlBoxWidth = float( self.sliceDictionary['javascriptControlBoxWidth'] )
		noJavascriptControlBoxHeight = float( self.sliceDictionary['noJavascriptControlBoxHeight'] )
		controlTop = len( rotatedBoundaryLayers ) * ( self.margin + self.extent.y * self.unitScale + self.textHeight ) + 2.0 * self.margin + self.textHeight
		self.svgElement.getFirstChildWithClassName('title').text = os.path.basename(fileName) + ' - Slice Layers'
		svgElementDictionary['height'] = '%spx' % self.getRounded( controlTop + noJavascriptControlBoxHeight + self.margin )
#		width = margin + (sliceDimX * unitScale) + margin;
		width = 2.0 * self.margin + max( self.extent.x * self.unitScale, javascriptControlBoxWidth )
		svgElementDictionary['width'] = '%spx' % self.getRounded( width )
		self.sliceDictionary['decimalPlacesCarried'] = str( self.decimalPlacesCarried )
		if self.perimeterWidth != None:
			self.sliceDictionary['perimeterWidth'] = self.getRounded( self.perimeterWidth )
		self.sliceDictionary['yAxisPointingUpward'] = 'true'
		self.sliceDictionary['procedureDone'] = procedureName
		noJavascriptDictionary = self.svgElement.getXMLElementByID('noJavascriptControls').attributeDictionary
		noJavascriptDictionary['transform'] = 'translate(%s, %s)' % ( self.getRounded(self.margin), self.getRounded( controlTop ) )
		self.svgElement.getXMLElementByID('dimXNoJavascript').text = self.getRounded( self.extent.x )
		self.svgElement.getXMLElementByID('dimYNoJavascript').text = self.getRounded( self.extent.y )
		self.svgElement.getXMLElementByID('dimZNoJavascript').text = self.getRounded( self.extent.z )
		if not self.addLayerTemplateToSVG:
			self.svgElement.getFirstChildWithClassName('script').removeFromIDNameParent()
			self.svgElement.getXMLElementByID('beginningOfControlSection').removeFromIDNameParent()
			self.svgElement.getXMLElementByID('noJavascriptControls').removeFromIDNameParent()
		self.graphicsXMLElement.removeFromIDNameParent()
		if xmlElement != None:
			xmlElement.setParentAddToChildren(self.svgElement)
		output = cStringIO.StringIO()
		output.write( self.xmlParser.beforeRoot )
		self.svgElement.addXML( 0, output )
		return output.getvalue()

	def getRounded(self, number):
		"Get number rounded to the number of carried decimal places as a string."
		return euclidean.getRoundedToDecimalPlacesString(self.decimalPlacesCarried, number)

	def getRoundedComplexString(self, point):
		"Get the rounded complex string."
		return self.getRounded( point.real ) + ' ' + self.getRounded( point.imag )

	def getSVGStringForLoop( self, loop ):
		"Get the svg loop string."
		if len(loop) < 1:
			return ''
		return self.getSVGStringForPath(loop) + ' z'

	def getSVGStringForLoops( self, loops ):
		"Get the svg loops string."
		loopString = ''
		if len(loops) > 0:
			loopString += self.getSVGStringForLoop( loops[0] )
		for loop in loops[1 :]:
			loopString += ' ' + self.getSVGStringForLoop(loop)
		return loopString

	def getSVGStringForPath( self, path ):
		"Get the svg path string."
		svgLoopString = ''
		for point in path:
			stringBeginning = 'M '
			if len( svgLoopString ) > 0:
				stringBeginning = ' L '
			svgLoopString += stringBeginning + self.getRoundedComplexString(point)
		return svgLoopString

	def getTransformString(self):
		"Get the svg transform string."
		cornerMinimumXString = self.getRounded( - self.carving.getCarveCornerMinimum().x )
		cornerMinimumYString = self.getRounded( - self.carving.getCarveCornerMinimum().y )
		return 'scale(%s, %s) translate(%s, %s)' % ( self.unitScale, - self.unitScale, cornerMinimumXString, cornerMinimumYString )

	def setMetadataNoscriptElement( self, prefix, value ):
		"Set the metadata value and the NoJavascript text."
		valueString = self.getRounded(value)
		self.sliceDictionary[ prefix ] = valueString
		self.svgElement.getXMLElementByID( prefix + 'NoJavascript').text = valueString
コード例 #14
0
class SVGWriter:
    "A base class to get an svg skein from a carving."

    def __init__(self,
                 addLayerTemplateToSVG,
                 carving,
                 decimalPlacesCarried,
                 perimeterWidth=None):
        self.addLayerTemplateToSVG = addLayerTemplateToSVG
        self.carving = carving
        self.decimalPlacesCarried = decimalPlacesCarried
        self.margin = 20
        self.perimeterWidth = perimeterWidth
        self.textHeight = 22.5
        self.unitScale = 3.7

    def addLayerBegin(self, layerIndex, rotatedBoundaryLayer):
        "Add the start lines for the layer."
        zRounded = self.getRounded(rotatedBoundaryLayer.z)
        self.graphicsCopy = self.graphicsXMLElement.getCopy(
            zRounded, self.graphicsXMLElement.parent)
        if self.addLayerTemplateToSVG:
            marginRounded = self.getRounded(self.margin)
            layerTranslateY = layerIndex * self.textHeight + (
                layerIndex + 1) * (self.extent.y * self.unitScale +
                                   self.margin)
            translateYRounded = self.getRounded(layerTranslateY)
            self.graphicsCopy.attributeDictionary[
                'transform'] = 'translate(%s, %s)' % (marginRounded,
                                                      translateYRounded)
            self.graphicsCopy.getFirstChildWithClassName(
                'text').text = 'Layer %s, z:%s' % (layerIndex, zRounded)
        self.pathXMLElement = self.graphicsCopy.getFirstChildWithClassName(
            'path')
        self.pathDictionary = self.pathXMLElement.attributeDictionary

    def addOriginalAsComment(self, xmlElement):
        "Add original xmlElement as a comment."
        if xmlElement == None:
            return
        commentElement = XMLElement()
        commentElement.className = 'comment'
        xmlElementOutput = cStringIO.StringIO()
        xmlElement.addXML(0, xmlElementOutput)
        textLines = archive.getTextLines(xmlElementOutput.getvalue())
        commentElementOutput = cStringIO.StringIO()
        isComment = False
        for textLine in textLines:
            lineStripped = textLine.strip()
            if lineStripped[:len('<!--')] == '<!--':
                isComment = True
            if not isComment:
                if len(textLine) > 0:
                    commentElementOutput.write(textLine + '\n')
            if '-->' in lineStripped:
                isComment = False
        commentElement.text = '<!-- Original XML Text:\n%s-->\n' % commentElementOutput.getvalue(
        )
        commentElement.setParentAddToChildren(self.svgElement)

    def addRotatedLoopLayerToOutput(self, layerIndex, rotatedBoundaryLayer):
        "Add rotated boundary layer to the output."
        self.addLayerBegin(layerIndex, rotatedBoundaryLayer)
        if rotatedBoundaryLayer.rotation != None:
            self.graphicsCopy.attributeDictionary['bridgeRotation'] = str(
                rotatedBoundaryLayer.rotation)
        if self.addLayerTemplateToSVG:
            self.pathDictionary['transform'] = self.getTransformString()
        else:
            del self.pathDictionary['transform']
        self.pathDictionary['d'] = self.getSVGStringForLoops(
            rotatedBoundaryLayer.loops)

    def addRotatedLoopLayersToOutput(self, rotatedBoundaryLayers):
        "Add rotated boundary layers to the output."
        for rotatedBoundaryLayerIndex, rotatedBoundaryLayer in enumerate(
                rotatedBoundaryLayers):
            self.addRotatedLoopLayerToOutput(rotatedBoundaryLayerIndex,
                                             rotatedBoundaryLayer)

    def getReplacedSVGTemplate(self,
                               fileName,
                               procedureName,
                               rotatedBoundaryLayers,
                               xmlElement=None):
        "Get the lines of text from the layer_template.svg file."
        #		( layers.length + 1 ) * (margin + sliceDimY * unitScale + txtHeight) + margin + txtHeight + margin + 110
        cornerMaximum = self.carving.getCarveCornerMaximum()
        cornerMinimum = self.carving.getCarveCornerMinimum()
        self.extent = cornerMaximum - cornerMinimum
        svgTemplateText = archive.getFileTextInFileDirectory(
            __file__, os.path.join('templates', 'layer_template.svg'))
        self.xmlParser = XMLSimpleReader(fileName, None, svgTemplateText)
        self.svgElement = self.xmlParser.getRoot()
        if not self.addLayerTemplateToSVG:
            self.svgElement.getXMLElementByID(
                'layerTextTemplate').removeFromIDNameParent()
            del self.svgElement.getXMLElementByID(
                'sliceElementTemplate').attributeDictionary['transform']
        svgElementDictionary = self.svgElement.attributeDictionary
        self.graphicsXMLElement = self.svgElement.getXMLElementByID(
            'sliceElementTemplate')
        self.graphicsXMLElement.attributeDictionary['id'] = 'z:'
        self.addRotatedLoopLayersToOutput(rotatedBoundaryLayers)
        self.sliceDictionary = getSliceDictionary(self.svgElement)
        self.setMetadataNoscriptElement('layerThickness',
                                        self.carving.getCarveLayerThickness())
        self.setMetadataNoscriptElement('maxX', cornerMaximum.x)
        self.setMetadataNoscriptElement('minX', cornerMinimum.x)
        self.setMetadataNoscriptElement('maxY', cornerMaximum.y)
        self.setMetadataNoscriptElement('minY', cornerMinimum.y)
        self.setMetadataNoscriptElement('maxZ', cornerMaximum.z)
        self.setMetadataNoscriptElement('minZ', cornerMinimum.z)
        self.margin = float(self.sliceDictionary['margin'])
        self.textHeight = float(self.sliceDictionary['textHeight'])
        javascriptControlBoxWidth = float(
            self.sliceDictionary['javascriptControlBoxWidth'])
        noJavascriptControlBoxHeight = float(
            self.sliceDictionary['noJavascriptControlBoxHeight'])
        controlTop = len(rotatedBoundaryLayers) * (
            self.margin + self.extent.y * self.unitScale +
            self.textHeight) + 2.0 * self.margin + self.textHeight
        self.svgElement.getFirstChildWithClassName(
            'title').text = os.path.basename(fileName) + ' - Slice Layers'
        svgElementDictionary['height'] = '%spx' % self.getRounded(
            controlTop + noJavascriptControlBoxHeight + self.margin)
        #		width = margin + (sliceDimX * unitScale) + margin;
        width = 2.0 * self.margin + max(self.extent.x * self.unitScale,
                                        javascriptControlBoxWidth)
        svgElementDictionary['width'] = '%spx' % self.getRounded(width)
        self.sliceDictionary['decimalPlacesCarried'] = str(
            self.decimalPlacesCarried)
        if self.perimeterWidth != None:
            self.sliceDictionary['perimeterWidth'] = self.getRounded(
                self.perimeterWidth)
        self.sliceDictionary['yAxisPointingUpward'] = 'true'
        self.sliceDictionary['procedureDone'] = procedureName
        noJavascriptDictionary = self.svgElement.getXMLElementByID(
            'noJavascriptControls').attributeDictionary
        noJavascriptDictionary['transform'] = 'translate(%s, %s)' % (
            self.getRounded(self.margin), self.getRounded(controlTop))
        self.svgElement.getXMLElementByID(
            'dimXNoJavascript').text = self.getRounded(self.extent.x)
        self.svgElement.getXMLElementByID(
            'dimYNoJavascript').text = self.getRounded(self.extent.y)
        self.svgElement.getXMLElementByID(
            'dimZNoJavascript').text = self.getRounded(self.extent.z)
        if not self.addLayerTemplateToSVG:
            self.svgElement.getFirstChildWithClassName(
                'script').removeFromIDNameParent()
            self.svgElement.getXMLElementByID(
                'beginningOfControlSection').removeFromIDNameParent()
            self.svgElement.getXMLElementByID(
                'noJavascriptControls').removeFromIDNameParent()
        self.graphicsXMLElement.removeFromIDNameParent()
        self.addOriginalAsComment(xmlElement)
        output = cStringIO.StringIO()
        output.write(self.xmlParser.beforeRoot)
        self.svgElement.addXML(0, output)
        return output.getvalue()

    def getRounded(self, number):
        "Get number rounded to the number of carried decimal places as a string."
        return euclidean.getRoundedToDecimalPlacesString(
            self.decimalPlacesCarried, number)

    def getRoundedComplexString(self, point):
        "Get the rounded complex string."
        return self.getRounded(point.real) + ' ' + self.getRounded(point.imag)

    def getSVGStringForLoop(self, loop):
        "Get the svg loop string."
        if len(loop) < 1:
            return ''
        return self.getSVGStringForPath(loop) + ' z'

    def getSVGStringForLoops(self, loops):
        "Get the svg loops string."
        loopString = ''
        if len(loops) > 0:
            loopString += self.getSVGStringForLoop(loops[0])
        for loop in loops[1:]:
            loopString += ' ' + self.getSVGStringForLoop(loop)
        return loopString

    def getSVGStringForPath(self, path):
        "Get the svg path string."
        svgLoopString = ''
        for point in path:
            stringBeginning = 'M '
            if len(svgLoopString) > 0:
                stringBeginning = ' L '
            svgLoopString += stringBeginning + self.getRoundedComplexString(
                point)
        return svgLoopString

    def getTransformString(self):
        "Get the svg transform string."
        cornerMinimumXString = self.getRounded(
            -self.carving.getCarveCornerMinimum().x)
        cornerMinimumYString = self.getRounded(
            -self.carving.getCarveCornerMinimum().y)
        return 'scale(%s, %s) translate(%s, %s)' % (
            self.unitScale, -self.unitScale, cornerMinimumXString,
            cornerMinimumYString)

    def setMetadataNoscriptElement(self, prefix, value):
        "Set the metadata value and the NoJavascript text."
        valueString = self.getRounded(value)
        self.sliceDictionary[prefix] = valueString
        self.svgElement.getXMLElementByID(prefix +
                                          'NoJavascript').text = valueString