From: Antonio Ospite Date: Sat, 1 Jul 2006 14:59:37 +0000 (+0200) Subject: Warn about negative scales X-Git-Tag: vrm-0.3~26 X-Git-Url: https://git.ao2.it/vrm.git/commitdiff_plain/dcc666c5b495072d477e85b544d6eb967fb6acc0 Warn about negative scales * Get the Projector earlier * Cleanup the workspace if the rendering fails * Add a warning if the objects has negative scale values, blender does not transform normals correctly in this case Signed-off-by: Antonio Ospite --- diff --git a/vrm.py b/vrm.py index aa73b10..35df00c 100755 --- a/vrm.py +++ b/vrm.py @@ -57,7 +57,9 @@ __bpydoc__ = """\ # Think to a way to merge adjacent polygons that have the same color. # Or a way to use paths for silhouettes and contours. # - Add Vector Writers other that SVG. -# - Consider SMIL for animation handling instead of ECMA Script? +# - Consider SMIL for animation handling instead of ECMA Script? (Firefox do +# not support SMIL for animations) +# - FIX the issue with negative scales in object tranformations! # # --------------------------------------------------------------------- # @@ -408,6 +410,7 @@ class SVGVectorWriter(VectorWriter): self.file.write("\n" % (framenumber, framestyle) ) + for obj in Objects: if(obj.getType() != 'Mesh'): @@ -575,8 +578,6 @@ class SVGVectorWriter(VectorWriter): hidden_stroke_style = "" - # We consider an edge visible if _both_ its vertices are selected, - # hence an edge is hidden if _any_ of its vertices is deselected. if e.sel == 0: if showHiddenEdges == False: continue @@ -647,6 +648,12 @@ class Renderer: # Render from the currently active camera self.cameraObj = self._SCENE.getCurrentCamera() + # Get a projector for this camera. + # NOTE: the projector wants object in world coordinates, + # so we should remember to apply modelview transformations + # _before_ we do projection transformations. + self.proj = Projector(self.cameraObj, self.canvasRatio) + # Get the list of lighting sources obj_lst = self._SCENE.getChildren() self.lights = [ o for o in obj_lst if o.getType() == 'Lamp'] @@ -692,7 +699,16 @@ class Renderer: for f in range(startFrame, endFrame+1): context.currentFrame(f) - renderedScene = self.doRenderScene(self._SCENE) + # Use some temporary workspace, a full copy of the scene + inputScene = self._SCENE.copy(2) + + try: + renderedScene = self.doRenderScene(inputScene) + except: + self._SCENE.makeCurrent() + Scene.unlink(inputScene) + del inputScene + outputWriter.printCanvas(renderedScene, doPrintPolygons = PRINT_POLYGONS, doPrintEdges = PRINT_EDGES, @@ -708,22 +724,13 @@ class Renderer: context.currentFrame(currentFrame) - def doRenderScene(self, inputScene): + def doRenderScene(self, workScene): """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.cameraObj, self.canvasRatio) - # global processing of the scene self._doConvertGeometricObjToMesh(workScene) @@ -773,7 +780,7 @@ class Renderer: self._doEdgesStyle(mesh, edgeSelectionStyles[EDGE_STYLE]) - self._doProjection(mesh, proj) + self._doProjection(mesh, self.proj) # Update the object data, important! :) mesh.update() @@ -932,11 +939,17 @@ class Renderer: def _joinMeshObjectsInScene(self, scene): """Merge all the Mesh Objects in a scene into a single Mesh Object. """ + + oList = [o for o in scene.getChildren() if o.getType()=='Mesh'] + + # FIXME: Object.join() do not work if the list contains 1 object + if len(oList) == 1: + return + mesh = Mesh.New() bigObj = Object.New('Mesh', 'BigOne') bigObj.link(mesh) - oList = [o for o in scene.getChildren() if o.getType()=='Mesh'] bigObj.join(oList) scene.link(bigObj) for o in oList: @@ -971,6 +984,11 @@ class Renderer: This step is done simply applying to the object its tranformation matrix and recalculating its normals. """ + # XXX FIXME: blender do not transform normals in the right way when + # there are negative scale values + if matrix[0][0] < 0 or matrix[1][1] < 0 or matrix[2][2] < 0: + print "WARNING: Negative scales, expect incorrect results!" + mesh.transform(matrix, True) def _doObjectDepthSorting(self, mesh): @@ -1137,10 +1155,9 @@ class Renderer: for e in mesh.edges: + e.sel = 0 if edgestyleSelect(e, mesh): e.sel = 1 - else: - e.sel = 0 def _doProjection(self, mesh, projector): """Calculate the Projection for the object.