I’ve moved the driver_display_callback.dll
into the arnold/plugins folder and alas, it appears blender can finally find this driver… Now how do I go about getting access to the driver’s method so I can use it like this:
cb = arnold.DisplayCallback(_callback)
arnold.AiNodeSetPtr(driver, "callback", cb)
After running the dll through link
I get the following:
00000000 characteristics
FFFFFFFF time date stamp
0.00 version
1 ordinal base
1 number of functions
1 number of names
ordinal hint RVA name
1 0 000110C3 NodeLoader = @ILT+190(NodeLoader)
It takes 6 parameters, perfect for that _callback
method, now it doesn’t appear that I can use this function from arnold
directly for whatever reason, so should I just import the .dll using ctypes in python and passing it the appropriate parameters directly?
brecht
July 1, 2018, 11:23am
23
Look at how the the display callback type was defined in Arnold 4 in Python with ctypes, you can do the same thing for the custom driver node.
This appears to work, not sure if it’s correct because it’s not displaying in Blender, but I can tell it at least attempts to render somewhere with this:
cb = arnold.AtRenderUpdateCallback(display_callback)
arnold.AiNodeSetPtr(session['display'], "callback_data", cb)
Using this callback I would assume would still work:
def display_callback(x, y, width, height, buffer, data):
_x = x - xoff
_y = y - yoff
if buffer:
try:
result = _htiles.pop((_x, _y), None)
if result is None:
result = engine.begin_result(_x, _y, width, height)
_buffer = ctypes.cast(buffer, ctypes.POINTER(ctypes.c_float))
rect = numpy.ctypeslib.as_array(_buffer, shape=(width * height, 4))
# TODO: gamma correction. need??? kick is darker
# set 1/2.2 the driver_display node by default
#rect **= 2.2
result.layers[0].passes[0].rect = rect
engine.end_result(result)
finally:
arnold.AiFree(buffer)
else:
result = engine.begin_result(_x, _y, width, height)
# TODO: sometimes highlighted tiles become empty
engine.update_result(result)
_htiles[(_x, _y)] = result
if engine.test_break():
arnold.AiRenderAbort()
while _htiles:
(_x, _y), result = _htiles.popitem()
engine.end_result(result, True)
mem = session["mem"] = arnold.AiMsgUtilGetUsedMemory() / 1048576 # 1024*1024
peak = session["peak"] = max(session["peak"], mem)
engine.update_memory_stats(mem, peak)
And the log it produced, which looks good to me, is there additional setup needed for blender’s viewport/Image Editor:
00:00:00 266MB | log started Sun Jul 1 05:46:49 2018
00:00:00 266MB | Arnold 5.1.1.0 [e338d869] windows icc-17.0.2 oiio-1.7.17 osl-1.9.0 vdb-4.0.0 clm-1.0.3.513 rlm-12.2.2 2018/05/23 00:19:24
00:00:00 266MB | running on DESKTOP-DMG0KNN, pid=18740
00:00:00 266MB | 1 x Intel(R) Core(TM) i9-7980XE CPU @ 2.60GHz (18 cores, 36 logical) with 32440MB
00:00:00 266MB | Nvidia driver version 397.64
00:00:00 266MB | GPU 0: GeForce GTX 1080 Ti @ 1683MHz (compute 6.1) with 11264MB (11127MB available)
00:00:00 266MB | GPU 1: GeForce GTX 1080 Ti @ 1683MHz (compute 6.1) with 11264MB (8843MB available)
00:00:00 266MB | Windows 8 (version 6.2, build 9200)
00:00:00 266MB | soft limit for open files raised from 512 to 2048
00:00:00 266MB |
00:00:00 266MB | loading plugins from C:\Program Files\Blender Foundation\Blender\2.79\scripts\modules\Arnold-5.1.1.0-windows\bin\..\plugins ...
00:00:00 266MB | alembic_proc.dll: alembic uses Arnold 5.1.1.0
00:00:00 266MB | driver_display_callback.dll: driver_display_callback uses Arnold 5.1.1.0
00:00:00 266MB | loaded 2 plugins from 2 lib(s) in 0:00.00
00:00:00 266MB | BARNOLD: >>>
00:00:00 266MB | [LAMP] 'Area.002'
00:00:00 266MB WARNING | : could not set STRING parameter "decay_type"
00:00:00 266MB WARNING | O0::Area_002: could not set BOOL parameter "affect_diffuse"
00:00:00 266MB WARNING | O0::Area_002: could not set BOOL parameter "affect_specular"
00:00:00 266MB WARNING | O0::Area_002: could not set BOOL parameter "affect_volumetrics"
00:00:00 266MB | [LAMP] 'Area.001'
00:00:00 266MB WARNING | : could not set STRING parameter "decay_type"
00:00:00 266MB WARNING | O1::Area_001: could not set BOOL parameter "affect_diffuse"
00:00:00 266MB WARNING | O1::Area_001: could not set BOOL parameter "affect_specular"
00:00:00 266MB | [MESH] 'Suzanne.002'
00:00:00 284MB | mesh (0.066586)
00:00:00 295MB | node (0.047118)
00:00:00 279MB | [MESH] 'Suzanne.001'
00:00:00 297MB | mesh (0.063069)
00:00:00 308MB | node (0.046324)
00:00:00 292MB | [LAMP] 'Area'
00:00:00 292MB WARNING | : could not set STRING parameter "decay_type"
00:00:00 292MB | [MESH] 'Suzanne'
00:00:00 307MB | mesh (0.062458)
00:00:00 318MB | node (0.046710)
00:00:00 302MB | [MESH] 'Plane'
00:00:00 302MB | mesh (0.001537)
00:00:00 302MB | node (0.001349)
00:00:00 302MB | [CAMERA] 'Camera'
00:00:00 302MB | skip (unsupported)
00:00:00 302MB WARNING | options.max_subdivisions: use type BYTE, not INT (converted automatically)
00:00:00 302MB | BARNOLD: <<<
00:00:00 302MB |
00:00:00 302MB | authorizing ...
00:00:00 303MB | [rlm] authorized for "arnold 21990101" from server localhost in 0:00.08
00:00:00 303MB |
00:00:00 303MB | [color_manager] no color manager is active
00:00:00 303MB | [color_manager] rendering color space is "linear" with declared chromaticities:
00:00:00 303MB | r(0.6400, 0.3300) g(0.3000, 0.6000) b(0.1500, 0.0600) and w(0.3127, 0.3290)
00:00:00 313MB |
00:00:00 313MB | there are 3 lights and 5 objects:
00:00:00 313MB | 1 persp_camera
00:00:00 313MB | 3 disk_light
00:00:00 313MB | 1 utility
00:00:00 313MB | 4 standard_surface
00:00:00 313MB | 1 gaussian_filter
00:00:00 313MB | 4 polymesh
00:00:00 313MB | 1 list_aggregate
00:00:00 313MB | 1 driver_display_callback
00:00:00 313MB |
00:00:00 313MB | rendering image at 960 x 540, 2 AA samples
00:00:00 313MB | AA sample clamp <disabled>
00:00:00 313MB | diffuse samples 2 / depth 1
00:00:00 313MB | specular samples 2 / depth 1
00:00:00 313MB | transmission samples 2 / depth 8
00:00:00 313MB | volume indirect <disabled by depth>
00:00:00 313MB | total depth 10
00:00:00 313MB | bssrdf samples 2
00:00:00 313MB | transparency depth 10
00:00:00 313MB | initializing 17 nodes ...
00:00:00 308MB | creating root object list ...
00:00:00 308MB | node initialization done in 0:00.01 (multithreaded)
00:00:00 308MB | updating 18 nodes ...
00:00:00 309MB | O1::Area_001: disk_light using 1 sample, 2 volume samples
00:00:00 309MB | O4::Area: disk_light using 1 sample, 2 volume samples
00:00:00 309MB | O0::Area_002: disk_light using 1 sample, 2 volume samples
00:00:00 309MB | scene bounds: (-11.2780485 -6.24652958 -0.700345218) -> (18.7206364 6.85765314 3.8126986)
00:00:00 309MB | node update done in 0:00.00 (multithreaded)
00:00:00 309MB | [aov] parsing 1 output statements ...
00:00:00 309MB | [aov] registered driver: "__driver" (driver_display_callback)
00:00:00 309MB | [aov] * "RGBA" of type RGBA filtered by "__filter" (gaussian_filter)
00:00:00 309MB | [aov] done preparing 2 AOVs for 1 output to 1 driver (0 deep AOVs)
00:00:00 309MB | starting 36 bucket workers of size 64x64 ...
00:00:00 331MB | [accel] list_aggregate bvh4 done - 0:00.00 (wall time) - 4 prims, 1 key
00:00:00 332MB | [accel] polymesh bvh4 done - 0:00.00 (wall time) - 3328 prims, 1 key
00:00:00 339MB | [accel] polymesh bvh4 done - 0:00.00 (wall time) - 125952 prims, 1 key
00:00:00 337MB | [accel] polymesh bvh4 done - 0:00.01 (wall time) - 125952 prims, 1 key
00:00:00 339MB | [accel] polymesh bvh4 done - 0:00.00 (wall time) - 125952 prims, 1 key
00:00:01 341MB | 0% done - 83 rays/pixel
00:00:01 342MB | 5% done - 79 rays/pixel
00:00:01 342MB | 10% done - 84 rays/pixel
00:00:01 343MB | 15% done - 92 rays/pixel
00:00:01 344MB | 20% done - 98 rays/pixel
00:00:02 344MB | 25% done - 86 rays/pixel
00:00:02 344MB | 30% done - 85 rays/pixel
00:00:02 345MB | 35% done - 87 rays/pixel
00:00:02 345MB | 40% done - 89 rays/pixel
00:00:02 339MB | 45% done - 85 rays/pixel
00:00:02 340MB | 50% done - 81 rays/pixel
00:00:02 340MB | 55% done - 82 rays/pixel
00:00:02 340MB | 60% done - 89 rays/pixel
00:00:03 340MB | 65% done - 86 rays/pixel
00:00:03 341MB | 70% done - 92 rays/pixel
00:00:03 341MB | 75% done - 92 rays/pixel
00:00:03 341MB | 80% done - 102 rays/pixel
00:00:03 341MB | 85% done - 105 rays/pixel
00:00:03 341MB | 90% done - 104 rays/pixel
00:00:03 341MB | 95% done - 105 rays/pixel
00:00:03 341MB | 100% done - 131 rays/pixel
00:00:03 312MB | render done in 0:03.144
00:00:03 312MB | render done
00:00:03 312MB |
00:00:03 312MB | -----------------------------------------------------------------------------------
00:00:03 312MB | scene creation time:
00:00:03 312MB | plugin loading 0:00.00
00:00:03 312MB | unaccounted 0:00.50
00:00:03 312MB | total 0:00.50 ( 1.53% machine utilization)
00:00:03 312MB | -----------------------------------------------------------------------------------
00:00:03 312MB | frame:
00:00:03 312MB | node init 0:00.01
00:00:03 312MB | sanity checks 0:00.00
00:00:03 312MB | rendering 0:03.14
00:00:03 312MB | mesh processing 0:00.00
00:00:03 312MB | threads blocked 0:00.06
00:00:03 312MB | accel. building 0:00.02
00:00:03 312MB | output driver 0:00.00
00:00:03 312MB | pixel rendering 0:03.04
00:00:03 312MB | unaccounted 0:00.09
00:00:03 312MB | total 0:03.25 (91.70% machine utilization)
00:00:03 312MB | -----------------------------------------------------------------------------------
00:00:03 312MB | top session self-times by category:
00:00:03 312MB | BVH::intersect 0:00.95 (26.7%)
00:00:03 312MB | O5::Suzanne 0:00.36 (10.1%)
00:00:03 312MB | root 0:00.25 (7.1%)
00:00:03 312MB | O3::Suzanne_001 0:00.13 (3.6%)
00:00:03 312MB | O6::Plane 0:00.10 (3.1%)
00:00:03 312MB | O2::Suzanne_002 0:00.10 (2.8%)
00:00:03 312MB | polymesh::intersect 0:00.69 (19.5%)
00:00:03 312MB | O5::Suzanne 0:00.36 (10.2%)
00:00:03 312MB | O3::Suzanne_001 0:00.13 (3.7%)
00:00:03 312MB | O6::Plane 0:00.11 (3.3%)
00:00:03 312MB | O2::Suzanne_002 0:00.08 (2.2%)
00:00:03 312MB | surface closure 0:00.53 (15.0%)
00:00:03 312MB | M3::Material_002 0:00.31 (8.9%)
00:00:03 312MB | M2::Material_000 0:00.09 (2.6%)
00:00:03 312MB | M0::Material_004 0:00.06 (1.8%)
00:00:03 312MB | M1::Material_001 0:00.06 (1.8%)
00:00:03 312MB | worker waiting 0:00.46 (13.0%)
00:00:03 312MB | AiLightsPrepare 0:00.31 (8.9%)
00:00:03 312MB | O6::Plane 0:00.18 (5.3%)
00:00:03 312MB | O5::Suzanne 0:00.05 (1.4%)
00:00:03 312MB | O3::Suzanne_001 0:00.04 (1.2%)
00:00:03 312MB | O2::Suzanne_002 0:00.03 (1.0%)
00:00:03 312MB | standard_surface 0:00.17 (4.8%)
00:00:03 312MB | M3::Material_002 0:00.08 (2.5%)
00:00:03 312MB | M2::Material_000 0:00.04 (1.2%)
00:00:03 312MB | M1::Material_001 0:00.02 (0.6%)
00:00:03 312MB | M0::Material_004 0:00.01 (0.5%)
00:00:03 312MB | TraceShadow 0:00.14 (3.9%)
00:00:03 312MB | ray traversal+intersection 0:00.10 (2.9%)
00:00:03 312MB | thread blocked 0:00.08 (2.4%)
00:00:03 312MB | -----------------------------------------------------------------------------------
00:00:03 312MB | top session self-times by node:
00:00:03 312MB | polymesh:O5::Suzanne 0:00.84 (23.6%)
00:00:03 312MB | polymesh::intersect 0:00.36 (10.2%)
00:00:03 312MB | BVH::intersect 0:00.36 (10.1%)
00:00:03 312MB | AiLightsPrepare 0:00.05 (1.4%)
00:00:03 312MB | thread blocked 0:00.04 (1.3%)
00:00:03 312MB | polymesh:O6::Plane 0:00.54 (15.2%)
00:00:03 312MB | AiLightsPrepare 0:00.18 (5.3%)
00:00:03 312MB | polymesh::intersect 0:00.11 (3.3%)
00:00:03 312MB | BVH::intersect 0:00.10 (3.1%)
00:00:03 312MB | TraceShadow 0:00.09 (2.5%)
00:00:03 312MB | ray traversal+intersection 0:00.03 (1.0%)
00:00:03 312MB | worker waiting 0:00.46 (13.0%)
00:00:03 312MB | standard_surface:M3::Material_002 0:00.44 (12.4%)
00:00:03 312MB | surface closure 0:00.31 (8.9%)
00:00:03 312MB | ray traversal+intersection 0:00.02 (0.7%)
00:00:03 312MB | polymesh:O3::Suzanne_001 0:00.33 (9.3%)
00:00:03 312MB | polymesh::intersect 0:00.13 (3.7%)
00:00:03 312MB | BVH::intersect 0:00.13 (3.6%)
00:00:03 312MB | AiLightsPrepare 0:00.04 (1.2%)
00:00:03 312MB | polymesh:O2::Suzanne_002 0:00.28 (8.0%)
00:00:03 312MB | BVH::intersect 0:00.10 (2.8%)
00:00:03 312MB | polymesh::intersect 0:00.08 (2.2%)
00:00:03 312MB | AiLightsPrepare 0:00.03 (1.0%)
00:00:03 312MB | thread blocked 0:00.03 (1.0%)
00:00:03 312MB | TraceShadow 0:00.02 (0.6%)
00:00:03 312MB | list_aggregate:root 0:00.25 (7.1%)
00:00:03 312MB | BVH::intersect 0:00.25 (7.1%)
00:00:03 312MB | standard_surface:M2::Material_000 0:00.14 (4.1%)
00:00:03 312MB | surface closure 0:00.09 (2.6%)
00:00:03 312MB | standard_surface:M1::Material_001 0:00.09 (2.6%)
00:00:03 312MB | surface closure 0:00.06 (1.8%)
00:00:03 312MB | standard_surface:M0::Material_004 0:00.09 (2.5%)
00:00:03 312MB | surface closure 0:00.06 (1.8%)
00:00:03 312MB | -----------------------------------------------------------------------------------
00:00:03 312MB | memory consumed in MB:
00:00:03 312MB | at startup 238.30
00:00:03 312MB | plugins 0.99
00:00:03 312MB | AOV samples 18.58
00:00:03 312MB | output buffers 16.01
00:00:03 312MB | node overhead 0.01
00:00:03 312MB | message passing 0.07
00:00:03 312MB | memory pools 28.05
00:00:03 312MB | geometry 12.76
00:00:03 312MB | polymesh 12.76
00:00:03 312MB | accel. structs 12.46
00:00:03 312MB | strings 12.01
00:00:03 312MB | texture cache 0.00
00:00:03 312MB | profiler 5.23
00:00:03 312MB | unaccounted 24.53
00:00:03 312MB | total peak 363.76
00:00:03 312MB | -----------------------------------------------------------------------------------
00:00:03 312MB | ray counts: ( /pixel, /sample) (% total) (avg. hits) (max hits)
00:00:03 312MB | camera 2140830 ( 4.13, 1.00) ( 4.67%) ( 1.64) ( 11)
00:00:03 312MB | shadow 23483754 ( 45.30, 10.97) ( 51.23%) ( 0.71) ( 11)
00:00:03 312MB | diffuse_reflect 11841069 ( 22.84, 5.53) ( 25.83%) ( 0.55) ( 11)
00:00:03 312MB | specular_reflect 8376200 ( 16.16, 3.91) ( 18.27%) ( 0.75) ( 11)
00:00:03 312MB | total 45841853 ( 88.43, 21.41) (100.00%) ( 0.72) ( 11)
00:00:03 312MB | by ray depth: 0 1 2
00:00:03 312MB | total 17.8% 67.3% 14.9%
00:00:03 312MB | -----------------------------------------------------------------------------------
00:00:03 312MB | shader calls ( /pixel, /sample) (% total)
00:00:03 312MB | primary 10452312 ( 20.16, 4.88) ( 60.64%)
00:00:03 312MB | transparent_shadow 6783141 ( 13.08, 3.17) ( 39.36%)
00:00:03 312MB | total 17235453 ( 33.25, 8.05) (100.00%)
00:00:03 312MB | by ray depth: 0 1 2
00:00:03 312MB | total 22.2% 60.2% 17.7%
00:00:03 312MB | -----------------------------------------------------------------------------------
00:00:03 312MB | geometry: (% hit ) (instances) ( init mem, final mem)
00:00:03 312MB | lists 1 (100.0%) ( 0) ( 0.00, 0.00)
00:00:03 312MB | polymeshes 4 (100.0%) ( 0) ( 29.26, 12.76)
00:00:03 312MB | -----------------------------------------------------------------------------------
00:00:03 312MB | geometric elements: ( min) ( avg.) ( max)
00:00:03 312MB | polygons 381184 ( 3328) ( 95296.0) ( 125952)
00:00:03 312MB | -----------------------------------------------------------------------------------
00:00:03 312MB | triangle tessellation: ( min) ( avg.) ( max) (/ element) (% total)
00:00:03 312MB | polymeshes 762368 ( 6656) ( 190592.0) ( 251904) ( 2.00) (100.00%)
00:00:03 312MB | unique triangles 762368
00:00:03 312MB | memory use (in MB) 12.76
00:00:03 312MB | vertices 4.38
00:00:03 312MB | vertex indices 3.08
00:00:03 312MB | packed normals 1.45
00:00:03 312MB | normal indices 3.08
00:00:03 312MB | uniform indices 0.77
00:00:03 312MB | largest polymeshes by triangle count:
00:00:03 312MB | 251904 tris -- O3::Suzanne_001
00:00:03 312MB | 251904 tris -- O5::Suzanne
00:00:03 312MB | 251904 tris -- O2::Suzanne_002
00:00:03 312MB | 6656 tris -- O6::Plane
00:00:03 312MB | -----------------------------------------------------------------------------------
00:00:03 312MB | acceleration structures: (% total)
00:00:03 312MB | bvh 5 (100.00%)
00:00:03 312MB | total 5 (100.00%)
00:00:03 312MB | -----------------------------------------------------------------------------------
00:00:03 312MB | number of warnings, warning type:
00:00:03 312MB | 1: %s.%s: use type BYTE, not INT (converted automatically)
00:00:03 312MB | 12: %s: could not set %s parameter "%s"
00:00:03 312MB | 3: %s: could not set STRING parameter "%s"
00:00:03 312MB | -----------------------------------------------------------------------------------
00:00:03 307MB |
00:00:03 307MB | releasing resources
00:00:03 266MB | unloading 2 plugins
00:00:03 266MB | closing alembic_proc.dll ...
00:00:03 266MB | closing driver_display_callback.dll ...
00:00:03 265MB | unloading plugins done
00:00:03 265MB | Arnold shutdown
>>> free: [3.655241]: <bpy_struct, ARNOLD_RENDER at 0x000001DC64FFA6E8>
ordered
OBArea.002
OBArea.001
OBSuzanne.002
OBSuzanne.001
OBArea
OBSuzanne
OBPlane
OBCamera
brecht
July 1, 2018, 12:21pm
27
The code in this callback is only for final renders. I suggest to add some print statements in there to figure out of you are getting the correct parameters.
For the viewport, the mechanism is quite different and you need to draw the image with OpenGL in the view_draw()
method.
Like this?
def view_draw(engine, context):
#print(">>> view_draw [%f]:" % time.clock(), engine)
try:
region = context.region
v3d = context.space_data
rv3d = context.region_data
data = {}
_camera = {}
ipr = engine._ipr
width = region.width
height = region.height
view_matrix = rv3d.view_matrix
if view_matrix != ipr.view_matrix:
ipr.view_matrix = view_matrix.copy()
_camera['matrix'] = ('MATRIX', numpy.reshape(view_matrix.inverted().transposed(), -1))
view_perspective = rv3d.view_perspective
if view_perspective != ipr.view_perspective:
ipr.view_perspective = view_perspective
if view_perspective == 'CAMERA':
ipr.camera_data = _view_update_camera(region.width / region.height, v3d, rv3d, _camera)
elif view_perspective == 'PERSP':
ipr.camera_data = _view_update_persp(v3d, _camera)
else:
# TODO: orpho
return
elif view_perspective == 'CAMERA':
cdata = v3d.camera.data
fit = cdata.sensor_fit
sensor = cdata.sensor_height if fit == 'VERTICAL' else cdata.sensor_width
offset_x, offset_y = rv3d.view_camera_offset
camera_data = (rv3d.view_camera_zoom, fit, sensor, cdata.lens,
offset_x, offset_y, cdata.shift_x, cdata.shift_y)
if camera_data != ipr.camera_data:
ipr.camera_data = _view_update_camera(region.width / region.height, v3d, rv3d, _camera)
elif view_perspective == 'PERSP':
lens = v3d.lens
if lens != ipr.camera_data[0]:
_camera['fov'] = ('FLOAT', math.degrees(2 * math.atan(64.0 / (2 * lens))))
ipr.camera_data = (lens, )
else:
# TODO: orpho
return
if _camera:
data.setdefault('nodes', {})['__camera'] = _camera
(width, height), rect = ipr.update(width, height, data)
v = bgl.Buffer(bgl.GL_FLOAT, 4)
bgl.glGetFloatv(bgl.GL_VIEWPORT, v)
vw = v[2]
vh = v[3]
bgl.glRasterPos2f(0, vh - 1.0)
bgl.glPixelZoom(vw / width, -vh / height)
bgl.glDrawPixels(width, height, bgl.GL_RGBA, bgl.GL_FLOAT,
bgl.Buffer(bgl.GL_FLOAT, len(rect), rect))
bgl.glPixelZoom(1.0, 1.0)
bgl.glRasterPos2f(0, 0)
except:
print("~" * 30)
traceback.print_exc()
print("~" * 30)
And I’m using the callback from the start of this post for the IPR and using it like this, which also appears to be properly logging/updating in realtime:
cb = arnold.AtRenderUpdateCallback(callback)
arnold.AiNodeSetPtr(driver, "callback_data", cb)
Check it out! Getting really close, not sure why I’m getting a terrifying crash log but I think we’re on to something:
@brecht I wanted to thank you for all your help in pointing me in the right direction for this. I’ve finally managed to get the display driver working after editing the Arnold SDK a bit.
kilon
July 4, 2018, 10:45am
35
great work mate, never give up and you shall receive. Looks cool, keep the up the great work .
1 Like