* Fix projection
* Fix face color rendering and add a way to disable wireframe
* Use a scene for the transformed object so we don't touch the
original user data
* Add a better visibility routine
* A little better depth sorting
* Add support for batch mode
Signed-off-by: Antonio Ospite <ospite@studenti.unina.it>
else:
m2 = self._calcPerspectiveMatrix(fovy, aspect, near, far)
else:
m2 = self._calcPerspectiveMatrix(fovy, aspect, near, far)
- m1 = Matrix()
- mP = Matrix()
- cam = cameraObj.getInverseMatrix()
+ cam = Matrix(cameraObj.getInverseMatrix())
- m1 = obMesh.getMatrix()
+ m1 = Matrix(obMesh.getMatrix())
m1.transpose()
mP = cam * m1
m1.transpose()
mP = cam * m1
mH = self.size[1]/2
if p[3]<=0:
mH = self.size[1]/2
if p[3]<=0:
- p[0] = int(p[0]*mW)+mW
- p[1] = int(p[1]*mH)+mH
+ p[0] = round(p[0]*mW)+mW
+ p[1] = round(p[1]*mH)+mH
- p[0] = int((p[0]/p[3])*mW)+mW
- p[1] = int((p[1]/p[3])*mH)+mH
+ p[0] = round((p[0]/p[3])*mW)+mW
+ p[1] = round((p[1]/p[3])*mH)+mH
# For now we want (0,0) in the top-left corner of the canvas
# Mirror and translate along y
# For now we want (0,0) in the top-left corner of the canvas
# Mirror and translate along y
+ Objects = scene.getChildren()
+ for obj in Objects:
+ for face in obj.getData().faces:
self._printPolygon(face)
self.file.write("</g>\n")
self._printPolygon(face)
self.file.write("</g>\n")
def _printPolygon(self, face):
"""Print our primitive, finally.
def _printPolygon(self, face):
"""Print our primitive, finally.
-
- There is no color Handling for now, *FIX!*
+
+ wireframe = False
+
+ stroke_width=0.5
self.file.write("<polygon points=\"")
self.file.write("<polygon points=\"")
- if i != 0:
- self.file.write(", ")
-
- i+=1
-
- self.file.write("%g, %g" % (v[0], v[1]))
+ self.file.write("%g,%g " % (v[0], v[1]))
- color = [ int(c*255) for c in face.col]
-
+ self.file.seek(-1,1) # get rid of the last space
+
+ #take as face color the first vertex color
+ fcol = face.col[0]
+ color = [fcol.r, fcol.g, fcol.b]
+
+ 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("\tstyle=\"fill:rgb("+str(color[0])+","+str(color[1])+","+str(color[2])+");")
- self.file.write(" stroke:rgb(0,0,0);")
+ 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-width:"+str(stroke_width)+";\n")
- self.file.write(" stroke-linecap:round;stroke-linejoin:round\"/>\n")
+ self.file.write(" stroke-linecap:round;stroke-linejoin:round")
+ self.file.write("\"/>\n")
# ---------------------------------------------------------------------
# ---------------------------------------------------------------------
Objects = scene.getChildren()
# A structure to store the transformed scene
Objects = scene.getChildren()
# A structure to store the transformed scene
+ newscene = Scene.New("flat"+scene.name)
proj = Projector(cameraObj, obj, self.canvasSize)
# Let's store the transformed data
proj = Projector(cameraObj, obj, self.canvasSize)
# Let's store the transformed data
- transformed_mesh = NMesh.New(obj.name)
+ transformed_mesh = NMesh.New("flat"+obj.name)
+ transformed_mesh.hasVertexColours(1)
# Store the materials
materials = obj.getData().getMaterials()
# Store the materials
materials = obj.getData().getMaterials()
for face in meshfaces:
# if the face is visible flatten it on the "picture plane"
for face in meshfaces:
# if the face is visible flatten it on the "picture plane"
- if self._isFaceVisible(face, obj, cameraObj):
+ if self._isFaceVisible_old(face, obj, cameraObj):
for vert in face:
p = proj.doProjection(vert.co)
for vert in face:
p = proj.doProjection(vert.co)
- transformed_vert = NMesh.Vert(p[0], p[1], p[2])
- transformed_face.append(transformed_vert)
+ tmp_vert = NMesh.Vert(p[0], p[1], p[2])
- newface = NMesh.Face(transformed_face)
+ # Add the vert to the mesh
+ transformed_mesh.verts.append(tmp_vert)
+
+ newface.v.append(tmp_vert)
+
# Per-face color calculation
# code taken mostly from the original vrm script
# TODO: understand the code and rewrite it clearly
# Per-face color calculation
# code taken mostly from the original vrm script
# TODO: understand the code and rewrite it clearly
- ambient = -250
- fakelight = [10, 10, 15]
- norm = face.normal
+ ambient = -150
+
+ fakelight = Object.Get("Lamp").loc
+ if fakelight == None:
+ fakelight = [1.0, 1.0, -0.3]
+
+ norm = Vector(face.no)
vektori = (norm[0]*fakelight[0]+norm[1]*fakelight[1]+norm[2]*fakelight[2])
vduzine = fabs(sqrt(pow(norm[0],2)+pow(norm[1],2)+pow(norm[2],2))*sqrt(pow(fakelight[0],2)+pow(fakelight[1],2)+pow(fakelight[2],2)))
intensity = floor(ambient + 200*acos(vektori/vduzine))/200
vektori = (norm[0]*fakelight[0]+norm[1]*fakelight[1]+norm[2]*fakelight[2])
vduzine = fabs(sqrt(pow(norm[0],2)+pow(norm[1],2)+pow(norm[2],2))*sqrt(pow(fakelight[0],2)+pow(fakelight[1],2)+pow(fakelight[2],2)))
intensity = floor(ambient + 200*acos(vektori/vduzine))/200
intensity = 0
if materials:
intensity = 0
if materials:
- newface.col = materials[face.mat].getRGBCol()
+ tmp_col = materials[face.mat].getRGBCol()
- newface.col = [0.5, 0.5, 0.5]
+ tmp_col = [0.5, 0.5, 0.5]
- newface.col = [ (c>0) and (c-intensity) for c in newface.col]
+ tmp_col = [ (c>intensity) and int(round((c-intensity)*10)*25.5) for c in tmp_col ]
+
+ vcol = NMesh.Col(tmp_col[0], tmp_col[1], tmp_col[2])
+ newface.col = [vcol, vcol, vcol, 255]
transformed_mesh.addFace(newface)
# at the end of the loop on obj
transformed_mesh.addFace(newface)
# at the end of the loop on obj
- #transformed_object = NMesh.PutRaw(transformed_mesh)
- newscene.append(transformed_mesh)
+ transformed_obj = Object.New(obj.getType(), "flat"+obj.name)
+ transformed_obj.link(transformed_mesh)
+ transformed_obj.loc = obj.loc
+ newscene.link(transformed_obj)
- # reverse the order (TODO: See how is the object order in NMesh)
- #newscene.reverse()
- def _isFaceVisible(self, face, obj, cameraObj):
+ def _isFaceVisible_old(self, face, obj, cameraObj):
"""Determine if the face is visible from the current camera.
The following code is taken basicly from the original vrm script.
"""Determine if the face is visible from the current camera.
The following code is taken basicly from the original vrm script.
c[1] += obj.LocY - camera.LocY
c[2] += obj.LocZ - camera.LocZ
c[1] += obj.LocY - camera.LocY
c[2] += obj.LocZ - camera.LocZ
norm[0] = (b[1] - a[1])*(c[2] - a[2]) - (c[1] - a[1])*(b[2] - a[2])
norm[1] = -((b[0] - a[0])*(c[2] - a[2]) - (c[0] - a[0])*(b[2] - a[2]))
norm[2] = (b[0] - a[0])*(c[1] - a[1]) - (c[0] - a[0])*(b[1] - a[1])
d = norm[0]*a[0] + norm[1]*a[1] + norm[2]*a[2]
norm[0] = (b[1] - a[1])*(c[2] - a[2]) - (c[1] - a[1])*(b[2] - a[2])
norm[1] = -((b[0] - a[0])*(c[2] - a[2]) - (c[0] - a[0])*(b[2] - a[2]))
norm[2] = (b[0] - a[0])*(c[1] - a[1]) - (c[0] - a[0])*(b[1] - a[1])
d = norm[0]*a[0] + norm[1]*a[1] + norm[2]*a[2]
- # d = DotVecs(norm, Vector(a))
+ #d = DotVecs(Vector(norm), Vector(a))
+
+ return (d<0)
+
+ def _isFaceVisible(self, face, obj, cameraObj):
+ """Determine if the face is visible from the current camera.
+
+ The following code is taken basicly from the original vrm script.
+ """
+
+ camera = cameraObj
+
+ numvert = len(face)
+
+ # backface culling
+
+ # translate and rotate according to the object matrix
+ # and then translate according to the camera position
+ m = obj.getMatrix()
+ m.transpose()
+
+ a = m*Vector(face[0]) - Vector(cameraObj.loc)
+ b = m*Vector(face[1]) - Vector(cameraObj.loc)
+ c = m*Vector(face[numvert-1]) - Vector(cameraObj.loc)
+
+ norm = m*Vector(face.no)
+
+ d = DotVecs(norm, a)
# ---------------------------------------------------------------------
# ---------------------------------------------------------------------
-# hackish sorting of faces according to the max z value of a vertex
-def zSorting(scene):
- for o in scene:
- o.faces.sort(lambda f1, f2:
+# FIXME: really hackish code, just to test if the other parts work
+def depthSorting(scene):
+
+ cameraObj = Scene.GetCurrent().getCurrentCamera()
+ Objects = scene.getChildren()
+
+ Objects.sort(lambda obj1, obj2:
+ cmp(Vector(Vector(cameraObj.loc) - Vector(obj1.loc)).length,
+ Vector(Vector(cameraObj.loc) - Vector(obj2.loc)).length
+ )
+ )
+
+ # hackish sorting of faces according to the max z value of a vertex
+ for o in Objects:
+
+ mesh = o.data
+ mesh.faces.sort(
+ lambda f1, f2:
# Sort faces according to the min z coordinate in a face
#cmp(min([v[2] for v in f1]), min([v[2] for v in f2])))
# Sort faces according to the min z coordinate in a face
#cmp(min([v[2] for v in f1]), min([v[2] for v in f2])))
# Sort faces according to the avg z coordinate in a face
#cmp(sum([v[2] for v in f1])/len(f1), sum([v[2] for v in f2])/len(f2)))
# Sort faces according to the avg z coordinate in a face
#cmp(sum([v[2] for v in f1])/len(f1), sum([v[2] for v in f2])/len(f2)))
+ mesh.faces.reverse()
+ mesh.update()
+
+ # update the scene
+ for o in scene.getChildren():
+ scene.unlink(o)
+ for o in Objects:
+ scene.link(o)
def vectorize(filename):
print "Filename: %s" % filename
def vectorize(filename):
print "Filename: %s" % filename
- print
- filename = filename.replace('/', sys.sep)
- print filename
- print
- scene = Scene.GetCurrent()
+ scene = Scene.GetCurrent()
renderer = Renderer()
flatScene = renderer.doRendering(scene)
canvasSize = renderer.getCanvasSize()
renderer = Renderer()
flatScene = renderer.doRendering(scene)
canvasSize = renderer.getCanvasSize()
+ depthSorting(flatScene)
writer = SVGVectorWriter(filename, canvasSize)
writer.printCanvas(flatScene)
writer = SVGVectorWriter(filename, canvasSize)
writer.printCanvas(flatScene)
-
-try:
- Blender.Window.FileSelector (vectorize, 'Save SVG', "proba.svg")
-except:
- vectorize("proba.svg")
+
+ Blender.Scene.unlink(flatScene)
+ del flatScene
+
+# Here the main
+if __name__ == "__main__":
+ try:
+ Blender.Window.FileSelector (vectorize, 'Save SVG', "proba.svg")
+ except:
+ vectorize("proba.svg")