969525ac4eb3bf9a7b86ec4c3bd4c7f8a89e9975
[blender-addons-contrib.git] / io_directx_bel / bel / mesh.py
1 ##\file
2 # raw extract quick cleaning from blended cities2.6 project. thanks to myself for cooperation, but what a messy code we have here.
3 import bpy
4 import mathutils
5 from mathutils import *
6
7 import bel.uv
8 import bel.ob
9
10 debuglevel = 0
11 '''
12 wip.. naming behaviour previous to any data
13 name exist ?
14 no : create
15 yes :
16     naming_method = 0   blender default (increment name)
17     naming_method = 1   do nothing, abort creation and use existing
18     naming_method = 2   create new, rename existing, 
19     naming_method = 3   create new, remove existing
20     
21 for now, and mesh data, 0 2 or 3
22 '''
23
24 ## material MUST exist before creation of material slots
25 ## map only uvmap 0 to its image defined in mat  for now (multitex view)
26 def write(obname,name, 
27           verts=[], edges=[], faces=[], 
28           matslots=[], mats=[], uvs=[], 
29           groupnames=[], vindices=[], vweights=[],
30           smooth=False,
31           naming_method = 0,
32           ) :
33
34     
35     obj = bpy.data.objects[obname] if obname in bpy.data.objects else False
36     me = bpy.data.meshes[name] if name in bpy.data.meshes else False
37
38     #print(naming_method,type(obj),type(me))
39     #print(obj,me)
40     #print()
41     if naming_method == 1 and me and obj and obj.data == me :
42         #print('%s and %s exist, reuse'%(obj.name,me.name))
43         return obj
44        
45     if naming_method == 3 :
46         if obj : 
47             #print('remove ob %s'%obj.name)
48             bel.ob.remove(obj,False)
49         if me :
50             #print('remove me %s'%me.name)
51             bel.ob.removeData(me)
52     
53
54     me = bpy.data.meshes.new(name)
55     if naming_method == 2 : me.name = name
56     
57     me.from_pydata(verts, edges, faces)
58     me.update()
59
60     if smooth : shadesmooth(me)
61     
62     # material slots
63     matimage=[]
64     if len(matslots) > 0 :
65         for matname in matslots :
66             '''
67             if matname not in bpy.data.materials :
68                 mat = bpy.data.materials.new(name=matname)
69                 mat.diffuse_color=( random.uniform(0.0,1.0),random.uniform(0.0,1.0),random.uniform(0.0,1.0))
70                 mat.use_fake_user = True
71                 warn.append('Created missing material : %s'%matname)
72             else :
73             '''
74             mat = bpy.data.materials[matname]
75             me.materials.append(mat)
76             texslot_nb = len(mat.texture_slots)
77             if texslot_nb :
78                 texslot = mat.texture_slots[0]
79                 if type(texslot) != type(None) :
80                     tex = texslot.texture
81                     if tex.type == 'IMAGE' :
82                         img = tex.image
83                         if type(img) != type(None) :
84                             matimage.append(img)
85                             continue
86             matimage.append(False)
87
88     # map a material to each face
89     if len(mats) > 0 :
90         for fi,f in enumerate(me.faces) :
91             f.material_index = mats[fi]
92
93     # uvs
94     if len(uvs) > 0 :
95         bel.uv.write(me, uvs, matimage)
96
97
98     obj = bpy.data.objects.new(name=obname, object_data=me)
99     if naming_method != 0 :
100         obj.name = obname
101             
102     '''
103     else :
104         ob = bpy.data.objects[name]
105         ob.data = me
106         if naming_method == 2 : ob.name = 
107         ob.parent = None
108         ob.matrix_local = Matrix()
109         print('  reuse object %s'%ob.name)
110     '''
111             
112     # vertexgroups
113     if len(groupnames) > 0 :
114         for gpi, groupname in enumerate(groupnames) :
115             weightsadd(obj, groupname, vindices[gpi], vweights[gpi])
116     
117     # scene link check
118     if obj.name not in bpy.context.scene.objects.keys() :
119         bpy.context.scene.objects.link(obj)
120         
121     return obj
122
123 def shadesmooth(me,lst=True) :
124     if type(lst) == list :
125         for fi in lst :
126             me.faces[fi].use_smooth = True
127     else :
128         for fi,face in enumerate(me.faces) :
129             face.use_smooth = True
130  
131 def shadeflat(me,lst=True) :
132     if type(lst) == list :
133         for fi in lst :
134             me.faces[fi].use_smooth = False
135     else :
136         for fi,face in enumerate(me.faces) :
137             face.use_smooth = False
138
139 def weightsadd(ob, groupname, vindices, vweights=False) :
140     if vweights == False : vweights = [1.0 for i in range(len(vindices))]
141     elif type(vweights) == float : vweights = [vweights for i in range(len(vindices))]
142     group = ob.vertex_groups.new(groupname)
143     for vi,v in enumerate(vindices) :
144         group.add([v], vweights[vi], 'REPLACE')
145
146 def matToString(mat) :
147     #print('*** %s %s'%(mat,type(mat)))
148     return str(mat).replace('\n       ','')[6:]
149
150 def stringToMat(string) :
151     return Matrix(eval(string))
152
153
154 def objectBuild(elm, verts, edges=[], faces=[], matslots=[], mats=[], uvs=[] ) :
155     #print('build element %s (%s)'%(elm,elm.className()))
156     dprint('object build',2)
157     city = bpy.context.scene.city
158     # apply current scale
159     verts = metersToBu(verts)
160     
161     if type(elm) != str :
162         obname = elm.objectName()
163         if obname == 'not built' :
164             obname = elm.name
165     else : obname= elm
166
167     obnew = createMeshObject(obname, True, verts, edges, faces, matslots, mats, uvs)
168     #elm.asElement().pointer = str(ob.as_pointer())
169     if type(elm) != str :
170         if elm.className() == 'outlines' :
171             obnew.lock_scale[2] = True
172             if elm.parent :
173                 obnew.parent = elm.Parent().object()
174         else :
175             #otl = elm.asOutline()
176             #ob.parent = otl.object()
177             objectLock(obnew,True)
178         #ob.matrix_local = Matrix() # not used
179         #ob.matrix_world = Matrix() # world
180     return obnew
181
182 def dprint(str,l=2) :
183     if l <= debuglevel :
184         print(str)
185
186
187 def materialsCheck(bld) :
188     if hasattr(bld,'materialslots') == False :
189         #print(bld.__class__.__name__)
190         builderclass = eval('bpy.types.%s'%(bld.__class__.__name__))
191         builderclass.materialslots=[bld.className()]
192
193     matslots = bld.materialslots
194     if len(matslots) > 0 :
195         for matname in matslots :
196             if matname not in bpy.data.materials :
197                 mat = bpy.data.materials.new(name=matname)
198                 mat.use_fake_user = True
199                 if hasattr(bld,'mat_%s'%(matname)) :
200                     method = 'defined by builder'
201                     matdef = eval('bld.mat_%s'%(matname))
202                     mat.diffuse_color = matdef['diffuse_color']
203                 else :
204                     method = 'random'
205                     mat.diffuse_color=( random.uniform(0.0,1.0),random.uniform(0.0,1.0),random.uniform(0.0,1.0))
206                 dprint('Created missing material %s (%s)'%(matname,method),2)
207
208