726c83d72263d0d6c5975a76890ef463ef6d5a37
[vrm.git] / vrm.py
1 #!BPY
2
3 """
4 Name: 'VRM'
5 Blender: 237
6 Group: 'Export'
7 Tooltip: 'Vector Rendering Method Export Script'
8 """
9
10 import Blender
11 from Blender import Scene, Object, Lamp, Camera
12 from math import *
13 from Blender.Window import *
14 from Blender.Scene import Render
15
16
17 # distance from camera Z'
18 def Distance(PX,PY,PZ):
19     
20     dist = sqrt(PX*PX+PY*PY+PZ*PZ)
21     return dist
22
23 def RotatePoint(PX,PY,PZ,AngleX,AngleY,AngleZ):
24     
25     NewPoint = []
26     # Rotate X
27     NewY = (PY * cos(AngleX))-(PZ * sin(AngleX))
28     NewZ = (PZ * cos(AngleX))+(PY * sin(AngleX))
29     # Rotate Y
30     PZ = NewZ
31     PY = NewY
32     NewZ = (PZ * cos(AngleY))-(PX * sin(AngleY))
33     NewX = (PX * cos(AngleY))+(PZ * sin(AngleY))
34     PX = NewX
35     PZ = NewZ
36     # Rotate Z
37     NewX = (PX * cos(AngleZ))-(PY * sin(AngleZ))
38     NewY = (PY * cos(AngleZ))+(PX * sin(AngleZ))
39     NewPoint.append(NewX)
40     NewPoint.append(NewY)
41     NewPoint.append(NewZ)
42     return NewPoint
43
44 def vetmatmult(v, M):
45     
46     v2 = [0, 0, 0, 0]
47     
48     for i in range(0, 3):
49         for j in range(0, 3):
50             v2[i] += (v[i]*M[i][j])
51
52     return v2
53
54 def flatern(vertx, verty, vertz):
55
56     cam = Camera.get()            # Get the cameras in scene
57     Lens = cam[0].getLens()       # The First Blender camera lens
58
59     camTyp = cam[0].getType()
60
61     msize = (context.imageSizeX(), context.imageSizeY())
62     xres = msize[0]             # X res for output
63     yres = msize[1]                # Y res for output
64     ratio = xres/yres
65
66     fov = atan(ratio * 16.0 / Lens)  # Get fov stuff
67     
68     dist = xres/2*tan(fov)         # Calculate dist from pinhole camera to image plane
69
70     screenxy=[0,0]
71     x=-vertx
72     y=verty
73     z=vertz
74
75     #----------------------------        
76     # calculate x'=dist*x/z & y'=dist*x/z
77     #----------------------------
78     screenxy[0]=int(xres/2.0+4*x*dist/z)
79     screenxy[1]=int(yres/2.0+4*y*dist/z)
80     return screenxy
81
82
83 ########
84 # Main #
85 ########
86
87 scena = Scene.GetCurrent()
88 context = scena.getRenderingContext()
89 renderDir = context.getRenderPath()
90
91 msize = (context.imageSizeX(), context.imageSizeY())
92
93 file=open("proba.svg","w")
94
95 file.write("<?xml version=\"1.0\"?>\n")
96 file.write("<svg width=\"" + `msize[0]` + "\" height=\"" + `msize[1]` + "\"\n")
97 file.write("\txmlns=\"http://www.w3.org/2000/svg\" version=\"1.2\" streamable=\"true\">\n")
98 #file.write("<pageSet>\n")
99
100 Objects = Blender.Object.Get()
101 NUMobjects = len(Objects)
102
103 startFrm = context.startFrame()
104 endFrm = startFrm
105 #endFrm = context.endFrame()
106 frames = range(startFrm, endFrm+1)
107
108 # are we rendering an animation ?
109 animation = (len(frames) > 1)
110
111 camera = scena.getCurrentCamera() # Get the current camera
112
113 for f in frames:
114     context.currentFrame(f)
115     Blender.Set('curframe', f)
116
117     DrawProgressBar (f/len(frames),"Rendering ..." + str(f))
118
119     print "Frame: ", f, "\n"
120     if animation :
121         file.write("<g id=\"Frame" + str(f) + "\" style=\"visibility:hidden\">\n")
122
123     for o in Objects:
124
125         if o.getType() == "Mesh":
126
127             obj = o                  # Get the first selected object
128             objname = obj.name                # The object name
129
130
131             OBJmesh = obj.getData()           # Get the mesh data for the object
132             meshfaces = OBJmesh.faces        # The number of faces in the object
133
134             #------------
135             # Get the Material Colors
136             #------------
137             
138             #MATinfo = OBJmesh.getMaterials()
139             #    
140             #if len(MATinfo) > 0:
141             #    RGB=MATinfo[0].rgbCol
142             #    R=int(RGB[0]*255)
143             #    G=int(RGB[1]*255)
144             #    B=int(RGB[2]*255)
145             #    color=`R`+"."+`G`+"."+`B`
146             #    print color
147             #else:
148             #    color="100.100.100"
149
150
151             for face in range(0, len(meshfaces)):
152                 numvert = len(OBJmesh.faces[face])
153                 
154                 #if (isVisible(face)):
155                 #    print "face visible"
156
157                 # backface culling
158                 a = []
159                 a.append(OBJmesh.faces[face][0][0])
160                 a.append(OBJmesh.faces[face][0][1])
161                 a.append(OBJmesh.faces[face][0][2])
162                 a = RotatePoint(a[0], a[1], a[2], obj.RotX, obj.RotY, obj.RotZ)
163                 a[0] += obj.LocX - camera.LocX
164                 a[1] += obj.LocY - camera.LocY
165                 a[2] += obj.LocZ - camera.LocZ
166                 b = []
167                 b.append(OBJmesh.faces[face][1][0])
168                 b.append(OBJmesh.faces[face][1][1])
169                 b.append(OBJmesh.faces[face][1][2])
170                 b = RotatePoint(b[0], b[1], b[2], obj.RotX, obj.RotY, obj.RotZ)
171                 b[0] += obj.LocX - camera.LocX
172                 b[1] += obj.LocY - camera.LocY
173                 b[2] += obj.LocZ - camera.LocZ
174                 c = []
175                 c.append(OBJmesh.faces[face][numvert-1][0])
176                 c.append(OBJmesh.faces[face][numvert-1][1])
177                 c.append(OBJmesh.faces[face][numvert-1][2])
178                 c = RotatePoint(c[0], c[1], c[2], obj.RotX, obj.RotY, obj.RotZ)
179                 c[0] += obj.LocX - camera.LocX
180                 c[1] += obj.LocY - camera.LocY
181                 c[2] += obj.LocZ - camera.LocZ
182
183                 norm = [0,0,0]
184                 norm[0] = (b[1] - a[1])*(c[2] - a[2]) - (c[1] - a[1])*(b[2] - a[2])
185                 norm[1] = -((b[0] - a[0])*(c[2] - a[2]) - (c[0] - a[0])*(b[2] - a[2]))
186                 norm[2] = (b[0] - a[0])*(c[1] - a[1]) - (c[0] - a[0])*(b[1] - a[1])
187
188                 d = norm[0]*a[0] + norm[1]*a[1] + norm[2]*a[2]
189
190                 # if the face is visible flatten it on the "picture plane"
191                 if d < 0:
192                     file.write("<polygon points=\"")
193                     for vert in range(numvert):
194
195                         vertxyz = []
196
197                         if vert != 0: file.write(", ")
198
199                         vertxyz.append(OBJmesh.faces[face][vert][0])
200                         vertxyz.append(OBJmesh.faces[face][vert][1])
201                         vertxyz.append(OBJmesh.faces[face][vert][2])
202
203                         # rotate object
204                         vertxyz = RotatePoint(vertxyz[0], vertxyz[1], vertxyz[2], obj.RotX, obj.RotY, obj.RotZ)
205
206                         # original setting for translate
207                         vertxyz[0] += (obj.LocX - camera.LocX)
208                         vertxyz[1] += (obj.LocY - camera.LocY)
209                         vertxyz[2] += (obj.LocZ - camera.LocZ)
210
211                         # rotate camera
212                         vertxyz = RotatePoint(vertxyz[0], vertxyz[1], vertxyz[2], -camera.RotX, -camera.RotY, -camera.RotZ)
213
214                         #dist = Distance(vertxyz[0], vertxyz[1], vertxyz[2])
215                         xy = flatern(vertxyz[0], vertxyz[1], vertxyz[2])
216                         px = int(xy[0])
217                         py = int(xy[1])
218                         # add/sorting in Z' direction
219                         #Dodaj(px,py,Distance(vertxyz[0], vertxyz[1], vertxyz[2]))
220                         file.write(`px` + ", " + `py`)
221
222                     # per face color calculation
223                     ambient = -200
224                     #svetlo = [1, 1, -1] #original
225                     svetlo = [1, 1, -0.3]
226                     vektori = (norm[0]*svetlo[0]+norm[1]*svetlo[1]+norm[2]*svetlo[2])
227                     vduzine = fabs(sqrt(pow(norm[0],2)+pow(norm[1],2)+pow(norm[2],2))*sqrt(pow(svetlo[0],2)+pow(svetlo[1],2)+pow(svetlo[2],2)))
228                     intensity = floor(ambient + 255 * acos(vektori/vduzine))
229                     if intensity < 0:
230                         intensity = 0
231                     
232                     wireframe = True
233                     if wireframe:
234                         stroke_width=1
235                     else: 
236                         stroke_width=0
237                     file.write("\"\n style=\"fill:rgb("+str(intensity)+","+str(intensity)+","+str(intensity)+");stroke:rgb(0,0,0);stroke-width:"+str(stroke_width)+"\"/>\n")
238     if animation:
239         file.write("<animate attributeName=\"visibility\" begin=\""+str(f*0.08)+"s\" dur=\"0.08s\" fill=\"remove\" to=\"visible\">\n")
240         file.write("</animate>\n")
241         file.write("</g>\n")
242
243 file.write("</svg>")
244 file.close()
245 DrawProgressBar (1.0,"Finished.")
246 print "Finished\n"