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