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