123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- # THIS FILE IS A PART OF VCStudio
- # PYTHON 3
- # BPY ( WITH IN BLENDER )
- #################################################################
- # This file is running with in Blender to link assets from their
- # AST files into the animation files. And make library overrides.
- # NOTE: It's using BPY module which is not available outside of
- # blender. So in order to test any changes to it. You have to
- # run it with in Blender. Or Using blender -P <your_script>.
- # See blender --help for details.
- #################################################################
- import bpy
- import os
- # The main problem with running from with in blender is that we
- # have no access to all the outside modules. And this script
- # will be there on it's own. So it need a way of knowing where
- # are the assets.
- blendpath = bpy.data.filepath # Animation file path
- folder = blendpath[:blendpath.rfind("/")] # Animation shot folder
- pf = folder[:folder.rfind("/rnd/")] # Project's folder
- # In order for VCStudio or Blender-Organizer to know what is going
- # on I use print(). It's not going to be outputted into terminal.
- # since we are piping everything directly into VCStudio. Which is
- # going to parse those lines to give the user some graphical feed
- # back.
- print("BLENDPATH : ", blendpath)
- print("FOLDER : ", folder)
- print("PROJECT FOLDER : ", pf)
- # Now we are going to abort the process if there is no file in the
- # shot folder that has the info about the linked data. autolink.data
- if os.path.exists(folder+"/extra/autolink.data"):
- print("FOUND AUTOLINK.DATA YEY :)")
-
-
- # Now let's parse the extra/autolink.data file
-
- df = open(folder+"/extra/autolink.data" , "r")
- df = df.read()
-
- # These 2 values will be our location in the blender space since
- # I don't think any user wants all of their assets to be in the
- # same exact spot.
-
- movey = 0
- movex = 0
-
- # We need to get our mode first. Because the user might want to
- # just link. Or make the old proxy.
- mode = "link"
- for num, line in enumerate(df.split("\n")):
- if line.startswith("Mode : "):
- mode = line[7:]
-
-
- # Let's see if there any lines that say what we want to link.
-
- for num, line in enumerate(df.split("\n")):
- if line.startswith("Link : "):
-
- # So here is out item. ( asset ). NOTE: THe item in
- # autolink.data will have /dev/ added to the begining
- # like all links in Blender-Organizer.
-
- item = line[7:]
- print("\nLINKING ITEM : "+item)
-
- # Now let's see if the asset also has an autolink.data
- # configured. Because if not. Script would not know what
- # to link.
-
- itemsdf = pf+item+"/autolink.data"
- if os.path.exists(itemsdf):
- print("FOUND "+item+"'S AUTOLINK.DATA :)")
-
- # Now let's parse the autolink.data of the asset.
-
- idf = open(itemsdf, "r")
- idf = idf.read()
-
- # We need to find 2 types of data. What collections
- # to link. Since not all of them are nessesary. And
- # whether to do library-overrides.
-
- # At the time of Blender-Organizer library-overrides
- # was still a very unstable thing. So I was going
- # proxies. Now I don't want to break backward compati-
- # bility with Blender-Organizer. So we are going to
- # read the full list of Proxies. And if they exist
- # we are going to use library override instead. So
- # keep in mind. They called proxies in the script. But
- # they are library-overrides.
-
- linkdata = [] # Lits of colletions to link
- proxydata = [] # Lits of "Proxies" so to speak.
-
- for iline in idf.split("\n"):
- if iline.startswith("Link : "):
- linkdata.append(iline[7:])
- elif iline.startswith("Proxy : "):
- proxydata.append(iline[8:])
-
- print("LINKDATA ", linkdata)
- print("PROXYDATA ", proxydata)
-
- # Okay. Now we got both lists. Let's see if there is
- # an asset blend file. Because for any reason it might
- # not exists.
-
- astblend = pf+"/ast/"+item[5:]+".blend"
- print("AST BLEND : "+astblend)
-
-
- if os.path.exists(astblend):
- print("YAY FOUND THE BLENDFILE :)")
-
- # We found our asset blend file. So now let's do
- # the linking.
-
- for collection in linkdata:
-
-
-
- print("ATTEMPTING TO LINK : "+collection)
-
- # Now let's try actually doing it.
-
- try:
- with bpy.data.libraries.load(astblend, link=True) as (data_from, data_to):
- data_to.collections = [c for c in data_from.collections if c == collection]
-
- for num2, new_coll in enumerate(data_to.collections):
-
- print("TRYING LINKING ", new_coll.name)
-
- try:
- if new_coll.name:
- instance = bpy.data.objects.new(new_coll.name, None)
- instance.instance_type = 'COLLECTION'
- instance.instance_collection = new_coll
- bpy.context.scene.collection.objects.link(instance)
- if not item[5:].startswith("loc"):
- bpy.data.objects[collection].location[1] = movey
- bpy.data.objects[collection].location[0] = movex
-
- # So here we already linked our data. And placed the
- # objects. Next we want to do library-overrides.
- if proxydata and mode == "override":
-
- # With library overrides there is one little problem.
- # It nullifies the location. Because the location is
- # now also overriden.
-
- bpy.data.objects[collection].select_set(True)
- bpy.context.view_layer.objects.active = bpy.data.objects[collection]
- bpy.ops.object.make_override_library()
-
-
- # So after we do the override we need to change the
- # location again.
-
- if not item[5:].startswith("loc"):
- bpy.data.objects[proxydata[0]].location[1] = movey
- bpy.data.objects[proxydata[0]].location[0] = movex
-
- # And while we are on it. In the Blender-Organizer
- # linker there was one inconvinience that you had
- # to hide the rig from viewport since if not you will
- # have both linked and proxy rig drawn on screen at
- # the same time. So let's unhide it.
-
- bpy.data.objects[proxydata[0]].hide_viewport = False
-
- # Also while we are here. Let's use the size of the
- # rig to offset it's location instead of 5. If the
- # rig exists.
-
-
-
- movey = movey + bpy.data.objects[proxydata[0]].dimensions.y+1
- if movey > 25:
- movey = 0
- movex = movex + 5
-
- elif proxydata and mode == "proxy":
-
- # Now the used could select to do it the old way.
- # using a proxy. Then this is the way.
- for proxymake in proxydata:
- print("TRYING PROXING ", proxymake)
-
- try:
-
- ob = bpy.context.scene.objects[new_coll.name]
- ob.select_set(True)
- bpy.context.view_layer.objects.active = ob
- bpy.ops.object.proxy_make(object=proxymake)
- except Exception as e:
- print("PROXY FAILED ", proxymake)
- print(e, "ERROR IN PROXY")
-
- movey = movey + 5
- if movey > 25:
- movey = 0
- movex = movex + 5
-
- else:
-
- # If ther is no library - override enabled. The instance
- # empty has a size of 0. So this same dimension thing
- # would not work here. :(. I might come up with something
- # later.
-
- movey = movey + 5
- if movey > 25:
- movey = 0
- movex = movex + 5
-
- # Now I want to save the file. BUT. In the old way of
- # doing it I made a mistake to save without checking
- # that all paths should be RELATIVE. And so copying the
- # project to another computer bloke all the files.
-
- bpy.ops.file.make_paths_relative()
- bpy.ops.wm.save_mainfile()
-
- # So ther is 2 line now when saving.
-
- # Now I'd like to print out the current fraction of
- # the linking progress done. So I could make a progress
- # bar in the VCStudio.
-
- print("FRACTION:", (num+1)/len(df.split("\n")))
-
- except Exception as e:
- print(e, "ERROR IN LINING")
- except Exception as e:
- print(e, "ERROR IN GENERAL")
-
-
- else:
- print("NO BLENDFILE DOEN'T EXIST :(")
-
-
- else:
- print("NO "+item+"'S AUTOLINK.DATA :(")
-
-
- else:
- print("NO AUTOLINK.DATA SORRY :(")
- print("FINISHED")
|