+ def printCanvas(self, scene, doPrintPolygons=True, doPrintEdges=False, showHiddenEdges=False):
+ """Convert the scene representation to SVG."""
+
+ Objects = scene.getChildren()
+ for obj in Objects:
+
+ if(obj.getType() != 'Mesh'):
+ continue
+ #
+
+ self.file.write("<g>\n")
+
+
+ if doPrintPolygons:
+ for face in obj.getData().faces:
+ self._printPolygon(face)
+
+ if doPrintEdges:
+ self._printEdges(obj.getData(), showHiddenEdges)
+
+ self.file.write("</g>\n")
+
+
+ ##
+ # Private Methods
+ #
+
+ def _printHeader(self):
+ """Print SVG header."""
+
+ self.file.write("<?xml version=\"1.0\"?>\n")
+ self.file.write("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n")
+ self.file.write("\t\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n")
+ self.file.write("<svg version=\"1.1\"\n")
+ self.file.write("\txmlns=\"http://www.w3.org/2000/svg\"\n")
+ self.file.write("\twidth=\"%d\" height=\"%d\" streamable=\"true\">\n\n" %
+ self.canvasSize)
+
+ def _printFooter(self):
+ """Print the SVG footer."""
+
+ self.file.write("\n</svg>\n")
+ self.file.close()
+
+ def _printEdges(self, mesh, showHiddenEdges=False):
+ """Print the wireframe using mesh edges... is this the correct way?
+ """
+
+ stroke_width=0.5
+ stroke_col = [0, 0, 0]
+
+ self.file.write("<g>\n")
+
+ for e in mesh.edges:
+
+ hidden_stroke_style = ""
+
+ # And edge is selected if both vertives are selected
+ if e.v1.sel == 0 or e.v2.sel == 0:
+ if showHiddenEdges == False:
+ continue
+ else:
+ hidden_stroke_style = ";\n stroke-dasharray:3, 3"
+
+ p1 = self._calcCanvasCoord(e.v1)
+ p2 = self._calcCanvasCoord(e.v2)
+
+ self.file.write("<line x1=\"%g\" y1=\"%g\" x2=\"%g\" y2=\"%g\"\n"
+ % ( p1[0], p1[1], p2[0], p2[1] ) )
+ self.file.write(" style=\"stroke:rgb("+str(stroke_col[0])+","+str(stroke_col[1])+","+str(stroke_col[2])+");")
+ self.file.write(" stroke-width:"+str(stroke_width)+";\n")
+ self.file.write(" stroke-linecap:round;stroke-linejoin:round")
+ self.file.write(hidden_stroke_style)
+ self.file.write("\"/>\n")
+
+ self.file.write("</g>\n")
+
+
+
+ def _printPolygon(self, face):
+ """Print our primitive, finally.
+ """
+
+ wireframe = False
+
+ stroke_width=0.5
+
+ self.file.write("<polygon points=\"")
+
+ for v in face:
+ p = self._calcCanvasCoord(v)
+ self.file.write("%g,%g " % (p[0], p[1]))
+
+ self.file.seek(-1,1) # get rid of the last space
+ self.file.write("\"\n")
+
+ #take as face color the first vertex color
+ if face.col:
+ fcol = face.col[0]
+ color = [fcol.r, fcol.g, fcol.b]
+ else:
+ color = [ 255, 255, 255]
+
+ stroke_col = [0, 0, 0]
+ if not wireframe:
+ stroke_col = color
+
+ self.file.write("\tstyle=\"fill:rgb("+str(color[0])+","+str(color[1])+","+str(color[2])+");")
+ self.file.write(" stroke:rgb("+str(stroke_col[0])+","+str(stroke_col[1])+","+str(stroke_col[2])+");")
+ self.file.write(" stroke-width:"+str(stroke_width)+";\n")
+ self.file.write(" stroke-linecap:round;stroke-linejoin:round")
+ self.file.write("\"/>\n")
+
+ def _calcCanvasCoord(self, v):
+
+ pt = Vector([0, 0, 0])
+
+ mW = self.canvasSize[0]/2
+ mH = self.canvasSize[1]/2
+
+ # rescale to canvas size
+ pt[0] = round(v[0]*mW)+mW
+ pt[1] = round(v[1]*mH)+mH
+
+ # For now we want (0,0) in the top-left corner of the canvas
+ # Mirror and translate along y
+ pt[1] *= -1
+ pt[1] += self.canvasSize[1]
+
+ return pt
+
+
+# ---------------------------------------------------------------------
+#
+## Rendering Classes
+#
+# ---------------------------------------------------------------------
+
+class Renderer:
+ """Render a scene viewed from a given camera.
+
+ This class is responsible of the rendering process, hence transformation
+ and projection of the ojects in the scene are invoked by the renderer.
+
+ The user can optionally provide a specific camera for the rendering, see
+ the #doRendering# method for more informations.
+ """
+
+ def __init__(self):
+ """Make the rendering process only for the current scene by default.
+ """
+
+ # Render the current Scene set as a READ-ONLY property
+ self._SCENE = Scene.GetCurrent()
+
+ # Use the aspect ratio of the scene rendering context
+ context = self._SCENE.getRenderingContext()
+ self.canvasRatio = (context.aspectRatioX(), context.aspectRatioY())
+
+ # Render from the currently active camera
+ self.camera = self._SCENE.getCurrentCamera()
+
+
+ ##
+ # Public Methods
+ #
+
+ def doRendering(self, outputWriter, animation=0):
+ """Render picture or animation and write it out.
+
+ The parameters are:
+ - a Vector writer object than will be used to output the result.
+ - a flag to tell if we want to render an animation or the only
+ current frame.
+ """
+
+ context = self._SCENE.getRenderingContext()
+ currentFrame = context.currentFrame()
+
+ # Handle the animation case
+ if animation == 0:
+ startFrame = currentFrame
+ endFrame = startFrame
+ else:
+ startFrame = context.startFrame()
+ endFrame = context.endFrame()
+
+ # Do the rendering process frame by frame
+ print "Start Rendering!"
+ for f in range(startFrame, endFrame+1):
+ context.currentFrame(f)
+ renderedScene = self.doRenderScene(self._SCENE)
+ outputWriter.printCanvas(renderedScene,
+ doPrintPolygons=False, doPrintEdges=True, showHiddenEdges=True)
+
+ # clear the rendered scene
+ self._SCENE.makeCurrent()
+ Scene.unlink(renderedScene)
+ del renderedScene
+
+ print "Done!"
+ context.currentFrame(currentFrame)
+
+
+
+ def doRenderScene(self, inputScene):
+ """Control the rendering process.
+
+ Here we control the entire rendering process invoking the operation
+ needed to transform and project the 3D scene in two dimensions.
+ """
+
+ # Use some temporary workspace, a full copy of the scene
+ workScene = inputScene.copy(2)
+
+ # Get a projector for this scene.
+ # NOTE: the projector wants object in world coordinates,
+ # so we should apply modelview transformations _before_
+ # projection transformations
+ proj = Projector(self.camera, self.canvasRatio)
+
+ # global processing of the scene
+ self._doDepthSorting(workScene)
+
+ # Per object activities
+ Objects = workScene.getChildren()
+
+ for obj in Objects:
+
+ if (obj.getType() != 'Mesh'):
+ print "Type:", obj.getType(), "\tSorry, only mesh Object supported!"
+ continue
+ #
+
+ self._doModelViewTransformations(obj)