Newer
Older
# SPDX-License-Identifier: GPL-2.0-or-later
"name": "3D-Coat Applink",
"author": "Kalle-Samuli Riihikoski (haikalle)",
"location": "Scene > 3D-Coat Applink",
"description": "Transfer data between 3D-Coat/Blender",
"warning": "",
"doc_url": "{BLENDER_MANUAL_URL}/addons/import_export/coat3D.html",
"category": "Import-Export",
import importlib
importlib.reload(tex)
from bpy.app.handlers import persistent
from io_coat3D import folders
from bpy.types import PropertyGroup
from bpy.props import (
BoolProperty,
EnumProperty,
FloatVectorProperty,
StringProperty,
PointerProperty,
)
global_exchange_folder = ''
liveUpdate = True
mTime = 0
@persistent
def every_3_seconds():
global global_exchange_folder
global liveUpdate
global mTime
global only_one_time
if(only_one_time):
only_one_time = False
folders.loadExchangeFolder()
try:
coat3D = bpy.context.scene.coat3D
Export_folder = coat3D.exchangeFolder
Export_folder += ('%sexport.txt' % (os.sep))
if (os.path.isfile(Export_folder) and mTime != os.path.getmtime(Export_folder)):
for objekti in bpy.data.objects:
if(objekti.coat3D.applink_mesh):
tex.updatetextures(objekti)
mTime = os.path.getmtime(Export_folder)
except:
pass
return 3.0
@persistent
def load_handler(dummy):
bpy.app.timers.register(every_3_seconds)
def removeFile(exportfile):
if (os.path.isfile(exportfile)):
os.remove(exportfile)
def folder_size(path):
Kalle-Samuli Riihikoski
committed
folder_size_max = int(bpy.context.scene.coat3D.folder_size)
if(bpy.context.scene.coat3D.defaultfolder == ''):
tosi = True
while tosi:
list_of_files = []
for file in os.listdir(path):
list_of_files.append(path + os.sep + file)
if len(list_of_files) >= folder_size_max:
oldest_file = min(list_of_files, key=os.path.getctime)
os.remove(os.path.abspath(oldest_file))
else:
tosi = False
def make_texture_list(texturefolder):
texturefolder += ('%stextures.txt'%(os.sep))
texturelist = []
if (os.path.isfile(texturefolder)):
texturefile = open(texturefolder)
index = 0
for line in texturefile:
if line != '' and index == 0:
objekti = line
index += 1
elif index == 1:
material = line
index += 1
elif index == 2:
type = line
index += 1
elif index == 3:
address = line
texturelist.append([objekti,material,type,address])
index = 0
texturefile.close()
return texturelist
#Updating objects MESH part ( Mesh, Vertex Groups, Vertex Colors )
Kalle-Samuli Riihikoski
committed
def updatemesh(objekti, proxy, texturelist):
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# Vertex colors
if(len(proxy.data.vertex_colors) > 0):
bring_vertex_map = True
else:
bring_vertex_map = False
if(bring_vertex_map):
if(len(objekti.data.vertex_colors) > 0):
for vertex_map in objekti.data.vertex_colors:
if vertex_map.name == 'Col':
copy_data = True
vertex_map_copy = vertex_map
break
else:
copy_data = False
else:
copy_data = False
if(copy_data):
for poly in objekti.data.polygons:
for loop_index in poly.loop_indices:
vertex_map_copy.data[loop_index].color = proxy.data.vertex_colors[0].data[loop_index].color
else:
objekti.data.vertex_colors.new()
vertex_map_copy = objekti.data.vertex_colors[-1]
for poly in objekti.data.polygons:
for loop_index in poly.loop_indices:
vertex_map_copy.data[loop_index].color = proxy.data.vertex_colors[0].data[loop_index].color
# UV -Sets
Kalle-Samuli Riihikoski
committed
udim_textures = False
Kalle-Samuli Riihikoski
committed
if(texturelist != []):
if(texturelist[0][0].startswith('100')):
udim_textures =True
Kalle-Samuli Riihikoski
committed
proxy.select_set(True)
objekti.select_set(True)
Kalle-Samuli Riihikoski
committed
uv_count = len(proxy.data.uv_layers)
index = 0
while(index < uv_count and len(proxy.data.polygons) == len(objekti.data.polygons)):
Kalle-Samuli Riihikoski
committed
for poly in proxy.data.polygons:
for indi in poly.loop_indices:
if(proxy.data.uv_layers[index].data[indi].uv[0] != 0 and proxy.data.uv_layers[index].data[indi].uv[1] != 0):
Kalle-Samuli Riihikoski
committed
if(udim_textures):
udim = proxy.data.uv_layers[index].name
udim_index = int(udim[2:]) - 1
Kalle-Samuli Riihikoski
committed
objekti.data.uv_layers[0].data[indi].uv[0] = proxy.data.uv_layers[index].data[indi].uv[0]
objekti.data.uv_layers[0].data[indi].uv[1] = proxy.data.uv_layers[index].data[indi].uv[1]
Kalle-Samuli Riihikoski
committed
index = index + 1
# Mesh Copy
Kalle-Samuli Riihikoski
committed
if(proxy.name.startswith('RetopoGroup')):
objekti.data = proxy.data
else:
for ind, v in enumerate(objekti.data.vertices):
v.co = proxy.data.vertices[ind].co
class SCENE_OT_getback(bpy.types.Operator):
bl_idname = "getback.pilgway_3d_coat"
bl_label = "Export your custom property"
bl_description = "Export your custom property"
bl_options = {'UNDO'}
global global_exchange_folder
path_ex = ''
Export_folder = global_exchange_folder
Blender_folder = os.path.join(Export_folder, 'Blender')
BlenderFolder = Blender_folder
ExportFolder = Export_folder
Blender_folder += ('%sexport.txt' % (os.sep))
Export_folder += ('%sexport.txt' % (os.sep))
if (bpy.app.background == False):
if os.path.isfile(Export_folder):
print('BLENDER -> 3DC -> BLENDER WORKFLLOW')
workflow1(ExportFolder)
removeFile(Export_folder)
elif os.path.isfile(Blender_folder):
print('3DC -> BLENDER WORKFLLOW')
workflow2(BlenderFolder)
removeFile(Blender_folder)
return {'FINISHED'}
class SCENE_OT_savenew(bpy.types.Operator):
bl_idname = "save_new_export.pilgway_3d_coat"
bl_label = "Export your custom property"
bl_description = "Export your custom property"
bl_options = {'UNDO'}
def invoke(self, context, event):
coat3D = bpy.context.scene.coat3D
platform = os.sys.platform
if(platform == 'win32' or platform == 'darwin'):
exchangeFile = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3DC2Blender' + os.sep + 'Exchange_folder.txt'
else:
exchangeFile = os.path.expanduser("~") + os.sep + '3DC2Blender' + os.sep + 'Exchange_folder.txt'
if(os.path.isfile(exchangeFile)):
folderPath = ''
if(os.path.isfile(exchangeFile)):
file = open(exchangeFile, "w")
file.write("%s"%(coat3D.exchangeFolder))
return {'FINISHED'}
class SCENE_OT_folder(bpy.types.Operator):
bl_idname = "update_exchange_folder.pilgway_3d_coat"
bl_label = "Export your custom property"
bl_description = "Export your custom property"
bl_options = {'UNDO'}
def invoke(self, context, event):
coat3D = bpy.context.scene.coat3D
if(os.path.isdir(coat3D.exchangeFolder)):
folders.updateExchangeFile(coat3D.exchangeFolder)
return {'FINISHED'}
class SCENE_OT_opencoat(bpy.types.Operator):
bl_idname = "open_3dcoat.pilgway_3d_coat"
bl_label = "Export your custom property"
bl_description = "Export your custom property"
bl_options = {'UNDO'}
def invoke(self, context, event):
coat3D = bpy.context.selected_objects[0].coat3D.applink_3b_path
if (platform == 'win32' or platform == 'darwin'):
importfile = bpy.context.scene.coat3D.exchangeFolder
importfile += ('%simport.txt' % (os.sep))
file = open(importfile, "w")
file.write("%s" % (coat3D))
file.write("\n%s" % (coat3D))
file.write("\n[3B]")
file.close()
else:
importfile = bpy.context.scene.coat3D.exchangeFolder
importfile += ('%simport.txt' % (os.sep))
file = open(importfile, "w")
file.write("%s" % (coat3D))
file.write("\n%s" % (coat3D))
file.write("\n[3B]")
file.close()
def scaleParents():
save = []
names =[]
for objekti in bpy.context.selected_objects:
temp = objekti
while (temp.parent is not None and temp.parent.name not in names):
save.append([temp.parent,(temp.parent.scale[0],temp.parent.scale[1],temp.parent.scale[2])])
names.append(temp.parent)
temp = temp.parent
for name in names:
name.scale = (1,1,1)
return save
def scaleBackParents(save):
for data in save:
data[0].scale = data[1]
Kalle-Samuli Riihikoski
committed
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
def deleteNodes(type):
deletelist = []
deleteimages = []
deletegroup =[]
delete_images = bpy.context.scene.coat3D.delete_images
if type == 'Material':
if(len(bpy.context.selected_objects) == 1):
material = bpy.context.selected_objects[0].active_material
if(material.use_nodes):
for node in material.node_tree.nodes:
if(node.name.startswith('3DC')):
if (node.type == 'GROUP'):
deletegroup.append(node.node_tree.name)
deletelist.append(node.name)
if node.type == 'TEX_IMAGE' and delete_images == True:
deleteimages.append(node.image.name)
if deletelist:
for node in deletelist:
material.node_tree.nodes.remove(material.node_tree.nodes[node])
if deleteimages:
for image in deleteimages:
bpy.data.images.remove(bpy.data.images[image])
elif type == 'Object':
if (len(bpy.context.selected_objects) > 0):
for objekti in bpy.context.selected_objects:
for material in objekti.material_slots:
if (material.material.use_nodes):
for node in material.material.node_tree.nodes:
if (node.name.startswith('3DC')):
if(node.type == 'GROUP'):
deletegroup.append(node.node_tree.name)
deletelist.append(node.name)
if node.type == 'TEX_IMAGE' and delete_images == True:
deleteimages.append(node.image.name)
if deletelist:
for node in deletelist:
material.material.node_tree.nodes.remove(material.material.node_tree.nodes[node])
deletelist = []
if deleteimages:
for image in deleteimages:
bpy.data.images.remove(bpy.data.images[image])
deleteimages = []
elif type == 'Collection':
for collection_object in bpy.context.view_layer.active_layer_collection.collection.all_objects:
if(collection_object.type == 'MESH'):
for material in collection_object.material_slots:
if (material.material.use_nodes):
for node in material.material.node_tree.nodes:
if (node.name.startswith('3DC')):
if (node.type == 'GROUP'):
deletegroup.append(node.node_tree.name)
deletelist.append(node.name)
if node.type == 'TEX_IMAGE' and delete_images == True:
deleteimages.append(node.image.name)
if deletelist:
for node in deletelist:
material.material.node_tree.nodes.remove(material.material.node_tree.nodes[node])
deletelist = []
if deleteimages:
for image in deleteimages:
bpy.data.images.remove(bpy.data.images[image])
deleteimages = []
elif type == 'Scene':
for collection in bpy.data.collections:
for collection_object in collection.all_objects:
if (collection_object.type == 'MESH'):
for material in collection_object.material_slots:
if (material.material.use_nodes):
for node in material.material.node_tree.nodes:
if (node.name.startswith('3DC')):
if (node.type == 'GROUP'):
deletegroup.append(node.node_tree.name)
deletelist.append(node.name)
if node.type == 'TEX_IMAGE' and delete_images == True:
deleteimages.append(node.image.name)
if deletelist:
for node in deletelist:
material.material.node_tree.nodes.remove(material.material.node_tree.nodes[node])
deletelist = []
if deleteimages:
for image in deleteimages:
bpy.data.images.remove(bpy.data.images[image])
deleteimages = []
if(deletelist):
for node in deletelist:
bpy.data.node_groups.remove(bpy.data.node_groups[node])
for image in bpy.data.images:
if (image.name.startswith('3DC') and image.name[6] == '_'):
deleteimages.append(image.name)
if(deletegroup):
for node in deletegroup:
bpy.data.node_groups.remove(bpy.data.node_groups[node])
if deleteimages:
for image in deleteimages:
bpy.data.images.remove(bpy.data.images[image])
def delete_materials_from_end(keep_materials_count, objekti):
#bpy.context.object.active_material_index = 0
index_t = 0
while (index_t < keep_materials_count):
temp_len = len(objekti.material_slots)-1
bpy.context.object.active_material_index = temp_len
bpy.ops.object.material_slot_remove()
index_t +=1
Kalle-Samuli Riihikoski
committed
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
''' DELETE NODES BUTTONS'''
class SCENE_OT_delete_material_nodes(bpy.types.Operator):
bl_idname = "delete_material_nodes.pilgway_3d_coat"
bl_label = "Delete material nodes"
bl_description = "Delete material nodes"
bl_options = {'UNDO'}
def invoke(self, context, event):
type = bpy.context.scene.coat3D.deleteMode = 'Material'
deleteNodes(type)
return {'FINISHED'}
class SCENE_OT_delete_object_nodes(bpy.types.Operator):
bl_idname = "delete_object_nodes.pilgway_3d_coat"
bl_label = "Delete material nodes"
bl_description = "Delete material nodes"
bl_options = {'UNDO'}
def invoke(self, context, event):
type = bpy.context.scene.coat3D.deleteMode = 'Object'
deleteNodes(type)
return {'FINISHED'}
class SCENE_OT_delete_collection_nodes(bpy.types.Operator):
bl_idname = "delete_collection_nodes.pilgway_3d_coat"
bl_label = "Delete material nodes"
bl_description = "Delete material nodes"
bl_options = {'UNDO'}
def invoke(self, context, event):
type = bpy.context.scene.coat3D.deleteMode = 'Collection'
deleteNodes(type)
return {'FINISHED'}
class SCENE_OT_delete_scene_nodes(bpy.types.Operator):
bl_idname = "delete_scene_nodes.pilgway_3d_coat"
bl_label = "Delete material nodes"
bl_description = "Delete material nodes"
bl_options = {'UNDO'}
def invoke(self, context, event):
type = bpy.context.scene.coat3D.deleteMode = 'Scene'
deleteNodes(type)
return {'FINISHED'}
''' TRANSFER AND UPDATE BUTTONS'''
class SCENE_OT_export(bpy.types.Operator):
bl_idname = "export_applink.pilgway_3d_coat"
bl_label = "Export your custom property"
bl_description = "Export your custom property"
bl_options = {'UNDO'}
def invoke(self, context, event):
bpy.ops.export_applink.pilgway_3d_coat()
return {'FINISHED'}
def execute(self, context):
global global_exchange_folder
global run_background_update
run_background_update = False
foundExchangeFolder, global_exchange_folder = folders.InitFolders()
if (mesh.users == 0 and mesh.coat3D.name == '3DC'):
bpy.data.meshes.remove(mesh)
for material in bpy.data.materials:
if (material.users == 1 and material.coat3D.name == '3DC'):
coat3D = bpy.context.scene.coat3D
if (bpy.context.selected_objects == []):
return {'FINISHED'}
else:
for objec in bpy.context.selected_objects:
if objec.type == 'MESH':
if(len(objec.data.uv_layers) == 0):
objec.data.uv_layers.new(name='UVMap', do_init = False)
if (export_ok == False):
scaled_objects = scaleParents()
activeobj = bpy.context.active_object.name
checkname = ''
coa = bpy.context.active_object.coat3D
p = pathlib.Path(coat3D.exchangeFolder)
kokeilu = coat3D.exchangeFolder[:-9]
Blender_folder2 = ("%s%sExchange" % (kokeilu, os.sep))
Blender_folder2 += ('%sexport.txt' % (os.sep))
if (os.path.isfile(Blender_folder2)):
os.remove(Blender_folder2)
if (not os.path.isdir(coat3D.exchangeFolder)):
coat3D.exchange_found = False
return {'FINISHED'}
folder_objects = folders.set_working_folders()
folder_size(folder_objects)
importfile = coat3D.exchangeFolder
texturefile = coat3D.exchangeFolder
importfile += ('%simport.txt'%(os.sep))
texturefile += ('%stextures.txt'%(os.sep))
looking = True
object_index = 0
active_render = bpy.context.scene.render.engine
if(coat3D.type == 'autopo'):
checkname = folder_objects + os.sep
checkname = ("%sretopo.fbx" % (checkname))
elif(coat3D.type == 'update'):
checkname = bpy.context.selected_objects[0].coat3D.applink_address
else:
while(looking == True):
checkname = folder_objects + os.sep + "3DC"
checkname = ("%s%.3d.fbx"%(checkname,object_index))
if(os.path.isfile(checkname)):
object_index += 1
else:
looking = False
coa.applink_name = ("%s%.2d"%(activeobj,object_index))
coa.applink_address = checkname
for objekti in bpy.context.selected_objects:
if objekti.type == 'MESH':
objekti.name = '__' + objekti.name
if(objekti.material_slots.keys() == []):
newmat = bpy.data.materials.new('Material')
newmat.use_nodes = True
objekti.data.materials.append(newmat)
matindex += 1
objekti.coat3D.applink_name = objekti.name
bake_location = folder_objects + os.sep + 'Bake'
if (os.path.isdir(bake_location)):
shutil.rmtree(bake_location)
os.makedirs(bake_location)
else:
os.makedirs(bake_location)
# BAKING #
for objekti in bpy.context.selected_objects:
if objekti.type == 'MESH':
mod_mat_list[objekti.name] = []
objekti.coat3D.applink_scale = objekti.scale
objekti.coat3D.retopo = False
''' Checks what materials are linked into UV '''
if(coat3D.type == 'ppp'):
final_material_indexs = []
uvtiles_index = []
for poly in objekti.data.polygons:
if(poly.material_index not in final_material_indexs):
final_material_indexs.append(poly.material_index)
loop_index = poly.loop_indices[0]
uvtiles_index.append([poly.material_index,objekti.data.uv_layers.active.data[loop_index].uv[0]])
if(len(final_material_indexs) == len(objekti.material_slots)):
break
material_index = 0
if (len(final_material_indexs) != len(objekti.material_slots)):
for material in objekti.material_slots:
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
if material_index not in final_material_indexs:
temp_mat = material.material
material.material = objekti.material_slots[0].material
mod_mat_list[objekti.name].append([material_index, temp_mat])
material_index = material_index + 1
bake_list = []
if(coat3D.bake_diffuse):
bake_list.append(['DIFFUSE', '$LOADTEX'])
if (coat3D.bake_ao):
bake_list.append(['AO', '$ExternalAO'])
if (coat3D.bake_normal):
bake_list.append(['NORMAL', '$LOADLOPOLYTANG'])
if (coat3D.bake_roughness):
bake_list.append(['ROUGHNESS', '$LOADROUGHNESS'])
if(coat3D.bake_resolution == 'res_64'):
res_size = 64
elif (coat3D.bake_resolution == 'res_128'):
res_size = 128
elif (coat3D.bake_resolution == 'res_256'):
res_size = 256
elif (coat3D.bake_resolution == 'res_512'):
res_size = 512
elif (coat3D.bake_resolution == 'res_1024'):
res_size = 1024
elif (coat3D.bake_resolution == 'res_2048'):
res_size = 2048
elif (coat3D.bake_resolution == 'res_4096'):
res_size = 4096
elif (coat3D.bake_resolution == 'res_8192'):
res_size = 8192
if(len(bake_list) > 0):
index_bake_tex = 0
while(index_bake_tex < len(bake_list)):
bake_index = 0
for bake_mat_index in final_material_indexs:
bake_node = objekti.material_slots[bake_mat_index].material.node_tree.nodes.new('ShaderNodeTexImage')
bake_node.name = 'ApplinkBake' + str(bake_index)
bpy.ops.image.new(name=bake_node.name, width=res_size, height=res_size)
bake_node.image = bpy.data.images[bake_node.name]
objekti.material_slots[bake_mat_index].material.node_tree.nodes.active = bake_node
bake_index += 1
if(bpy.context.scene.render.engine != 'CYCLES'):
bpy.context.scene.render.engine = 'CYCLES'
bpy.context.scene.render.bake.use_pass_direct = False
bpy.context.scene.render.bake.use_pass_indirect = False
bpy.context.scene.render.bake.use_pass_color = True
bpy.ops.object.bake(type=bake_list[index_bake_tex][0], margin=1, width=res_size, height=res_size)
bake_index = 0
for bake_mat_index in final_material_indexs:
bake_image = 'ApplinkBake' + str(bake_index)
bpy.data.images[bake_image].filepath_raw = bake_location + os.sep + objekti.name + '_' + bake_image + '_' + bake_list[index_bake_tex][0] + ".png"
image_bake_name = bpy.data.images[bake_image].filepath_raw
tie = image_bake_name.split(os.sep)
toi = ''
for sana in tie:
toi += sana
toi += "/"
final_bake_name = toi[:-1]
bpy.data.images[bake_image].save()
temp_string += '''\n[script ImportTexture("''' + bake_list[index_bake_tex][1] + '''","''' + objekti.material_slots[bake_mat_index].material.name + '''","''' + final_bake_name + '''");]'''
bake_index += 1
for material in objekti.material_slots:
if material.material.use_nodes == True:
for node in material.material.node_tree.nodes:
if (node.name.startswith('ApplinkBake') == True):
material.material.node_tree.nodes.remove(node)
for image in bpy.data.images:
if (image.name.startswith('ApplinkBake') == True):
bpy.data.images.remove(image)
index_bake_tex += 1
#BAKING ENDS
#bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
if(len(bpy.context.selected_objects) > 1 and coat3D.type != 'vox'):
bpy.ops.object.transforms_to_deltas(mode='ROT')
if(coat3D.type == 'autopo'):
coat3D.bring_retopo = True
coat3D.bring_retopo_path = checkname
bpy.ops.export_scene.fbx(filepath=checkname, global_scale = 1, use_selection=True, use_mesh_modifiers=coat3D.exportmod, axis_forward='-Z', axis_up='Y')
elif (coat3D.type == 'vox'):
coat3D.bring_retopo = False
bpy.ops.export_scene.fbx(filepath=coa.applink_address, global_scale = 0.01, use_selection=True,
use_mesh_modifiers=coat3D.exportmod, axis_forward='-Z', axis_up='Y')
bpy.ops.export_scene.fbx(filepath=coa.applink_address,global_scale = 0.01, use_selection=True, use_mesh_modifiers=coat3D.exportmod, axis_forward='-Z', axis_up='Y')
file = open(importfile, "w")
file.write("%s"%(checkname))
file.write("\n%s"%(checkname))
file.write("\n[%s]"%(coat3D.type))
if(coat3D.type == 'ppp' or coat3D.type == 'mv' or coat3D.type == 'ptex'):
file.write("\n[export_preset Blender Cycles]")
file.write(temp_string)
for idx, objekti in enumerate(bpy.context.selected_objects):
if objekti.type == 'MESH':
objekti.name = objekti.name[2:]
if(len(bpy.context.selected_objects) == 1):
objekti.coat3D.applink_onlyone = True
objekti.coat3D.type = coat3D.type
objekti.coat3D.applink_mesh = True
objekti.coat3D.obj_mat = ''
objekti.coat3D.applink_index = ("3DC%.3d" % (object_index))
objekti.coat3D.applink_firsttime = True
if(coat3D.type != 'autopo'):
objekti.coat3D.applink_address = coa.applink_address
objekti.coat3D.objecttime = str(os.path.getmtime(objekti.coat3D.applink_address))
objekti.data.coat3D.name = '3DC'
if(coat3D.type != 'vox'):
if(objekti.material_slots.keys() != []):
for material in objekti.material_slots:
if material.material.use_nodes == True:
for node in material.material.node_tree.nodes:
if(node.name.startswith('3DC_') == True):
material.material.node_tree.nodes.remove(node)
for ind, mat_list in enumerate(mod_mat_list):
if(mat_list == '__' + objekti.name):
for ind, mat in enumerate(mod_mat_list[mat_list]):
objekti.material_slots[mod_mat_list[mat_list][ind][0]].material = mod_mat_list[mat_list][ind][1]
scaleBackParents(scaled_objects)
bpy.context.scene.render.engine = active_render
return {'FINISHED'}
def DeleteExtra3DC():
for node_group in bpy.data.node_groups:
if(node_group.users == 0):
bpy.data.node_groups.remove(node_group)
for mesh in bpy.data.meshes:
if(mesh.users == 0 and mesh.coat3D.name == '3DC'):
bpy.data.meshes.remove(mesh)
for material in bpy.data.materials:
img_list = []
if (material.users == 1 and material.coat3D.name == '3DC'):
if material.use_nodes == True:
for node in material.node_tree.nodes:
if node.type == 'TEX_IMAGE' and node.name.startswith('3DC'):
img_list.append(node.image)
if img_list != []:
for del_img in img_list:
bpy.data.images.remove(del_img)
bpy.data.materials.remove(material)
image_del_list = []
for image in bpy.data.images:
if (image.name.startswith('3DC')):
if image.users == 0:
image_del_list.append(image.name)
if (image_del_list != []):
for image in image_del_list:
bpy.data.images.remove(bpy.data.images[image])
def new_ref_function(new_applink_address, nimi):
create_collection = True
for collection in bpy.data.collections:
if collection.name == 'Applink_Objects':
create_collection = False
if create_collection:
bpy.data.collections.new('Applink_Objects')
coll_items = bpy.context.scene.collection.children.items()
add_applink_collection = True
for coll in coll_items:
if coll[0] == 'Applink_Objects':
add_applink_collection = False
if add_applink_collection:
bpy.context.scene.collection.children.link(bpy.data.collections['Applink_Objects'])
Kalle-Samuli Riihikoski
committed
bpy.context.view_layer.active_layer_collection = bpy.context.view_layer.layer_collection.children['Applink_Objects']
Kalle-Samuli Riihikoski
committed
old_objects = bpy.data.objects.keys()
object_list = []
bpy.ops.import_scene.fbx(filepath=new_applink_address, global_scale = 0.01,axis_forward='X', axis_up='Y',use_custom_normals=False)
new_objects = bpy.data.objects.keys()
diff_objects = [i for i in new_objects if i not in old_objects]
texturelist = []
for diff_object in diff_objects:
refmesh = bpy.data.objects[nimi]
copymesh = bpy.data.objects[nimi].copy()
copymesh.data = bpy.data.objects[diff_object].data
copymesh.coat3D.applink_name = bpy.data.objects[diff_object].data.name
copymesh.coat3D.applink_address = refmesh.coat3D.applink_address
ne_name = bpy.data.objects[diff_object].data.name
copymesh.coat3D.type = 'ppp'
copymesh.coat3D.retopo = True
bpy.data.collections['Applink_Objects'].objects.link(copymesh)
Kalle-Samuli Riihikoski
committed
bpy.data.objects.remove(bpy.data.objects[diff_object])
bpy.ops.object.select_all(action='DESELECT')
copymesh.select_set(True)
copymesh.delta_rotation_euler[0] = 1.5708
copymesh.name = ne_name
normal_node = copymesh.material_slots[0].material.node_tree.nodes['Normal Map']
copymesh.material_slots[0].material.node_tree.nodes.remove(normal_node)
copymesh.material_slots[0].material.node_tree.nodes['Principled BSDF'].inputs['Metallic'].default_value = 0
copymesh.material_slots[0].material.node_tree.nodes['Principled BSDF'].inputs['Specular'].default_value = 0.5
Kalle-Samuli Riihikoski
committed
refmesh.coat3D.applink_name = ''
refmesh.coat3D.applink_address = ''
refmesh.coat3D.type = ''
copymesh.scale = (1,1,1)
copymesh.coat3D.applink_scale = (1,1,1)
copymesh.location = (0,0,0)
copymesh.rotation_euler = (0,0,0)
def blender_3DC_blender(texturelist, file_applink_address):
coat3D = bpy.context.scene.coat3D
old_materials = bpy.data.materials.keys()
old_objects = bpy.data.objects.keys()
cache_base = bpy.data.objects.keys()
object_list = []
import_list = []
import_type = []
Kalle-Samuli Riihikoski
committed
for objekti in bpy.data.objects:
if objekti.type == 'MESH' and objekti.coat3D.applink_address == file_applink_address:
obj_coat = objekti.coat3D
object_list.append(objekti.name)
if(os.path.isfile(obj_coat.applink_address)):
if (obj_coat.objecttime != str(os.path.getmtime(obj_coat.applink_address))):
obj_coat.dime = objekti.dimensions
obj_coat.import_mesh = True
obj_coat.objecttime = str(os.path.getmtime(obj_coat.applink_address))
if(obj_coat.applink_address not in import_list):
import_list.append(obj_coat.applink_address)
import_type.append(coat3D.type)
Kalle-Samuli Riihikoski
committed
if(import_list or coat3D.importmesh):
for idx, list in enumerate(import_list):
Kalle-Samuli Riihikoski
committed
bpy.ops.import_scene.fbx(filepath=list, global_scale = 0.01,axis_forward='X',use_custom_normals=False)
cache_objects = bpy.data.objects.keys()
cache_objects = [i for i in cache_objects if i not in cache_base]
for cache_object in cache_objects:
bpy.data.objects[cache_object].coat3D.type = import_type[idx]
bpy.data.objects[cache_object].coat3D.applink_address = list
cache_base.append(cache_object)
bpy.ops.object.select_all(action='DESELECT')
new_materials = bpy.data.materials.keys()
new_objects = bpy.data.objects.keys()
Kalle-Samuli Riihikoski
committed
diff_mat = [i for i in new_materials if i not in old_materials]
diff_objects = [i for i in new_objects if i not in old_objects]
for mark_mesh in diff_objects:
bpy.data.objects[mark_mesh].data.coat3D.name = '3DC'
for c_index in diff_mat:
bpy.data.materials.remove(bpy.data.materials[c_index])
Kalle-Samuli Riihikoski
committed
'''The main Applink Object Loop'''
Kalle-Samuli Riihikoski
committed
for oname in object_list:
objekti = bpy.data.objects[oname]
if(objekti.coat3D.applink_mesh == True):
path3b_n = coat3D.exchangeFolder
path3b_n += ('%slast_saved_3b_file.txt' % (os.sep))
Kalle-Samuli Riihikoski
committed
if(objekti.coat3D.import_mesh and coat3D.importmesh == True):
Kalle-Samuli Riihikoski
committed
objekti.coat3D.import_mesh = False
objekti.select_set(True)
use_smooth = objekti.data.polygons[0].use_smooth
found_obj = False
'''Changes objects mesh into proxy mesh'''
if(objekti.coat3D.type != 'ref'):
for proxy_objects in diff_objects:
if(objekti.coat3D.retopo == False):
if (proxy_objects == objekti.coat3D.applink_name):
obj_proxy = bpy.data.objects[proxy_objects]
obj_proxy.coat3D.delete_proxy_mesh = True
found_obj = True
Kalle-Samuli Riihikoski
committed
else:
if (proxy_objects == objekti.coat3D.applink_name + '.001'):
obj_proxy = bpy.data.objects[proxy_objects]
obj_proxy.coat3D.delete_proxy_mesh = True
found_obj = True
mat_list = []
if (objekti.material_slots):
for obj_mat in objekti.material_slots:
mat_list.append(obj_mat.material)
if(found_obj == True):
exportfile = coat3D.exchangeFolder
path3b_n = coat3D.exchangeFolder
path3b_n += ('%slast_saved_3b_file.txt' % (os.sep))
exportfile += ('%sBlender' % (os.sep))
exportfile += ('%sexport.txt'%(os.sep))
if(os.path.isfile(exportfile)):
export_file = open(exportfile)
export_file.close()
os.remove(exportfile)
if(os.path.isfile(path3b_n)):
mesh_time = os.path.getmtime(objekti.coat3D.applink_address)
b_time = os.path.getmtime(path3b_n)
if (abs(mesh_time - b_time) < 240):
export_file = open(path3b_n)
for line in export_file:
objekti.coat3D.applink_3b_path = line
head, tail = os.path.split(line)
just_3b_name = tail
objekti.coat3D.applink_3b_just_name = just_3b_name
export_file.close()
coat3D.remove_path = True