Upload files to 'studio'
This commit is contained in:
parent
238d27ce86
commit
a09b61c000
9 changed files with 1864 additions and 45 deletions
266
studio/bpy_do_linking.py
Normal file
266
studio/bpy_do_linking.py
Normal file
|
@ -0,0 +1,266 @@
|
||||||
|
# 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")
|
63
studio/bpy_get_blend_content.py
Normal file
63
studio/bpy_get_blend_content.py
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
# THIS FILE IS A PART OF VCStudio
|
||||||
|
# PYTHON 3
|
||||||
|
# BPY ( WITH IN BLENDER )
|
||||||
|
|
||||||
|
#################################################################
|
||||||
|
|
||||||
|
# This file is running with in Blender to link get data from blend
|
||||||
|
# files about their contents.
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# Basically I want to have 3 types of data.
|
||||||
|
|
||||||
|
# 0. What collections does the blend file has.
|
||||||
|
# 1. What objects does the blend file has. And in what collection are they.
|
||||||
|
# 2. Whether those objects are armatures. Or in other words what types are
|
||||||
|
# these objects.
|
||||||
|
|
||||||
|
# It's not going to work on pre 2.80 blenders. So there is this try.
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
# Now let's look through all the collections that the blend file has.
|
||||||
|
|
||||||
|
for n, i in enumerate(bpy.data.collections):
|
||||||
|
|
||||||
|
# Then I want to know whether in this collection are any objects.
|
||||||
|
foundobj = False
|
||||||
|
|
||||||
|
# So let's try itterating through the object os the collection.
|
||||||
|
|
||||||
|
for nn, b in enumerate(i.objects):
|
||||||
|
|
||||||
|
# If we found enything there is this.
|
||||||
|
foundobj = True
|
||||||
|
print( ">>>", i.name, "<==" ,b.name, "<==" ,b.data)
|
||||||
|
|
||||||
|
# Now some scenes have terribly huge amount of
|
||||||
|
# stuff in there. This is why I break early.
|
||||||
|
# Now this value probably should be done using a
|
||||||
|
# setting in the UI somewhere. I'm not sure how
|
||||||
|
# to do it yet. So yeah.
|
||||||
|
|
||||||
|
if nn > 200:
|
||||||
|
print("BROKEN AFTER", b.name)
|
||||||
|
break
|
||||||
|
|
||||||
|
if not foundobj:
|
||||||
|
print( ">>>", i.name)
|
||||||
|
|
||||||
|
#if n > 300:
|
||||||
|
# break
|
||||||
|
|
||||||
|
print ("VERSION = SUCCESS")
|
||||||
|
except:
|
||||||
|
print("ERROR")
|
|
@ -262,6 +262,33 @@ def layer(win):
|
||||||
0,
|
0,
|
||||||
10)
|
10)
|
||||||
|
|
||||||
|
# Before search. On the other side when you have done the asset there will
|
||||||
|
# be a little configure icon. This is configuration for linking. Creating
|
||||||
|
# the /ast/ blend.file and autolink.data file. So the linker could link
|
||||||
|
# the files into the animation scene.
|
||||||
|
#
|
||||||
|
# See:
|
||||||
|
# studio/studio_shot_linkLayer.py
|
||||||
|
# studio/bpy_do_linking.py
|
||||||
|
# studio/studio_asset_configureLayer.py
|
||||||
|
|
||||||
|
def do():
|
||||||
|
|
||||||
|
def after(win, var):
|
||||||
|
print(var)
|
||||||
|
|
||||||
|
studio_dialogs.asset_configure(win, "configuring_asset", after, win.cur)
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/4*3-60,
|
||||||
|
210,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
button=do,
|
||||||
|
icon="link_configure")
|
||||||
|
|
||||||
|
|
||||||
# Search
|
# Search
|
||||||
|
|
||||||
UI_elements.image(layer, win, "settings/themes/"\
|
UI_elements.image(layer, win, "settings/themes/"\
|
||||||
|
|
735
studio/studio_asset_configureLayer.py
Normal file
735
studio/studio_asset_configureLayer.py
Normal file
|
@ -0,0 +1,735 @@
|
||||||
|
# THIS FILE IS A PART OF VCStudio
|
||||||
|
# PYTHON 3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import datetime
|
||||||
|
from subprocess import *
|
||||||
|
|
||||||
|
# GTK module ( Graphical interface
|
||||||
|
import gi
|
||||||
|
gi.require_version('Gtk', '3.0')
|
||||||
|
from gi.repository import Gtk
|
||||||
|
from gi.repository import GLib
|
||||||
|
from gi.repository import Gdk
|
||||||
|
import cairo
|
||||||
|
|
||||||
|
# Own modules
|
||||||
|
from settings import settings
|
||||||
|
from settings import talk
|
||||||
|
from settings import fileformats
|
||||||
|
from settings import oscalls
|
||||||
|
from project_manager import pm_project
|
||||||
|
|
||||||
|
#UI modules
|
||||||
|
from UI import UI_elements
|
||||||
|
from UI import UI_color
|
||||||
|
|
||||||
|
# Studio
|
||||||
|
from studio import studio_dialogs
|
||||||
|
from studio import analytics
|
||||||
|
from studio import story
|
||||||
|
|
||||||
|
def layer(win, call):
|
||||||
|
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
# This file will do the asset configuration for linking assets into anima-
|
||||||
|
# tion files. The ways it's going to be performed is following:
|
||||||
|
|
||||||
|
# 0. User creates the asset. The /dev/ folder for the asset is created.
|
||||||
|
# 1. User finished the asset and the checklists is now 100%.
|
||||||
|
# 2. User Clicks on a configure button which launches this UI.
|
||||||
|
# 3. User choses the main blendfile. It is copied to the /ast/ folder.
|
||||||
|
# 4. User choses the collection and the rig with in the file. and it's
|
||||||
|
# saved into autolink.data
|
||||||
|
# 5. User creates a shot in the script editor. And creates a blend-file.
|
||||||
|
# 6. Use presses the link button on the blend file. And it loads the assets
|
||||||
|
# mentioned in the script.
|
||||||
|
# 7. User presses the okay button and a script is running inside blender
|
||||||
|
# that will read autolink.data files. And open /ast/ blend files. From
|
||||||
|
# which it will loaded the right collection and make library override or
|
||||||
|
# proxy to the rig. Both specified here by the user.
|
||||||
|
|
||||||
|
# See:
|
||||||
|
# studio/studio_shot_linkLayer.py
|
||||||
|
# studio/bpy_do_linking.py
|
||||||
|
# studio/studio_assetLayer.py
|
||||||
|
|
||||||
|
# The way this file going to work will be like a step by step wizzard.
|
||||||
|
|
||||||
|
# This file will be able to be openned from studio_shot_linkLayer dialog so
|
||||||
|
# there will be 3 different UIs in this file.
|
||||||
|
|
||||||
|
# 0. If checklist is not yet 100%. There will be a message to finish the
|
||||||
|
# asset first.
|
||||||
|
# 1. When the checklist is 100%. There will UI to select / copy /ast/file
|
||||||
|
# 2. When that's done. The program going to launch a script to read data
|
||||||
|
# from the newly created /ast/ file. And will present the user with
|
||||||
|
# selection of collections and objects from the collections. So to
|
||||||
|
# what to link and what to proxy.
|
||||||
|
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
|
||||||
|
# Making the layer
|
||||||
|
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, win.current['w'],
|
||||||
|
win.current['h'])
|
||||||
|
layer = cairo.Context(surface)
|
||||||
|
|
||||||
|
|
||||||
|
#text setting
|
||||||
|
layer.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "dark_overdrop")
|
||||||
|
layer.rectangle(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
win.current["w"],
|
||||||
|
win.current["h"],
|
||||||
|
)
|
||||||
|
layer.fill()
|
||||||
|
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "node_background")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/2-250,
|
||||||
|
100,
|
||||||
|
500,
|
||||||
|
win.current["h"]-200,
|
||||||
|
10)
|
||||||
|
|
||||||
|
# Exit button
|
||||||
|
def do():
|
||||||
|
win.current["calls"][call]["var"] = False
|
||||||
|
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/2+210,
|
||||||
|
win.current["h"]-140,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
button=do,
|
||||||
|
icon="cancel",
|
||||||
|
tip=talk.text("cancel"))
|
||||||
|
|
||||||
|
|
||||||
|
# Okay so before we going to clip everything. Let's make a little widget.
|
||||||
|
# this will be similar to the thing on top of shots. With the little round
|
||||||
|
# icons. And a some kind of progress bar with fat points. But this one
|
||||||
|
# will have only 3 points.
|
||||||
|
|
||||||
|
# Let's simplify the process a little bit
|
||||||
|
|
||||||
|
x = win.current["w"]/2-250
|
||||||
|
y = 100
|
||||||
|
width = 500
|
||||||
|
height = win.current["h"]-200
|
||||||
|
|
||||||
|
# Okay. let's draw the icons.
|
||||||
|
|
||||||
|
threeicons = {
|
||||||
|
"edit_mode":False,
|
||||||
|
"blender":False,
|
||||||
|
"link_configure":False
|
||||||
|
}
|
||||||
|
|
||||||
|
for numb, icon in enumerate(threeicons):
|
||||||
|
UI_elements.image(layer, win,"settings/themes/"\
|
||||||
|
+win.settings["Theme"]+"/icons/"+icon+".png",
|
||||||
|
x+(width/4)*numb+(width/8)+40,
|
||||||
|
y+20,
|
||||||
|
40,
|
||||||
|
40)
|
||||||
|
|
||||||
|
# Before we can do progress bar and or progress dots we need to check
|
||||||
|
# a few things about the asset.
|
||||||
|
|
||||||
|
# First is whether it's done.
|
||||||
|
threeicons["edit_mode"] = story.get_asset_data(win, win.current["asset_configure"]["asset"])["fraction"] == 1
|
||||||
|
# Then whether the ast exists.
|
||||||
|
threeicons["blender"] = os.path.exists(win.project+"/ast"+win.current["asset_configure"]["asset"]+".blend")
|
||||||
|
# Then whether the autolink.data exists.
|
||||||
|
threeicons["link_configure"] = os.path.exists(win.project+"/dev"+win.current["asset_configure"]["asset"]+"/autolink.data")
|
||||||
|
|
||||||
|
# Now let's manually make the fraction.
|
||||||
|
fraction = 0.0
|
||||||
|
if threeicons["edit_mode"]:
|
||||||
|
fraction = 0.33
|
||||||
|
if threeicons["blender"]:
|
||||||
|
fraction = 0.66
|
||||||
|
if threeicons["link_configure"]:
|
||||||
|
fraction = 1
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "progress_background")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
x+20,
|
||||||
|
y+80,
|
||||||
|
width-40,
|
||||||
|
0,
|
||||||
|
5)
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "progress_active")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
x+20,
|
||||||
|
y+80,
|
||||||
|
(width-40)*fraction,
|
||||||
|
0,
|
||||||
|
5)
|
||||||
|
|
||||||
|
# And the 3 dots
|
||||||
|
|
||||||
|
for numb, icon in enumerate(threeicons):
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "progress_background")
|
||||||
|
if threeicons[icon]: # If this folder has any files.
|
||||||
|
UI_color.set(layer, win, "progress_active")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
x+(width/4)*numb+(width/8)+50,
|
||||||
|
y+75,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
10)
|
||||||
|
|
||||||
|
# Now let's do 3 UIs.
|
||||||
|
|
||||||
|
|
||||||
|
################## STEP 1: MAKE ASSET ######################
|
||||||
|
|
||||||
|
if not threeicons["edit_mode"]:
|
||||||
|
|
||||||
|
fraction = story.get_asset_data(win, win.current["asset_configure"]["asset"])["fraction"]
|
||||||
|
|
||||||
|
UI_elements.text(layer, win, "asset_configuration_step",
|
||||||
|
x,
|
||||||
|
y+150,
|
||||||
|
width,
|
||||||
|
30,
|
||||||
|
10,
|
||||||
|
fill=False,
|
||||||
|
centered=True,
|
||||||
|
editable=False)
|
||||||
|
win.text["asset_configuration_step"]["text"] = talk.text("asset_configuration_step_1")
|
||||||
|
|
||||||
|
UI_elements.text(layer, win, "asset_configuration_step1",
|
||||||
|
x,
|
||||||
|
y+200,
|
||||||
|
width,
|
||||||
|
30,
|
||||||
|
10,
|
||||||
|
fill=False,
|
||||||
|
centered=True,
|
||||||
|
editable=False)
|
||||||
|
win.text["asset_configuration_step1"]["text"] = str(int(round(fraction*100)))+"%"
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "progress_background")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
x+20,
|
||||||
|
y+250,
|
||||||
|
width-40,
|
||||||
|
0,
|
||||||
|
5)
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "progress_active")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
x+20,
|
||||||
|
y+250,
|
||||||
|
(width-40)*fraction,
|
||||||
|
0,
|
||||||
|
5)
|
||||||
|
|
||||||
|
####################### STEP 2 : COPY BLEND-FILE TO AST ####################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Setting up the scroll
|
||||||
|
if "asset_configure" not in win.scroll:
|
||||||
|
win.scroll["asset_configure"] = 0
|
||||||
|
|
||||||
|
current_Y = 310 # The max scroll value
|
||||||
|
|
||||||
|
if threeicons["edit_mode"] and not threeicons["blender"]:
|
||||||
|
|
||||||
|
UI_elements.text(layer, win, "asset_configuration_step",
|
||||||
|
x,
|
||||||
|
y+150,
|
||||||
|
width,
|
||||||
|
30,
|
||||||
|
10,
|
||||||
|
fill=False,
|
||||||
|
centered=True,
|
||||||
|
editable=False)
|
||||||
|
win.text["asset_configuration_step"]["text"] = talk.text("asset_configuration_step_2")
|
||||||
|
|
||||||
|
# So if the file is selected I want to have an apply button.
|
||||||
|
|
||||||
|
if win.current["asset_configure"]["blend_to_copy"]:
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "text_normal")
|
||||||
|
layer.set_font_size(20)
|
||||||
|
layer.move_to(x+40,
|
||||||
|
y+height-20)
|
||||||
|
layer.show_text(win.current["asset_configure"]["blend_to_copy"])
|
||||||
|
|
||||||
|
def do():
|
||||||
|
copy_from = win.project+"/dev"+win.current["asset_configure"]["asset"]+"/"+win.current["asset_configure"]["blend_to_copy"]
|
||||||
|
copy_to = win.project+"/ast"+win.current["asset_configure"]["asset"]+".blend"
|
||||||
|
|
||||||
|
newname = copy_to[copy_to.rfind("/")+1:]
|
||||||
|
copy_to = copy_to[:copy_to.rfind("/")]
|
||||||
|
|
||||||
|
oscalls.copy_file(
|
||||||
|
win,
|
||||||
|
copy_from,
|
||||||
|
copy_to,
|
||||||
|
newname)
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/2+170,
|
||||||
|
win.current["h"]-140,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
button=do,
|
||||||
|
icon="ok",
|
||||||
|
tip=talk.text("checked"))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Here I want to draw a whole window with blend file selection and stuff.
|
||||||
|
# so here we go.
|
||||||
|
|
||||||
|
# Clipping everything
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/2-250,
|
||||||
|
300,
|
||||||
|
500,
|
||||||
|
win.current["h"]-460,
|
||||||
|
10,
|
||||||
|
fill=False)
|
||||||
|
layer.clip()
|
||||||
|
|
||||||
|
clip = [
|
||||||
|
win.current["w"]/2-250,
|
||||||
|
300,
|
||||||
|
500,
|
||||||
|
win.current["h"]-460]
|
||||||
|
|
||||||
|
# Background
|
||||||
|
#UI_color.set(layer, win, "dark_overdrop")
|
||||||
|
#layer.rectangle(x, y,width,height)
|
||||||
|
#layer.fill()
|
||||||
|
|
||||||
|
# Now we draw all the blend files of the file. I know it's redundant but
|
||||||
|
# I want to be able to configure an asset from the linking window.
|
||||||
|
|
||||||
|
tileX = x+70
|
||||||
|
|
||||||
|
for filename in sorted(os.listdir(win.project+"/dev"+win.current["asset_configure"]["asset"])):
|
||||||
|
|
||||||
|
if filename.endswith(".blend"):
|
||||||
|
|
||||||
|
if int(current_Y + win.scroll["asset_configure"]) in range(0-200, height):
|
||||||
|
|
||||||
|
# Making the layer
|
||||||
|
node2surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 170, 200)
|
||||||
|
node2 = cairo.Context(node2surface)
|
||||||
|
node2.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
|
||||||
|
|
||||||
|
|
||||||
|
UI_elements.roundrect(node2, win,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
170,
|
||||||
|
200,
|
||||||
|
10,
|
||||||
|
fill=False)
|
||||||
|
|
||||||
|
node2.clip()
|
||||||
|
|
||||||
|
# Background
|
||||||
|
UI_color.set(node2, win, "dark_overdrop")
|
||||||
|
node2.rectangle(0,0,170, 200)
|
||||||
|
node2.fill()
|
||||||
|
|
||||||
|
# Banner
|
||||||
|
UI_color.set(node2, win, "node_blendfile")
|
||||||
|
node2.rectangle(0,0,170, 20)
|
||||||
|
node2.fill()
|
||||||
|
|
||||||
|
# Outputting the layer
|
||||||
|
layer.set_source_surface(node2surface,
|
||||||
|
tileX-10,
|
||||||
|
current_Y + win.scroll["asset_configure"] )
|
||||||
|
layer.paint()
|
||||||
|
|
||||||
|
UI_elements.image(layer, win, win.project+"/dev"+win.current["asset_configure"]["asset"]+"/"+filename,
|
||||||
|
tileX,
|
||||||
|
current_Y + win.scroll["asset_configure"] + 30,
|
||||||
|
150,
|
||||||
|
150)
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "text_normal")
|
||||||
|
layer.set_font_size(12)
|
||||||
|
layer.move_to(tileX,
|
||||||
|
current_Y + win.scroll["asset_configure"]+15)
|
||||||
|
layer.show_text(filename[filename.rfind("/")+1:][:22])
|
||||||
|
|
||||||
|
# If selected
|
||||||
|
layer.set_line_width(4)
|
||||||
|
if win.current["asset_configure"]["blend_to_copy"] == filename:
|
||||||
|
UI_color.set(layer, win, "progress_background")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
tileX-10,
|
||||||
|
current_Y + win.scroll["asset_configure"],
|
||||||
|
170,
|
||||||
|
200,
|
||||||
|
10,
|
||||||
|
fill=False)
|
||||||
|
layer.stroke()
|
||||||
|
|
||||||
|
# Button to activate it
|
||||||
|
def do():
|
||||||
|
win.current["asset_configure"]["blend_to_copy"] = filename
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
tileX-10,
|
||||||
|
current_Y + win.scroll["asset_configure"],
|
||||||
|
170,
|
||||||
|
200,
|
||||||
|
10,
|
||||||
|
button=do,
|
||||||
|
tip=filename,
|
||||||
|
fill=False,
|
||||||
|
clip=clip)
|
||||||
|
|
||||||
|
layer.stroke()
|
||||||
|
layer.set_line_width(2)
|
||||||
|
|
||||||
|
tileX += 200
|
||||||
|
|
||||||
|
if tileX > 1000:
|
||||||
|
tileX = x+70
|
||||||
|
current_Y += 230
|
||||||
|
|
||||||
|
####################### STEP 3 : CONFIGURE AUTOLINK.DATA ####################
|
||||||
|
|
||||||
|
if threeicons["edit_mode"] and threeicons["blender"]:
|
||||||
|
|
||||||
|
UI_elements.text(layer, win, "asset_configuration_step",
|
||||||
|
x,
|
||||||
|
y+150,
|
||||||
|
width,
|
||||||
|
30,
|
||||||
|
10,
|
||||||
|
fill=False,
|
||||||
|
centered=True,
|
||||||
|
editable=False)
|
||||||
|
win.text["asset_configuration_step"]["text"] = talk.text("asset_configuration_step_3")
|
||||||
|
|
||||||
|
if win.current["asset_configure"]["apply"]:
|
||||||
|
|
||||||
|
def do():
|
||||||
|
# Here I'm going to actually write stuff to the file. It's not hard.
|
||||||
|
|
||||||
|
autolink = open(win.project+"/dev"+win.current["asset_configure"]["asset"]+"/autolink.data", "w")
|
||||||
|
|
||||||
|
cols = win.current["asset_configure"]["collections"]
|
||||||
|
for col in cols:
|
||||||
|
|
||||||
|
# If the collection is selected we write it.
|
||||||
|
|
||||||
|
if cols[col]["selected"]:
|
||||||
|
autolink.write("Link : "+col+"\n")
|
||||||
|
|
||||||
|
# Also we need to then look throught the collection to
|
||||||
|
# see if there are any proxy objects. Aramtures...
|
||||||
|
|
||||||
|
objs = cols[col]["objects"]
|
||||||
|
|
||||||
|
for obj in objs:
|
||||||
|
|
||||||
|
# Same thing if it's selected. Then write it to file.
|
||||||
|
|
||||||
|
if objs[obj]["selected"]:
|
||||||
|
autolink.write("Proxy : "+obj+"\n")
|
||||||
|
autolink.close()
|
||||||
|
|
||||||
|
# And we need to quit the window. So...
|
||||||
|
win.current["calls"][call]["var"] = False
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/2+170,
|
||||||
|
win.current["h"]-140,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
button=do,
|
||||||
|
icon="ok",
|
||||||
|
tip=talk.text("checked"))
|
||||||
|
|
||||||
|
|
||||||
|
# For this step I can't just copy stuff from assed layer and pretend that everything
|
||||||
|
# is good. Because this part requires a whole new script to write and test.
|
||||||
|
|
||||||
|
# See:
|
||||||
|
# studio/bpy_get_blend_content.py
|
||||||
|
|
||||||
|
# Now let's actually run this script quickly. Basically we need to get data out of
|
||||||
|
# the asset blend file. But of course not on every frame. It's a bit too much. So
|
||||||
|
# here is how we do it.
|
||||||
|
|
||||||
|
if not win.current["asset_configure"]["collections"]:
|
||||||
|
|
||||||
|
# If in the current data the data about the file still doesn't exists we load
|
||||||
|
# it.
|
||||||
|
|
||||||
|
blenderpath = oscalls.get_current_blender(win)
|
||||||
|
assetblend = win.project+"/ast"+win.current["asset_configure"]["asset"]+".blend"
|
||||||
|
|
||||||
|
checkframes = Popen([blenderpath, "-b", assetblend , "-P",
|
||||||
|
os.getcwd()+"/studio/bpy_get_blend_content.py"],stdout=PIPE, universal_newlines=True)
|
||||||
|
checkframes.wait()
|
||||||
|
checkstring = checkframes.stdout.read()
|
||||||
|
|
||||||
|
# Let's also see if the file autolink.data already there. Meaning I can get
|
||||||
|
# data that is already saved there.
|
||||||
|
|
||||||
|
linkcols = []
|
||||||
|
linkobjs = []
|
||||||
|
|
||||||
|
if threeicons["link_configure"]:
|
||||||
|
autolink = open(win.project+"/dev"+win.current["asset_configure"]["asset"]+"/autolink.data")
|
||||||
|
autolink = autolink.read()
|
||||||
|
autolink = autolink.split("\n")
|
||||||
|
|
||||||
|
for line in autolink:
|
||||||
|
if line.startswith("Link : "):
|
||||||
|
linkcols.append(line[7:])
|
||||||
|
|
||||||
|
elif line.startswith("Proxy : "):
|
||||||
|
linkobjs.append(line[8:])
|
||||||
|
else:
|
||||||
|
# If there is no file. I want to start the applying process already:
|
||||||
|
win.current["asset_configure"]["apply"] = True
|
||||||
|
|
||||||
|
# Now let's parse this crazy stuff that we've got from the blender script.
|
||||||
|
|
||||||
|
for line in checkstring.split("\n"):
|
||||||
|
if line.startswith(">>> "):
|
||||||
|
line = line[4:]
|
||||||
|
if "<==" in line:
|
||||||
|
col = line[:line.find(" <==")]
|
||||||
|
obj = line[line.find(" <==")+5:].split(" <== ")
|
||||||
|
|
||||||
|
else:
|
||||||
|
col = line
|
||||||
|
obj = False
|
||||||
|
|
||||||
|
|
||||||
|
selected = False
|
||||||
|
if col in win.current["asset_configure"]["asset"] and not threeicons["link_configure"]:
|
||||||
|
selected = True
|
||||||
|
elif col in linkcols:
|
||||||
|
selected = True
|
||||||
|
|
||||||
|
# So we found a collection. Let's write it in
|
||||||
|
if col not in win.current["asset_configure"]["collections"]:
|
||||||
|
win.current["asset_configure"]["collections"][col] = {
|
||||||
|
"selected":selected,
|
||||||
|
"objects":{}
|
||||||
|
}
|
||||||
|
|
||||||
|
# We also got the object. Let's put it inside the collection.
|
||||||
|
# But first. If it's an armature we want it to be selected.
|
||||||
|
if obj:
|
||||||
|
selected = False
|
||||||
|
if "Armature" in obj[1] and not threeicons["link_configure"]:
|
||||||
|
selected = True
|
||||||
|
elif obj[0] in linkobjs:
|
||||||
|
selected = True
|
||||||
|
|
||||||
|
win.current["asset_configure"]["collections"][col]["objects"][obj[0]] = {
|
||||||
|
"selected":selected,
|
||||||
|
"type":obj[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Now let's draw the findings to the screen. But first we need
|
||||||
|
# buttons to see in what catergory are we.
|
||||||
|
|
||||||
|
buttons = ["collection", "rig"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for num, button in enumerate(buttons):
|
||||||
|
|
||||||
|
if win.current["asset_configure"]["step3_button"] == button:
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "progress_time")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
x+10+(40*num),
|
||||||
|
y+200,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10)
|
||||||
|
|
||||||
|
def do():
|
||||||
|
win.current["asset_configure"]["step3_button"] = button
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
x+10+(40*num),
|
||||||
|
y+200,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
do,
|
||||||
|
button)
|
||||||
|
|
||||||
|
|
||||||
|
# Now we can clip the bastard
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/2-250,
|
||||||
|
350,
|
||||||
|
500,
|
||||||
|
win.current["h"]-510,
|
||||||
|
10,
|
||||||
|
fill=False)
|
||||||
|
layer.clip()
|
||||||
|
|
||||||
|
clip = [
|
||||||
|
win.current["w"]/2-250,
|
||||||
|
350,
|
||||||
|
500,
|
||||||
|
win.current["h"]-510]
|
||||||
|
|
||||||
|
# Background
|
||||||
|
#UI_color.set(layer, win, "dark_overdrop")
|
||||||
|
#layer.rectangle(x, y,width,height)
|
||||||
|
#layer.fill()
|
||||||
|
|
||||||
|
# Let's start by drawing the collections first since it's the first thing
|
||||||
|
# that the user will be doing. Is selecting the collections.
|
||||||
|
|
||||||
|
current_Y = current_Y - 50
|
||||||
|
|
||||||
|
if win.current["asset_configure"]["step3_button"] == "collection":
|
||||||
|
|
||||||
|
for collection in win.current["asset_configure"]["collections"]:
|
||||||
|
|
||||||
|
# We are going to draw a little collection icon. And put a text
|
||||||
|
# with it's name.
|
||||||
|
|
||||||
|
UI_elements.image(layer, win,
|
||||||
|
"settings/themes/"+win.settings["Theme"]+"/icons/collection.png",
|
||||||
|
x+60, y+current_Y+win.scroll["asset_configure"], 40, 40)
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "text_normal")
|
||||||
|
layer.set_font_size(20)
|
||||||
|
layer.move_to(x+120,
|
||||||
|
y+current_Y + win.scroll["asset_configure"]+30)
|
||||||
|
layer.show_text(collection)
|
||||||
|
|
||||||
|
# Now let's make a checkbox button beside each collection.
|
||||||
|
# Mimicing the Blender UI so to speak.
|
||||||
|
|
||||||
|
icon = "unchecked"
|
||||||
|
if win.current["asset_configure"]["collections"][collection]["selected"]:
|
||||||
|
icon = "checked"
|
||||||
|
|
||||||
|
def do():
|
||||||
|
win.current["asset_configure"]["collections"][collection]["selected"]\
|
||||||
|
= not win.current["asset_configure"]["collections"][collection]["selected"]
|
||||||
|
win.current["asset_configure"]["apply"] = True
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
x+10,
|
||||||
|
y+current_Y + win.scroll["asset_configure"],
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
do,
|
||||||
|
icon)
|
||||||
|
|
||||||
|
|
||||||
|
current_Y = current_Y + 50
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
# If we are not doing the collection but instead we are selecting the
|
||||||
|
# rigs. We need to draw different stuff.
|
||||||
|
|
||||||
|
for collection in win.current["asset_configure"]["collections"]:
|
||||||
|
|
||||||
|
# But we want to draw only objects that are in selected colllections
|
||||||
|
# so here what we do.
|
||||||
|
|
||||||
|
if win.current["asset_configure"]["collections"][collection]["selected"]:
|
||||||
|
|
||||||
|
for obj in win.current["asset_configure"]["collections"][collection]["objects"]:
|
||||||
|
|
||||||
|
name = obj
|
||||||
|
obj = win.current["asset_configure"]["collections"][collection]["objects"][obj]
|
||||||
|
|
||||||
|
# Now first thing is we need to find an icon to represent
|
||||||
|
# this object.
|
||||||
|
|
||||||
|
icon = "obj"
|
||||||
|
if "Mesh" in obj["type"]:
|
||||||
|
icon = "mesh"
|
||||||
|
elif "Armature" in obj["type"]:
|
||||||
|
icon = "rig"
|
||||||
|
elif "Camera" in obj["type"]:
|
||||||
|
icon = "shot"
|
||||||
|
|
||||||
|
UI_elements.image(layer, win,
|
||||||
|
"settings/themes/"+win.settings["Theme"]+"/icons/"+icon+".png",
|
||||||
|
x+60, y+current_Y+win.scroll["asset_configure"], 40, 40)
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "text_normal")
|
||||||
|
layer.set_font_size(20)
|
||||||
|
layer.move_to(x+120,
|
||||||
|
y+current_Y + win.scroll["asset_configure"]+30)
|
||||||
|
layer.show_text(name)
|
||||||
|
|
||||||
|
icon = "link"
|
||||||
|
if obj["selected"]:
|
||||||
|
icon = "override"
|
||||||
|
|
||||||
|
def do():
|
||||||
|
obj["selected"]\
|
||||||
|
= not obj["selected"]
|
||||||
|
win.current["asset_configure"]["apply"] = True
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
x+10,
|
||||||
|
y+current_Y + win.scroll["asset_configure"],
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
do,
|
||||||
|
icon)
|
||||||
|
|
||||||
|
|
||||||
|
current_Y = current_Y + 50
|
||||||
|
|
||||||
|
current_Y = current_Y - 300
|
||||||
|
|
||||||
|
###########################
|
||||||
|
|
||||||
|
UI_elements.scroll_area(layer, win, "asset_configure",
|
||||||
|
x,
|
||||||
|
y+300,
|
||||||
|
width,
|
||||||
|
height-400,
|
||||||
|
current_Y,
|
||||||
|
bar=True,
|
||||||
|
mmb=True,
|
||||||
|
url="asset_configure"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
return surface
|
|
@ -52,10 +52,10 @@ def layer(win, call):
|
||||||
|
|
||||||
UI_color.set(layer, win, "node_background")
|
UI_color.set(layer, win, "node_background")
|
||||||
UI_elements.roundrect(layer, win,
|
UI_elements.roundrect(layer, win,
|
||||||
40,
|
80,
|
||||||
40,
|
80,
|
||||||
win.current["w"]-80,
|
win.current["w"]-160,
|
||||||
win.current["h"]-80,
|
win.current["h"]-160,
|
||||||
10)
|
10)
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
|
@ -97,8 +97,8 @@ def layer(win, call):
|
||||||
|
|
||||||
UI_color.set(layer, win, "progress_time")
|
UI_color.set(layer, win, "progress_time")
|
||||||
UI_elements.roundrect(layer, win,
|
UI_elements.roundrect(layer, win,
|
||||||
50+(40*num),
|
100+(40*num),
|
||||||
50,
|
100,
|
||||||
40,
|
40,
|
||||||
40,
|
40,
|
||||||
10)
|
10)
|
||||||
|
@ -107,8 +107,8 @@ def layer(win, call):
|
||||||
win.current["asset_cur"] = cur
|
win.current["asset_cur"] = cur
|
||||||
|
|
||||||
UI_elements.roundrect(layer, win,
|
UI_elements.roundrect(layer, win,
|
||||||
50+(40*num),
|
100+(40*num),
|
||||||
50,
|
100,
|
||||||
40,
|
40,
|
||||||
40,
|
40,
|
||||||
10,
|
10,
|
||||||
|
@ -119,7 +119,7 @@ def layer(win, call):
|
||||||
# In case the user is confused
|
# In case the user is confused
|
||||||
UI_color.set(layer, win, "text_normal")
|
UI_color.set(layer, win, "text_normal")
|
||||||
layer.set_font_size(30)
|
layer.set_font_size(30)
|
||||||
layer.move_to(250,80)
|
layer.move_to(300,130)
|
||||||
layer.show_text(talk.text(win.current["asset_cur"]))
|
layer.show_text(talk.text(win.current["asset_cur"]))
|
||||||
|
|
||||||
|
|
||||||
|
@ -128,14 +128,14 @@ def layer(win, call):
|
||||||
UI_elements.image(layer, win, "settings/themes/"\
|
UI_elements.image(layer, win, "settings/themes/"\
|
||||||
+win.settings["Theme"]+"/icons/search.png",
|
+win.settings["Theme"]+"/icons/search.png",
|
||||||
win.current["w"]-440,
|
win.current["w"]-440,
|
||||||
50,
|
100,
|
||||||
40,
|
40,
|
||||||
40)
|
40)
|
||||||
|
|
||||||
UI_elements.text(layer, win, "asset_select_search",
|
UI_elements.text(layer, win, "asset_select_search",
|
||||||
win.current["w"]-400,
|
win.current["w"]-400,
|
||||||
50,
|
100,
|
||||||
350,
|
250,
|
||||||
40)
|
40)
|
||||||
|
|
||||||
# CANCEl
|
# CANCEl
|
||||||
|
@ -145,8 +145,8 @@ def layer(win, call):
|
||||||
win.assets = {}
|
win.assets = {}
|
||||||
|
|
||||||
UI_elements.roundrect(layer, win,
|
UI_elements.roundrect(layer, win,
|
||||||
win.current["w"]-80,
|
win.current["w"]-120,
|
||||||
win.current["h"]-80,
|
win.current["h"]-120,
|
||||||
40,
|
40,
|
||||||
40,
|
40,
|
||||||
10,
|
10,
|
||||||
|
@ -161,18 +161,18 @@ def layer(win, call):
|
||||||
# Now let's prepare the ground for the next part.
|
# Now let's prepare the ground for the next part.
|
||||||
|
|
||||||
UI_elements.roundrect(layer, win,
|
UI_elements.roundrect(layer, win,
|
||||||
50,
|
|
||||||
100,
|
100,
|
||||||
win.current["w"]-100,
|
150,
|
||||||
win.current["h"]-200,
|
win.current["w"]-200,
|
||||||
|
win.current["h"]-250,
|
||||||
10,
|
10,
|
||||||
fill=False)
|
fill=False)
|
||||||
layer.clip()
|
layer.clip()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
tileX = 70
|
tileX = 120
|
||||||
current_Y = 0
|
current_Y = 50
|
||||||
|
|
||||||
if "asset_select" not in win.scroll:
|
if "asset_select" not in win.scroll:
|
||||||
win.scroll["asset_select"] = 0
|
win.scroll["asset_select"] = 0
|
||||||
|
@ -304,10 +304,10 @@ def layer(win, call):
|
||||||
tip=talk.text(win.current["asset_cur"])+": "+asset,
|
tip=talk.text(win.current["asset_cur"])+": "+asset,
|
||||||
fill=False,
|
fill=False,
|
||||||
clip=[
|
clip=[
|
||||||
50,
|
|
||||||
100,
|
100,
|
||||||
win.current["w"]-100,
|
150,
|
||||||
win.current["h"]-200
|
win.current["w"]-200,
|
||||||
|
win.current["h"]-250
|
||||||
])
|
])
|
||||||
|
|
||||||
layer.stroke()
|
layer.stroke()
|
||||||
|
@ -315,8 +315,8 @@ def layer(win, call):
|
||||||
|
|
||||||
tileX += 200
|
tileX += 200
|
||||||
|
|
||||||
if tileX > win.current["w"]-220:
|
if tileX > win.current["w"]-270:
|
||||||
tileX = 70
|
tileX = 120
|
||||||
|
|
||||||
current_Y += 230
|
current_Y += 230
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,8 @@ from UI import UI_color
|
||||||
|
|
||||||
from studio import studio_file_selectLayer
|
from studio import studio_file_selectLayer
|
||||||
from studio import studio_asset_selectLayer
|
from studio import studio_asset_selectLayer
|
||||||
|
from studio import studio_shot_linkLayer
|
||||||
|
from studio import studio_asset_configureLayer
|
||||||
|
|
||||||
#################
|
#################
|
||||||
|
|
||||||
|
@ -167,6 +169,77 @@ def asset_select(win, name, call, force=False, cur="chr", SEARCH=""):
|
||||||
# Let's activate the text so you could type immediatly
|
# Let's activate the text so you could type immediatly
|
||||||
win.textactive = "asset_select_search"
|
win.textactive = "asset_select_search"
|
||||||
|
|
||||||
|
# Wiping the history of the assets. See studio/studio_asset_selectLayer.py
|
||||||
|
win.assets = {}
|
||||||
|
|
||||||
|
# Let's clear the LMB just in case
|
||||||
|
win.previous["LMB"] = False
|
||||||
|
|
||||||
|
def asset_link(win, name, call, filename, force=False):
|
||||||
|
|
||||||
|
# This function will configure the linking of the assets into animation files
|
||||||
|
# it's in theory a quite simple operation, but requires nesting of dialogs.
|
||||||
|
# which is untested by the time I'm writting this comment.
|
||||||
|
|
||||||
|
if name not in win.current["calls"]:
|
||||||
|
win.current["calls"][name] = {
|
||||||
|
"var" :None, # This is the variable that we are waiting for
|
||||||
|
"call":call, # This is what it's going to run when it's done
|
||||||
|
"url" :"asset_link",
|
||||||
|
"back":win.url,# This is where it's going to come back when it's done
|
||||||
|
"draw":studio_shot_linkLayer.layer
|
||||||
|
}
|
||||||
|
|
||||||
|
# let's prepare the data for this operation
|
||||||
|
|
||||||
|
if force or "linking_asset_data" not in win.current\
|
||||||
|
or win.current["linking_asset_data"]["linking_to"] != filename:
|
||||||
|
win.current["linking_asset_data"] = {
|
||||||
|
"linking_to":filename,
|
||||||
|
"assets":[],
|
||||||
|
"read":False,
|
||||||
|
"selected":"",
|
||||||
|
"mode":"link",
|
||||||
|
"fraction":0,
|
||||||
|
"process":False
|
||||||
|
}
|
||||||
|
if win.current["linking_asset_data"]["fraction"]:
|
||||||
|
win.current["linking_asset_data"]["assets"] = []
|
||||||
|
win.current["linking_asset_data"]["fraction"] = 0
|
||||||
|
|
||||||
|
# Wiping the history of the assets. See studio/studio_asset_selectLayer.py
|
||||||
|
win.assets = {}
|
||||||
|
|
||||||
|
# Let's clear the LMB just in case
|
||||||
|
win.previous["LMB"] = False
|
||||||
|
|
||||||
|
def asset_configure(win, name, call, asset, force=False):
|
||||||
|
|
||||||
|
# This function going to configure assets. More deatailed explanation is
|
||||||
|
# in the file: studio/studio_asset_configureLayer.py
|
||||||
|
|
||||||
|
if name not in win.current["calls"]:
|
||||||
|
win.current["calls"][name] = {
|
||||||
|
"var" :None, # This is the variable that we are waiting for
|
||||||
|
"call":call, # This is what it's going to run when it's done
|
||||||
|
"url" :"asset_configure",
|
||||||
|
"back":win.url,# This is where it's going to come back when it's done
|
||||||
|
"draw":studio_asset_configureLayer.layer
|
||||||
|
}
|
||||||
|
|
||||||
|
# let's prepare the data for this operation
|
||||||
|
|
||||||
|
if force or "asset_configure" not in win.current\
|
||||||
|
or win.current["asset_configure"]["asset"] != asset:
|
||||||
|
win.current["asset_configure"] = {
|
||||||
|
"asset":asset,
|
||||||
|
"blend_to_copy":"",
|
||||||
|
"collections":{},
|
||||||
|
"step3_button":"collection",
|
||||||
|
"apply":False
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# Wiping the history of the assets. See studio/studio_asset_selectLayer.py
|
# Wiping the history of the assets. See studio/studio_asset_selectLayer.py
|
||||||
win.assets = {}
|
win.assets = {}
|
||||||
|
|
||||||
|
|
|
@ -272,6 +272,7 @@ def pmdrawing(pmdrawing, main_layer, win):
|
||||||
win.calllayer = False
|
win.calllayer = False
|
||||||
remlater = []
|
remlater = []
|
||||||
|
|
||||||
|
try:
|
||||||
for call in win.current["calls"]:
|
for call in win.current["calls"]:
|
||||||
|
|
||||||
if win.current["calls"][call]["var"] == None:
|
if win.current["calls"][call]["var"] == None:
|
||||||
|
@ -288,6 +289,8 @@ def pmdrawing(pmdrawing, main_layer, win):
|
||||||
for call in remlater:
|
for call in remlater:
|
||||||
|
|
||||||
del win.current["calls"][call]
|
del win.current["calls"][call]
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
Layers.append([UI_testing.layer(win)])
|
Layers.append([UI_testing.layer(win)])
|
||||||
Layers.append([win.tooltip_surface])
|
Layers.append([win.tooltip_surface])
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
# THIS FILE IS A PART OF VCStudio
|
# THIS FILE IS A PART OF VCStudio
|
||||||
# PYTHON 3
|
# PYTHON 3
|
||||||
|
|
||||||
# This a console project manager.
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import datetime
|
import datetime
|
||||||
import re
|
import re
|
||||||
|
@ -2588,12 +2586,22 @@ def layer(win):
|
||||||
148,
|
148,
|
||||||
10,
|
10,
|
||||||
button=do,
|
button=do,
|
||||||
fill=False)
|
fill=False,
|
||||||
|
tip=blend)
|
||||||
layer.stroke()
|
layer.stroke()
|
||||||
|
|
||||||
# Link things into Blend-File
|
# Link things into Blend-File
|
||||||
def do():
|
def do():
|
||||||
print("Link")
|
|
||||||
|
# I'm using a dialog here. Because I want to return back
|
||||||
|
# to the shot we were in. But I don't really want to do
|
||||||
|
# anything after the dialog is closed. So there is this
|
||||||
|
# empty function.
|
||||||
|
|
||||||
|
def after(win, var):
|
||||||
|
pass
|
||||||
|
|
||||||
|
studio_dialogs.asset_link(win, "asset_linking", after, "/rnd"+win.cur+"/"+blend)
|
||||||
|
|
||||||
UI_elements.roundrect(layer, win,
|
UI_elements.roundrect(layer, win,
|
||||||
x+tileX+20,
|
x+tileX+20,
|
||||||
|
@ -2602,7 +2610,8 @@ def layer(win):
|
||||||
40,
|
40,
|
||||||
10,
|
10,
|
||||||
icon="obj_link",
|
icon="obj_link",
|
||||||
button=do)
|
button=do,
|
||||||
|
tip=talk.text("link_shot_blend_tooltip")+blend)
|
||||||
|
|
||||||
# Render
|
# Render
|
||||||
def do():
|
def do():
|
||||||
|
@ -2615,7 +2624,8 @@ def layer(win):
|
||||||
40,
|
40,
|
||||||
10,
|
10,
|
||||||
icon="render",
|
icon="render",
|
||||||
button=do)
|
button=do,
|
||||||
|
tip=talk.text("render_shot_blend_tooltip")+blend)
|
||||||
|
|
||||||
tileX = tileX + 150
|
tileX = tileX + 150
|
||||||
if tileX + 128 > width - 10 and bn != len(blendfiles)-1:
|
if tileX + 128 > width - 10 and bn != len(blendfiles)-1:
|
||||||
|
|
642
studio/studio_shot_linkLayer.py
Normal file
642
studio/studio_shot_linkLayer.py
Normal file
|
@ -0,0 +1,642 @@
|
||||||
|
# THIS FILE IS A PART OF VCStudio
|
||||||
|
# PYTHON 3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
from subprocess import *
|
||||||
|
|
||||||
|
# GTK module ( Graphical interface
|
||||||
|
import gi
|
||||||
|
gi.require_version('Gtk', '3.0')
|
||||||
|
from gi.repository import Gtk
|
||||||
|
from gi.repository import GLib
|
||||||
|
from gi.repository import Gdk
|
||||||
|
import cairo
|
||||||
|
|
||||||
|
# Own modules
|
||||||
|
from settings import settings
|
||||||
|
from settings import oscalls
|
||||||
|
from settings import talk
|
||||||
|
from settings import fileformats
|
||||||
|
from project_manager import pm_project
|
||||||
|
|
||||||
|
#UI modules
|
||||||
|
from UI import UI_elements
|
||||||
|
from UI import UI_color
|
||||||
|
|
||||||
|
# story
|
||||||
|
from studio import story
|
||||||
|
from studio import analytics
|
||||||
|
from studio import history
|
||||||
|
from studio import studio_dialogs
|
||||||
|
|
||||||
|
def link_from_script(win):
|
||||||
|
|
||||||
|
#########################################################################
|
||||||
|
|
||||||
|
# This file is here because there are multiple places in the window where
|
||||||
|
# I want to link assets based on what's written in the text of the script.
|
||||||
|
|
||||||
|
# So this file will basically parse the text and add the assets it finds
|
||||||
|
# linked to the link list.
|
||||||
|
|
||||||
|
#########################################################################
|
||||||
|
|
||||||
|
print("Reading from the scene")
|
||||||
|
|
||||||
|
# Fist we need to know what scene and shot are we.
|
||||||
|
|
||||||
|
if win.cur.count("/") > 1:
|
||||||
|
tmp = win.cur.replace("/","",1).split("/")
|
||||||
|
scene, shotis = tmp[0], tmp[1]
|
||||||
|
else:
|
||||||
|
scene = win.cur[win.cur.rfind("/")+1:]
|
||||||
|
shotis = ""
|
||||||
|
|
||||||
|
print(scene, shotis)
|
||||||
|
|
||||||
|
# Now let's read through the scene.
|
||||||
|
|
||||||
|
for shot in win.story["scenes"][scene]["shots"]:
|
||||||
|
|
||||||
|
|
||||||
|
# Ignore the non shots.
|
||||||
|
if shot[0] != "shot_block":
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Ingore all other shots.
|
||||||
|
if shot[1] != shotis:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Let's read the shot
|
||||||
|
for asset in shot[-1]:
|
||||||
|
# Ignore text
|
||||||
|
if asset[0] == "text":
|
||||||
|
continue
|
||||||
|
|
||||||
|
# It's it's a staight up link. Just add it.
|
||||||
|
if asset[0] == "link" and "/dev"+asset[1] not in win.current["linking_asset_data"]["assets"]:
|
||||||
|
win.current["linking_asset_data"]["assets"].append("/dev"+asset[1])
|
||||||
|
|
||||||
|
# It's a link in a frase.
|
||||||
|
if asset[0] == "frase" and asset[1][0] == "link" and "/dev"+asset[1][1] not in win.current["linking_asset_data"]["assets"]:
|
||||||
|
win.current["linking_asset_data"]["assets"].append("/dev"+asset[1][1])
|
||||||
|
|
||||||
|
|
||||||
|
def layer(win, call):
|
||||||
|
|
||||||
|
# Making the layer
|
||||||
|
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, win.current['w'],
|
||||||
|
win.current['h'])
|
||||||
|
layer = cairo.Context(surface)
|
||||||
|
|
||||||
|
|
||||||
|
#text setting
|
||||||
|
layer.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "dark_overdrop")
|
||||||
|
layer.rectangle(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
win.current["w"],
|
||||||
|
win.current["h"],
|
||||||
|
)
|
||||||
|
layer.fill()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "node_background")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
win.current["w"]-80,
|
||||||
|
win.current["h"]-80,
|
||||||
|
10)
|
||||||
|
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# This file is configuring and lanunching the linking into blend files. But it's
|
||||||
|
# not the only file in the chain of files that is responsible for this operation.
|
||||||
|
|
||||||
|
# For example the linking it self does studio/bpy_do_linking.py that is running
|
||||||
|
# inside blender and communicates with this file for the UI side of things.
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Okay
|
||||||
|
if not win.current["linking_asset_data"]["fraction"]:
|
||||||
|
def do():
|
||||||
|
|
||||||
|
if not win.current["linking_asset_data"]["process"]:
|
||||||
|
|
||||||
|
# So this is an apply button. I know it's a little not in the right
|
||||||
|
# order. So please read the rest of the file to see what it does.
|
||||||
|
|
||||||
|
# So now when a person clicks okay. We first need to save the
|
||||||
|
# autolink.data.
|
||||||
|
|
||||||
|
datafile = open(win.project+"/rnd"+win.cur+"/extra/autolink.data", "w")
|
||||||
|
for asset in win.current["linking_asset_data"]["assets"]:
|
||||||
|
datafile.write("Link : "+asset+"\n")
|
||||||
|
|
||||||
|
# Also let's write the mode. Because it's important.
|
||||||
|
datafile.write("Mode : "+win.current["linking_asset_data"]["mode"]+"\n")
|
||||||
|
|
||||||
|
datafile.close()
|
||||||
|
|
||||||
|
# Okay... now that we have the file. We can start the process of linking
|
||||||
|
# Which will be done using Blender. So let's get blender's url
|
||||||
|
|
||||||
|
blenderpath = oscalls.get_current_blender(win)
|
||||||
|
|
||||||
|
# Now here is the fun part. We gonna start a background process
|
||||||
|
# open there blender and will start linking stuff.
|
||||||
|
|
||||||
|
win.current["linking_asset_data"]["process"] = Popen(['stdbuf', '-o0', blenderpath, \
|
||||||
|
"-b", win.project+win.current["linking_asset_data"]["linking_to"], \
|
||||||
|
"-P", os.getcwd()+"/studio/bpy_do_linking.py"],\
|
||||||
|
stdout=PIPE, universal_newlines=True)
|
||||||
|
|
||||||
|
win.current["linking_asset_data"]["fraction"] = 0.01
|
||||||
|
|
||||||
|
# Hell of a command isn't it.
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]-120,
|
||||||
|
win.current["h"]-80,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
button=do,
|
||||||
|
icon="ok",
|
||||||
|
tip=talk.text("checked"),
|
||||||
|
url="asset_link")
|
||||||
|
|
||||||
|
# CANCEl
|
||||||
|
if not win.current["linking_asset_data"]["process"]:
|
||||||
|
def do():
|
||||||
|
if not win.current["linking_asset_data"]["process"]:
|
||||||
|
win.current["calls"][call]["var"] = False
|
||||||
|
win.assets = {}
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]-80,
|
||||||
|
win.current["h"]-80,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
button=do,
|
||||||
|
icon="cancel",
|
||||||
|
tip=talk.text("cancel"),
|
||||||
|
url="asset_link")
|
||||||
|
|
||||||
|
# Short cut ESC
|
||||||
|
if 65307 in win.current["keys"] and not win.textactive:
|
||||||
|
do()
|
||||||
|
|
||||||
|
# Now let's prepare the ground for the next part.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Before we do anything we need to make sure that there is an autolink.data
|
||||||
|
# file in the extra folder of the shot. But since this is a system that is
|
||||||
|
# designed to be very simple on the user side. There could not even be the
|
||||||
|
# extra folder. So...
|
||||||
|
|
||||||
|
try:
|
||||||
|
os.mkdir(win.project+"/rnd"+win.cur+"/extra")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Next thing will be to see if there is a file called autolink.data. And if
|
||||||
|
# yes read from it. We are going to load the data into the memory.
|
||||||
|
|
||||||
|
# So if there is nothing yet loaded let's try loading it from file. Try
|
||||||
|
# because there nothing quarantees that the file exists. If file does not
|
||||||
|
# exists we gonna populate it with assets from the shot. As marked in the
|
||||||
|
# scene the user wrote. But it's going to be a separate function since I
|
||||||
|
# want to make a button to do it.
|
||||||
|
|
||||||
|
if not win.current["linking_asset_data"]["assets"] and not win.current["linking_asset_data"]["read"]:
|
||||||
|
|
||||||
|
win.current["linking_asset_data"]["read"] = True
|
||||||
|
|
||||||
|
try:
|
||||||
|
datafile = open(win.project+"/rnd"+win.cur+"/extra/autolink.data")
|
||||||
|
datafile = datafile.read()
|
||||||
|
datafile = datafile.split("\n")
|
||||||
|
|
||||||
|
for line in datafile:
|
||||||
|
if line.startswith("Link : "):
|
||||||
|
asset = line[7:]
|
||||||
|
win.current["linking_asset_data"]["assets"].append(asset)
|
||||||
|
except:
|
||||||
|
|
||||||
|
# So if it fails to load the file. Probably because it's not created
|
||||||
|
# yet. Let's load from the story. What's so bad about it?
|
||||||
|
|
||||||
|
link_from_script(win)
|
||||||
|
|
||||||
|
# Now keep in mind that to help the script that runs inside blender all
|
||||||
|
# assets have /dev/ in their folder. So to reach /ast/ blend file we will
|
||||||
|
# need to parse the link. It's not hard just reminding it here.
|
||||||
|
|
||||||
|
|
||||||
|
# IK everything is all over the place in the file but...
|
||||||
|
# If there is a process. We should be able to see what it does.
|
||||||
|
# Draw like a litte progress bar and stuff
|
||||||
|
|
||||||
|
if win.current["linking_asset_data"]["process"]:
|
||||||
|
|
||||||
|
# Basically during the execution of the linking. I want to read the
|
||||||
|
# output and give the user some feedback of what is going on.
|
||||||
|
|
||||||
|
currentline = win.current["linking_asset_data"]["process"].stdout.readline()[:-1]
|
||||||
|
|
||||||
|
# In the bpy_do_linking.py file there is an instruction to write
|
||||||
|
# out a fraction of a current operation into terminal. Which is
|
||||||
|
# piped into the VCStudio and I can read it. So we can use it
|
||||||
|
# to draw a progress bar.
|
||||||
|
|
||||||
|
if currentline.startswith("FRACTION:"):
|
||||||
|
try:
|
||||||
|
fraction = float(currentline.split(":")[1])
|
||||||
|
win.current["linking_asset_data"]["fraction"] = fraction
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if currentline == "FINISHED":
|
||||||
|
win.current["linking_asset_data"]["process"] = False
|
||||||
|
win.current["linking_asset_data"]["fraction"] = 1
|
||||||
|
|
||||||
|
|
||||||
|
# The prgoress bar:
|
||||||
|
if win.current["linking_asset_data"]["fraction"]:
|
||||||
|
fraction = win.current["linking_asset_data"]["fraction"]
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "progress_background")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
70,
|
||||||
|
win.current["h"]-75,
|
||||||
|
(win.current["w"]-220),
|
||||||
|
0,
|
||||||
|
7)
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "progress_active")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
70,
|
||||||
|
win.current["h"]-75,
|
||||||
|
(win.current["w"]-220)*fraction,
|
||||||
|
0,
|
||||||
|
7)
|
||||||
|
|
||||||
|
|
||||||
|
# This file will fuel of nightmares. Okay. So while developping it I realzed
|
||||||
|
# one little problem. Overrides are kind a still buggy. Tho it's good to
|
||||||
|
# have them for future releases. And most of rigs work just fine.
|
||||||
|
|
||||||
|
# The thing that I want to do is to give the user options. Let's say their
|
||||||
|
# rig is broken when trying Library- Overrides but it's okay if you do
|
||||||
|
# legacy Proxy thing. So why not give the user the option of doing both.
|
||||||
|
|
||||||
|
# And also sometimes you just want to link and decide later what you do with
|
||||||
|
# your rig.
|
||||||
|
|
||||||
|
# So I gonna make 3 icons. 3 modes so to speak. LINK, OVERRIDE, PROXY.
|
||||||
|
|
||||||
|
linkoptions = {
|
||||||
|
"link":"link_mode_link",
|
||||||
|
"override":"link_mode_overrides", # Icon / Mode : Tooltip
|
||||||
|
"proxy":"link_mode_proxy"
|
||||||
|
}
|
||||||
|
|
||||||
|
for num, mode in enumerate(linkoptions):
|
||||||
|
|
||||||
|
if win.current["linking_asset_data"]["mode"] == mode:
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "progress_time")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
50+(40*num),
|
||||||
|
50,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10)
|
||||||
|
|
||||||
|
def do():
|
||||||
|
win.current["linking_asset_data"]["mode"] = mode
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
50+(40*num),
|
||||||
|
50,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
do,
|
||||||
|
mode,
|
||||||
|
tip=talk.text(linkoptions[mode]))
|
||||||
|
|
||||||
|
# Let's add a button that adds assets based on what's written in the script.
|
||||||
|
|
||||||
|
def do():
|
||||||
|
link_from_script(win)
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
200,
|
||||||
|
50,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
do,
|
||||||
|
"scene_new",
|
||||||
|
tip=talk.text("link_add_from_scene"))
|
||||||
|
|
||||||
|
|
||||||
|
if not os.path.exists(win.project+win.current["linking_asset_data"]["selected"]+"/autolink.data")\
|
||||||
|
or not os.path.exists(win.project+win.current["linking_asset_data"]["selected"].replace("/dev/","/ast/")+".blend"):
|
||||||
|
|
||||||
|
def do():
|
||||||
|
|
||||||
|
def after(win, var):
|
||||||
|
print(var)
|
||||||
|
|
||||||
|
studio_dialogs.asset_configure(win, "configuring_asset", after,
|
||||||
|
win.current["linking_asset_data"]["selected"].replace("/dev",""))
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
250,
|
||||||
|
50,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
button=do,
|
||||||
|
icon="link_configure")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# That's it. Now we are clipping and drawing the assets them selves.
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
50,
|
||||||
|
100,
|
||||||
|
win.current["w"]-100,
|
||||||
|
win.current["h"]-200,
|
||||||
|
10,
|
||||||
|
fill=False)
|
||||||
|
layer.clip()
|
||||||
|
|
||||||
|
tileX = 70
|
||||||
|
current_Y = 0
|
||||||
|
|
||||||
|
if "asset_link" not in win.scroll:
|
||||||
|
win.scroll["asset_link"] = 0
|
||||||
|
|
||||||
|
#############################
|
||||||
|
|
||||||
|
# Let's draw the list of assets that the user chose.
|
||||||
|
|
||||||
|
for num, asset in enumerate(win.current["linking_asset_data"]["assets"]):
|
||||||
|
|
||||||
|
cur, name = asset.split("/")[2], asset.split("/")[3]
|
||||||
|
|
||||||
|
if int(current_Y + win.scroll["asset_link"] + 100) in range(0-100, win.current["h"]):
|
||||||
|
|
||||||
|
# Making the layer
|
||||||
|
nodesurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 170, 200)
|
||||||
|
node = cairo.Context(nodesurface)
|
||||||
|
node.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
|
||||||
|
|
||||||
|
|
||||||
|
UI_elements.roundrect(node, win,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
170,
|
||||||
|
200,
|
||||||
|
10,
|
||||||
|
fill=False)
|
||||||
|
|
||||||
|
node.clip()
|
||||||
|
|
||||||
|
# Background
|
||||||
|
UI_color.set(node, win, "dark_overdrop")
|
||||||
|
node.rectangle(0,0,170, 200)
|
||||||
|
node.fill()
|
||||||
|
|
||||||
|
# Banner
|
||||||
|
UI_color.set(node, win, "node_asset")
|
||||||
|
|
||||||
|
# Now the banner will be node_asset color if the asset is configured
|
||||||
|
# but it could be not configured. Or not even have the asset blend.
|
||||||
|
# so we need to quickly check both. And if any of them missing. Make
|
||||||
|
# the banner a node_badfile color.
|
||||||
|
|
||||||
|
warning = ""
|
||||||
|
|
||||||
|
if not os.path.exists(win.project+asset+"/autolink.data")\
|
||||||
|
or not os.path.exists(win.project+asset.replace("/dev/","/ast/")+".blend"):
|
||||||
|
UI_color.set(node, win, "node_badfile")
|
||||||
|
|
||||||
|
warning = "\n"+talk.text("link_asset_not_configured")
|
||||||
|
|
||||||
|
# Let's do even cooler. And let's draw a thing arround the asset.
|
||||||
|
node.set_line_width(10)
|
||||||
|
UI_elements.roundrect(node, win,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
170,
|
||||||
|
200,
|
||||||
|
10,
|
||||||
|
fill=False)
|
||||||
|
|
||||||
|
node.stroke()
|
||||||
|
node.set_line_width(2)
|
||||||
|
|
||||||
|
# Even cooler. Let's put a configuration button right into here
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
node.rectangle(0,0,170, 20)
|
||||||
|
node.fill()
|
||||||
|
|
||||||
|
# Outputting the layer
|
||||||
|
layer.set_source_surface(nodesurface,
|
||||||
|
tileX-10,
|
||||||
|
current_Y + win.scroll["asset_link"] + 120)
|
||||||
|
layer.paint()
|
||||||
|
|
||||||
|
|
||||||
|
# Previes image
|
||||||
|
|
||||||
|
if os.path.exists(win.project+asset+"/renders/Preview.png"):
|
||||||
|
UI_elements.image(layer, win, win.project+asset+"/renders/Preview.png",
|
||||||
|
tileX,
|
||||||
|
current_Y + win.scroll["asset_link"] + 140,
|
||||||
|
150,
|
||||||
|
150)
|
||||||
|
|
||||||
|
elif os.path.exists(win.project+asset+"/renders/Preview.jpg"):
|
||||||
|
UI_elements.image(layer, win, win.project+asset+"/renders/Preview.jpg",
|
||||||
|
tileX,
|
||||||
|
current_Y + win.scroll["asset_link"] + 140,
|
||||||
|
150,
|
||||||
|
150)
|
||||||
|
else:
|
||||||
|
UI_elements.image(layer, win, "settings/themes/"+win.settings["Theme"]+"/icons/"+cur+".png",
|
||||||
|
tileX+55,
|
||||||
|
current_Y + win.scroll["asset_link"] + 150+55,
|
||||||
|
150,
|
||||||
|
150)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "text_normal")
|
||||||
|
layer.set_font_size(12)
|
||||||
|
layer.move_to(tileX,
|
||||||
|
current_Y + win.scroll["asset_link"] + 135)
|
||||||
|
layer.show_text(name[:22])
|
||||||
|
|
||||||
|
# Let's make a selection of an asset so you could delete one. Or
|
||||||
|
# do other stuff. Maybe.
|
||||||
|
|
||||||
|
if win.current["linking_asset_data"]["selected"] == asset:
|
||||||
|
|
||||||
|
layer.set_line_width(4)
|
||||||
|
UI_color.set(layer, win, "progress_background")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
tileX-10,
|
||||||
|
current_Y + win.scroll["asset_link"] + 120,
|
||||||
|
170,
|
||||||
|
200,
|
||||||
|
10,
|
||||||
|
fill=False)
|
||||||
|
|
||||||
|
layer.stroke()
|
||||||
|
layer.set_line_width(2)
|
||||||
|
|
||||||
|
# And the delete key.
|
||||||
|
|
||||||
|
if 65535 in win.current["keys"]:
|
||||||
|
try:
|
||||||
|
win.current["linking_asset_data"]["assets"].remove(asset)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
win.current["keys"] = []
|
||||||
|
|
||||||
|
# Button to activate it
|
||||||
|
def do():
|
||||||
|
win.current["linking_asset_data"]["selected"] = asset
|
||||||
|
|
||||||
|
layer.set_line_width(4)
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
tileX-10,
|
||||||
|
current_Y + win.scroll["asset_link"] + 120,
|
||||||
|
170,
|
||||||
|
200,
|
||||||
|
10,
|
||||||
|
button=do,
|
||||||
|
tip=talk.text(cur)+": "+name+warning,
|
||||||
|
fill=False,
|
||||||
|
clip=[
|
||||||
|
50,
|
||||||
|
100,
|
||||||
|
win.current["w"]-100,
|
||||||
|
win.current["h"]-200
|
||||||
|
],
|
||||||
|
url="asset_link")
|
||||||
|
|
||||||
|
layer.stroke()
|
||||||
|
layer.set_line_width(2)
|
||||||
|
|
||||||
|
tileX += 200
|
||||||
|
|
||||||
|
if tileX > win.current["w"]-220:
|
||||||
|
tileX = 70
|
||||||
|
|
||||||
|
current_Y += 230
|
||||||
|
|
||||||
|
|
||||||
|
# Now here I want to put the add new one button. So you could add assets
|
||||||
|
# to the stuff manually.
|
||||||
|
|
||||||
|
def do():
|
||||||
|
|
||||||
|
# Now this is going to be wild. Because I'm going to run a dialog with
|
||||||
|
# in a dialog. And I hope that it's going to work.
|
||||||
|
|
||||||
|
def after(win, var):
|
||||||
|
|
||||||
|
# Funny that it's actually working.
|
||||||
|
# Tho there is a little rub. If you press Cancel there is a bug that
|
||||||
|
# makes nothing unusable. so...
|
||||||
|
|
||||||
|
try:
|
||||||
|
del win.current["calls"]["link_add_asset_select"]
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if var and "/dev"+var not in win.current["linking_asset_data"]["assets"]:
|
||||||
|
win.current["linking_asset_data"]["assets"].append("/dev"+var)
|
||||||
|
|
||||||
|
# So basically I want to add one only if there is not one already.
|
||||||
|
# And then select it. So if the use gets which one is added or
|
||||||
|
# whether it was already there.
|
||||||
|
|
||||||
|
win.current["linking_asset_data"]["selected"] = "/dev"+var
|
||||||
|
|
||||||
|
# And since it could allight with the add button. Let's clear the
|
||||||
|
# click
|
||||||
|
|
||||||
|
win.current["LMB"] = False
|
||||||
|
win.previous["LMB"] = False
|
||||||
|
|
||||||
|
|
||||||
|
studio_dialogs.asset_select(win, "link_add_asset_select", after)
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
tileX-10,
|
||||||
|
current_Y + win.scroll["asset_link"] + 120,
|
||||||
|
170,
|
||||||
|
200,
|
||||||
|
10,
|
||||||
|
button=do,
|
||||||
|
url="asset_link")
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "progress_background")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
tileX-10,
|
||||||
|
current_Y + win.scroll["asset_link"] + 120,
|
||||||
|
170,
|
||||||
|
200,
|
||||||
|
10,
|
||||||
|
fill=False)
|
||||||
|
layer.stroke()
|
||||||
|
|
||||||
|
UI_elements.image(layer, win,
|
||||||
|
"settings/themes/"+win.settings["Theme"]+"/icons/asset_new.png",
|
||||||
|
tileX+55,
|
||||||
|
current_Y + win.scroll["asset_link"] + 200,
|
||||||
|
40, 40)
|
||||||
|
|
||||||
|
#############################
|
||||||
|
|
||||||
|
current_Y += 230
|
||||||
|
|
||||||
|
UI_elements.scroll_area(layer, win, "asset_link",
|
||||||
|
50,
|
||||||
|
100,
|
||||||
|
win.current["w"]-100,
|
||||||
|
win.current["h"]-200,
|
||||||
|
current_Y,
|
||||||
|
bar=True,
|
||||||
|
mmb=True,
|
||||||
|
url="asset_link",
|
||||||
|
strenght=130
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return surface
|
Loading…
Reference in a new issue