root/sgf2pov/sgf2pov.py

Revision 1, 9.0 kB (checked in by ug, 2 years ago)

Import sgf2pov project.

  • Property svn:executable set to
Line 
1 #! /usr/bin/env python
2 # File: sgf2pov.py
3
4 ##   Written by Ulrich Goertz (u@g0ertz.de)
5
6 ##   sgf2pov is a program which takes a go board position or an SGF file and
7 ##   creates source code which can be fed into the ray-tracing program
8 ##   povray, to produce a high quality 3d image of the position.
9
10 import sys
11 from random import randint
12
13 epsilon = 0.0001
14
15 BOARDSIZE = 15.0
16 BOARDHEIGHT = 1.0
17
18 LINEWIDTH = 0.05
19
20 step = BOARDSIZE / 20
21 smallstep = 0.01
22
23 def placeWhiteStone(line_number, i, irreg = (0,0)):
24     outfile.write('sphere { 0 %f \n' % (BOARDSIZE/40))
25     outfile.write('  texture{ \n')
26     if randint(0,2) == 0:
27         outfile.write('    pigment { \n')
28         outfile.write('      marble // gradient x\n')
29         outfile.write('      color_map {\n')
30         outfile.write('        [0.0 color White]\n')
31         outfile.write('        [0.2 color White]\n')
32         outfile.write('        [0.45 color Gray95]\n')
33         outfile.write('        [0.55 color Gray95]\n')
34         outfile.write('        [0.75 color White]\n')
35         outfile.write('        [1.0 color White]\n')
36         outfile.write('      } \n')
37         outfile.write('      frequency %f \n' % (6.5 + .2 * randint(0,5)))
38         outfile.write('      turbulence %f \n' % (.08 + .008 * randint(0,5)))
39         outfile.write('    }\n')
40         outfile.write('    finish { Shiny } // ambient .4} // specular .5 roughness .05 }\n')
41     else:
42         outfile.write('    pigment { \n')
43         outfile.write('      marble // gradient x\n')
44         outfile.write('      color_map {\n')
45         outfile.write('        [0.0 color White]\n')
46         outfile.write('        [0.2 color White]\n')
47         outfile.write('        [0.45 color Gray85]\n')
48         outfile.write('        [0.55 color Gray85]\n')
49         outfile.write('        [0.75 color White]\n')
50         outfile.write('        [1.0 color White]\n')
51         outfile.write('      } \n')
52         outfile.write('      frequency %f \n' % (6.5 + .2 * randint(0,5)))
53         outfile.write('      turbulence %f \n' % (.08 + .008 * randint(0,5)))
54         outfile.write('    }\n')
55         outfile.write('    finish { Shiny } // specular .5 roughness .05 }\n')
56     outfile.write('  }\n')
57     outfile.write('  scale < 1,0.4,1>\n')
58     outfile.write('  rotate %f * y \n' % randint(0,359))
59     outfile.write('translate <%f, %f, %f > }\n' % ((line_number-9)*step + smallstep*irreg[0],
60                                                    0.2*BOARDSIZE/20-0.05, (i-9)*step + smallstep*irreg[1]))
61
62 def placeBlackStone(line_number, i, irreg=(0,0)):
63     outfile.write('sphere { 0 %f \n' % (BOARDSIZE/40))
64     outfile.write('  texture{ pigment { Black } finish { specular .2 roughness .05 } } \n')
65     outfile.write('  scale < 1,0.4,1> \n')
66     outfile.write('  translate <%f, %f, %f > ' % ((line_number-9)*step + smallstep*irreg[0],
67                                                      0.2*BOARDSIZE/20-0.05, (i-9)*step + smallstep*irreg[1]))
68     outfile.write('}\n')
69
70
71 def putBoard():
72     outfile.write('plane { y, -1 texture{ pigment{ White } finish{ Shiny } } }\n')
73
74     outfile.write('box {\n')
75     outfile.write('  < %f, %f, %f >, \n' % (-BOARDSIZE/2,-BOARDHEIGHT,-BOARDSIZE/2))
76     outfile.write('  < %f, %f, %f >\n' % (BOARDSIZE/2, -10*epsilon, BOARDSIZE/2))
77     outfile.write('  texture {\n')
78     outfile.write('    T_Wood10\n')
79     outfile.write('    scale 2\n')
80     # outfile.write('    normal { dents 4 scale 4 }\n')
81     outfile.write('  }\n')
82     outfile.write('}\n')
83    
84
85     # draw lines on the board
86
87     for i in range(19):
88         outfile.write('box {\n')
89         outfile.write('  <%f, %f, %f>,\n' % (-BOARDSIZE/2 + (i+1)*step - LINEWIDTH/2, -9*epsilon, -BOARDSIZE/2+step))
90         outfile.write('  <%f, %f, %f>\n' % (-BOARDSIZE/2 + (i+1)*step + LINEWIDTH/2, -8*epsilon, +BOARDSIZE/2-step))
91         outfile.write('  texture{ pigment{ Black } finish {specular .02 ambient 0 } }\n')
92         outfile.write('}\n')
93        
94         outfile.write('box {\n')
95         outfile.write('  <%f, %f, %f>,\n' % (-BOARDSIZE/2 + step, -7*epsilon, -BOARDSIZE/2+(i+1)*step - LINEWIDTH/2))
96         outfile.write('  <%f, %f, %f>\n' % (+BOARDSIZE/2 - step, -6*epsilon, -BOARDSIZE/2+(i+1)*step + LINEWIDTH/2))
97         outfile.write('  texture{ pigment{ Black } finish {specular .02 ambient 0 } }\n')
98         outfile.write('}\n')
99
100     # hoshi points
101
102     for i in [4, 10, 16]:
103         for j in [4, 10, 16]:
104             outfile.write('cylinder { < %f, %f, %f >, <%f, %f, %f >, %f \n' % \
105                           (-BOARDSIZE/2+(i)*step, 5*epsilon, -BOARDSIZE/2+(j)*step,
106                            -BOARDSIZE/2+(i)*step, 4*epsilon, -BOARDSIZE/2+(j)*step,
107                            2*LINEWIDTH))
108             outfile.write('  texture{ pigment{ Black } finish {specular .02 ambient 0 } }\n')
109             outfile.write('}\n')
110
111
112 def drawPosition(pos, irreg = None):
113     if irreg:
114         for line_number in range(19):
115             for i in range(19):
116                 if pos[(line_number,i)] == 'O':
117                     placeWhiteStone(line_number, i, irreg[(line_number,i)])
118                 elif pos[(line_number,i)] == 'X':
119                     placeBlackStone(line_number, i, irreg[(line_number,i)])
120        
121     else:
122         for line_number in range(19):
123             for i in range(19):
124                 if pos[(line_number,i)] == 'O':
125                     placeWhiteStone(line_number, i)
126                 elif pos[(line_number,i)] == 'X':
127                     placeBlackStone(line_number, i)
128
129
130
131 def getIrreg(pos):
132     irreg = {}
133    
134     for i in range(19):
135         for j in range(19):
136             irreg[(i,j)] = [0,0]
137            
138     for i in range(19):
139
140         foundBeginning = -1
141        
142         for j in range(19):
143             if pos[(i,j)] == '.':
144                 if foundBeginning == -1: continue
145
146                 # string completed
147
148                 if j-foundBeginning > 15:
149                     irreg[(i,foundBeginning)][1] = randint(-2,0)
150                 elif j-foundBeginning > 8:
151                     irreg[(i,foundBeginning)][1] = randint(-2,1)
152                 else:
153                     irreg[(i,foundBeginning)][1] = randint(-2,2)
154                    
155                 for k in range(foundBeginning+1, j):
156
157                     if j - k > 15:
158                         limit = 0
159                     elif j - k > 8:
160                         limit = 1
161                     else:
162                         limit = 2
163                    
164                     irreg[(i,k)][1] = irreg[(i,k-1)][1] + randint(0, limit-irreg[(i,k-1)][1])
165
166                 foundBeginning = -1
167
168             elif pos[(i,j)] in ['X', 'O'] and foundBeginning == -1:
169                 foundBeginning = j
170
171     for j in range(19):
172
173         foundBeginning = -1
174        
175         for i in range(18,-1):
176             if pos[(i,j)] == '.':
177                 if foundBeginning == -1: continue
178
179                 # string completed
180
181                 if i-foundBeginning > 15:
182                     irreg[(foundBeginning,j)][1] = randint(-2,0)
183                 elif i-foundBeginning > 8:
184                     irreg[(foundBeginning,j)][1] = randint(-2,1)
185                 else:
186                     irreg[(foundBeginning,j)][1] = randint(-2,2)
187                    
188                 for k in range(foundBeginning+1, i):
189
190                     if i - k > 15:
191                         limit = 0
192                     elif i - k > 8:
193                         limit = 1
194                     else:
195                         limit = 2
196                    
197                     irreg[(k,j)][1] = irreg[(k-1,j)][1] + randint(0, limit-irreg[(k-1,j)][1])
198
199                 foundBeginning = -1
200
201             elif pos[(i,j)] in ['X', 'O'] and foundBeginning == -1:
202                 foundBeginning = i
203
204
205     return irreg
206        
207
208 def initPOV():
209     outfile.write('#include "shapes.inc"\n')
210     outfile.write('#include "colors.inc"\n')
211     outfile.write('#include "textures.inc"\n')
212     outfile.write('#include "woods.inc"\n')
213     outfile.write('#include "stones.inc"\n')
214
215
216 def putCamera():
217     outfile.write('camera {\n')
218     outfile.write('  location  <0.5, 12.0, -12>\n')
219     # outfile.write('  location  <0,.3,0>\n')
220     outfile.write('  up        <0.0, 1.0,  0.0>\n')
221     outfile.write('  right     <4/3, 0.0,  0.0>\n')
222     outfile.write('  look_at   <.0, .0,  .0>\n')
223     outfile.write('}\n')
224
225
226 def putLightSource():
227     # outfile.write('light_source { <-1,2,0> color White }\n')
228     outfile.write('light_source { <5, 15, 0> color White }\n')
229
230 if len(sys.argv) < 2:
231     print 'Usage: sgf2pov.py FILENAME'
232     print 'This will read a position in SL format from FILENAME,'
233     print 'and write a file which can be processed by Povray to'
234     print 'FILENAME.pov.'
235     sys.exit()
236
237 outfile = open(sys.argv[1]+'.pov', 'w')
238
239 initPOV()
240 putCamera()
241 putLightSource()
242
243 putBoard()
244
245 try:
246     posfile = open(sys.argv[1])
247     lines = posfile.readlines()
248     posfile.close()
249 except:
250     print 'Unable to open file', sys.argv[1], '.'
251     sys.exit()
252
253 pos = {}
254 line_number = 0
255 for line in lines:
256     if not line.startswith('$$ | '): continue
257     l = line[5:].split(' ')
258     for i in range(19):
259         pos[(line_number,i)] = l[i]
260     line_number += 1
261
262 irreg = getIrreg(pos)
263 drawPosition(pos, irreg)
264
265 outfile.close()
266
267
Note: See TracBrowser for help on using the browser.