1 '''Provides tools for building models.'''
2 from logging
import info
3 from os
import system
, walk
, makedirs
4 from os
.path
import exists
, basename
, dirname
5 from multiprocessing
import Pool
7 from hashlib
import md5
8 from shutil
import copyfile
, move
, rmtree
9 from ya2
.build
.mtprocesser
import ProcesserMgr
10 from ya2
.build
.build
import to_be_built
13 class ModelsBuilder():
16 self
._cache
_files
= [] # for avoiding rebuilding the same file
18 def build(self
, blend_path
, cores
):
19 '''Builds the models i.e. creates glTF and bam files from blend
22 for root
, _
, fnames
in walk(blend_path
):
23 for fname
in [fname
for fname
in fnames
if fname
.endswith('.blend')]:
24 if '/prototypes/' not in root
:
25 args
+= [(root
, fname
)]
27 p
.starmap(self
._export
_blend
, args
)
28 # caching is broken now: it is based on the previous
29 # non-multiprocessing approach
30 # i should evaluate if fix it or just change the blend_path for building
31 # only specific models
33 if exists('hash_cache.txt'):
34 with
open('hash_cache.txt') as fhash
:
35 lines
= fhash
.readlines()
36 for line
in lines
: # line's e.g. assets/path/to/gltf_or_png.ext 68ced1
37 line_spl
= line
.split()
38 hashval
= line_spl
[-1]
39 fname
= ' '.join(line_spl
[:-1])
40 if fname
not in self
._cache
_files
:
41 cache
+= [(fname
, hashval
)]
42 for cfile
in self
._cache
_files
:
43 cache
+= [(cfile
, md5(open(cfile
, 'rb').read()).hexdigest())]
45 with
open('hash_cache.txt', 'w') as fhash
:
46 fhash
.write('\n'.join([' '.join(line
) for line
in cache
]))
48 def _export_blend(self
, root
, fname
):
49 '''Exports blend files to glTF and bam formats.'''
50 if self
._export
_gltf
(root
, fname
):
51 self
._export
_bam
(root
, fname
)
53 def _export_gltf(self
, root
, fname
):
54 '''Exports glTF files from blend ones.'''
55 _fname
= '%s/%s' % (root
, fname
)
56 pgltf
= 'assets/models/gltf/'
57 new_dir
= root
.replace('assets/models/blend/', pgltf
)
58 rmtree(new_dir
, ignore_errors
=True)
60 #files_before = [basename(gname) for gname in glob('./*')]
61 cmd
= 'blender %s --background --python ya2/build/blend2gltf.py '
63 cmd
= cmd
% (_fname
, new_dir
+ '/' + fname
[:-6])
64 gltf_name
= _fname
.replace('assets/models/blend/', pgltf
)
65 gltf_name
= gltf_name
.replace('.blend', '.gltf')
66 if not to_be_built(gltf_name
, [_fname
]):
69 self
._cache
_files
+= [_fname
, gltf_name
]
70 #files_after = [basename(gname) for gname in glob('./*')]
71 #new_files = [nnm for nnm in files_after if nnm not in files_before]
72 #new_dir = root.replace('assets/models/blend/', pgltf)
73 #rmtree(new_dir, ignore_errors=True)
75 #for mname in new_files:
76 # new_name = '%s/%s' % (new_dir, mname)
77 # move(mname, new_name)
78 # info('move %s %s' % (mname, new_name))
79 # # blender rewrites metal files: let's restore them
80 # metal_files = [fnm for fnm in glob(new_dir + '/*') if 'metal' in fnm]
81 # for metal_file in metal_files:
82 # src = metal_file.replace(pgltf, 'assets/models/')
84 # src = metal_file.replace(pgltf, 'assets/models/prototypes/')
85 # src_split = src.split('/')
86 # src_tracks_idx = src_split.index('tracks')
87 # before = src_split[:src_tracks_idx]
88 # after = src_split[src_tracks_idx + 2:]
89 # src = '/'.join(before + after)
90 # copyfile(src, metal_file)
93 def _export_bam(self
, root
, fname
):
94 '''Exports bam files from glTF ones.'''
95 _fname
= '%s/%s' % (root
, fname
)
96 gltf_name
= (_fname
[:-5] + 'gltf').replace('/blend/', '/gltf/', 1)
97 bam_name
= (_fname
[:-5] + 'bam').replace('/blend/', '/bam/', 1)
98 cmd_args
= gltf_name
, bam_name
99 # use dds files in place of png/jpg in gltf2bam
100 copyfile(gltf_name
, gltf_name
+ '.tmp')
101 with
open(gltf_name
) as fgltf
:
102 lines
= fgltf
.readlines()
105 if ('.png' in line
or '.jpg' in line
) and '"uri"' in line
:
106 rln
= line
[line
.index('"uri"') + 9:].rstrip(',\n"')
107 tname
= '%s/%s' % (root
, rln
)
108 deps
+= [tname
.replace('/models/blend/', '/models/gltf/', 1)]
110 tgt
= dep
.replace('/gltf/', '/bam/', 1)
111 tgt
= tgt
.replace('.png', '.dds').replace('.jpg', '.dds')
112 makedirs(dirname(tgt
), exist_ok
=True)
113 info('convert %s %s' % (dep
, tgt
))
114 system('convert %s %s' % (dep
, tgt
))
115 rpl
= lambda lin
: lin
.replace('.png', '.dds').replace('.jpg', '.dds').replace('/png', '/dds').replace('/jpg', '/dds')
116 with
open(gltf_name
, 'w') as fgltf
:
117 fgltf
.write(''.join([rpl(line
) for line
in lines
]))
118 makedirs(dirname(bam_name
), exist_ok
=True)
119 if to_be_built(bam_name
, deps
):
120 system('gltf2bam %s %s' % cmd_args
)
121 self
._cache
_files
+= [bam_name
] + deps