Hacking around with Google Blockly and Blender. Blockly inside of Blender could be useful for game play scripting and other things. At the moment this is just a proof of concept how to get WebKit and Blockly to load inside of Blender and have simple two-way communication.
This hack is standalone, and already includes Blender2.63 compiled by natewiebe13 from Graphicall.org. To get this running, all you need to do is: "sudo apt-get install libwebkitgtk-3.0-dev" download hereHello World Source Code
import bpy
def myprocedure():
'''
user defined function, in blockly just define an empty function,
and give it the name "myprocedure"
'''
bpy.ops.mesh.primitive_monkey_add()
###############################################
import os, sys, time, ctypes
sys.path.append( os.path.abspath('.') )
import webkitgtk as webkit
import Blender # brett's ctypes wrapper to libblender
gtk = glib = webkit # webkit links to gtk and glib
gtk.init()
def get_html():
dom = view.get_dom_document()
html = webkit.dom_html_element_get_inner_html( dom )
return html
def call_javascript( script ):
'''
this won't work because it kills newlines!
view.execute_script('document.title=%s;' %script)
'''
view.execute_script(
"document.getElementsByTagName('text_hack')[0].setAttribute('x',%s);"%script
)
result = get_html()
result = result.split('text_hack x="')[-1]
result = result.split('"')[0]
return result
def hack_code( script ):
'''
need to hack the script a bit, blockly generates python2,
and blender needs python3!
'''
a = []
for line in script.splitlines():
if "print '" in line:
line = line.replace("print '", "print('") + ')'
if line == 'null': continue # blockly bug?
elif line.strip() == 'passnull': # check for an undefined function and remove it
a.pop()
continue
a.append(line)
script = '\n'.join(a)
print('----------- python code -------------')
print(script)
return script
def execute_python( script ):
script = hack_code( script )
print('----------- exec python code -------------')
exec( script )
################### WebKitGTK ####################
view = webkit.webkit_web_view_new()
print(view)
settings = webkit.web_settings_new()
for prop in 'enable-webaudio enable-file-access-from-file-uris enable-universal-access-from-file-uris enable-developer-extras enable-accelerated-compositing enable-webgl'.split():
gval = glib.GValue(True)
glib.g_object_set_property( settings, prop, gval )
view.set_settings( settings )
view.load_uri( 'file://%s/test-blockly.html'%os.path.abspath('.'))
win = gtk.Window()
root = gtk.VBox()
win.add( root )
header = gtk.HBox()
root.pack_start( header, expand=False )
button = gtk.Button('print html')
button.connect('clicked', lambda b: get_html() )
header.pack_start( button, expand=False )
header.pack_start( gtk.Label() )
button = gtk.Button('print python')
button.connect('clicked', lambda b: hack_code(call_javascript("Blockly.Generator.workspaceToCode('Python')")) )
header.pack_start( button, expand=False )
button = gtk.Button('run python')
button.connect('clicked', lambda b: execute_python(call_javascript("Blockly.Generator.workspaceToCode('Python')")) )
header.pack_start( button, expand=False )
root.pack_start( view, expand=True )
win.set_default_size( 800, 600 )
win.show_all()
class BlenderHack(object):
def update_gtk(self, region):
while gtk.gtk_events_pending():
gtk.gtk_main_iteration()
def setup_blender_hack(self, context):
self._sync_hack_handles = {} # region : handle
self.default_blender_screen = context.screen.name
self.evil_C = Blender.Context( context )
for area in context.screen.areas:
if area.type == 'VIEW_3D':
for reg in area.regions:
if reg.type == 'WINDOW':
handle = reg.callback_add( self.update_gtk, (reg,), 'POST_PIXEL' )
self._sync_hack_handles[ reg ] = handle
return self._sync_hack_handles
def mainloop(self):
self.active = True
while self.active:
screen = bpy.data.screens[ self.default_blender_screen ]
## force a redraw on the 3d view
for area in screen.areas:
if area.type == 'VIEW_3D':
for reg in area.regions:
if reg.type == 'WINDOW':
reg.tag_redraw()
break
## iterate blender's mainloop from ctypes
Blender.iterate( self.evil_C )
time.sleep(0.01)
hack = BlenderHack()
hack.setup_blender_hack( bpy.context )
hack.mainloop()
print('exit to normal blender mainloop')
great works mate , keep them coming
ReplyDeletethis is really amazing, are you planning on integrate it inside blender
ReplyDelete1xbet korean casino with korean player reviews, bonus offers and promotions
ReplyDelete1xbet korean casino with korean หาเงินออนไลน์ player reviews, bonus offers septcasino and promotions. 1xbet korean casino 1xbet with korean player reviews, bonus offers and promotions.