MeasureIt: More conversion of APIs (WIP)

Still the render is not working. The idea is replace the old system generating a image with alpha background and only the measures.
This commit is contained in:
Antonio Vazquez 2018-12-05 19:49:59 +01:00
parent a4e7c60ac8
commit 0c494907cf
3 changed files with 90 additions and 254 deletions

View File

@ -250,11 +250,8 @@ def register():
description="Save an image with measures over"
" render image",
default=False)
Scene.measureit_render_type = EnumProperty(items=(('1', "*Current", "Use current render"),
('2', "OpenGL", ""),
('3', "Animation OpenGL", ""),
('4', "Image", ""),
('5', "Animation", "")),
Scene.measureit_render_type = EnumProperty(items=(('1', "Frame", "Render current frame"),
('2', "Animation", "")),
name="Render type",
description="Type of render image")
Scene.measureit_sum = EnumProperty(items=(('99', "-", "Select a group for sum"),

View File

@ -1740,75 +1740,22 @@ class MEASUREIT_OT_RenderSegment(Operator):
self.report({'ERROR'}, camera_msg)
return {'FINISHED'}
# -----------------------------
# Use default render
# Frame render
# -----------------------------
if scene.measureit_render_type == "1":
# noinspection PyBroadException
try:
result = bpy.data.images['Render Result']
bpy.ops.render.render()
except:
bpy.ops.render.render()
print("MeasureIt: Using current render image on buffer")
if render_main(self, context) is True:
self.report({'INFO'}, msg)
# -----------------------------
# OpenGL image
# -----------------------------
if scene.measureit_render_type == "2":
self.set_camera_view()
self.set_only_render(True)
print("MeasureIt: Rendering opengl image")
bpy.ops.render.opengl()
if render_main(self, context) is True:
self.report({'INFO'}, msg)
self.set_only_render(False)
# -----------------------------
# OpenGL Animation
# -----------------------------
if scene.measureit_render_type == "3":
oldframe = scene.frame_current
self.set_camera_view()
self.set_only_render(True)
flag = False
# loop frames
for frm in range(scene.frame_start, scene.frame_end + 1):
scene.frame_set(frm)
print("MeasureIt: Rendering opengl frame %04d" % frm)
bpy.ops.render.opengl()
flag = render_main(self, context, True)
if flag is False:
break
self.set_only_render(False)
scene.frame_current = oldframe
if flag is True:
self.report({'INFO'}, msg)
# -----------------------------
# Image
# -----------------------------
if scene.measureit_render_type == "4":
print("MeasureIt: Rendering image")
bpy.ops.render.render()
if render_main(self, context) is True:
self.report({'INFO'}, msg)
# -----------------------------
# Animation
# -----------------------------
if scene.measureit_render_type == "5":
if scene.measureit_render_type == "2":
oldframe = scene.frame_current
flag = False
# loop frames
for frm in range(scene.frame_start, scene.frame_end + 1):
scene.frame_set(frm)
print("MeasureIt: Rendering frame %04d" % frm)
bpy.ops.render.render()
flag = render_main(self, context, True)
if flag is False:
break

View File

@ -25,7 +25,7 @@
# ----------------------------------------------------------
# noinspection PyUnresolvedReferences
import bpy
# noinspection PyUnresolvedReferences
import gpu
import bgl
# noinspection PyUnresolvedReferences
import blf
@ -46,216 +46,108 @@ from .measureit_geometry import *
#
# -------------------------------------------------------------
def render_main(self, context, animation=False):
# noinspection PyBroadException,PyBroadException
# Save old info
settings = bpy.context.scene.render.image_settings
depth = settings.color_depth
settings.color_depth = '8'
# noinspection PyBroadException
try:
scene = context.scene
# Get object list
objlist = context.scene.objects
# --------------------
# Get resolution
# --------------------
scene = bpy.context.scene
render_scale = scene.render.resolution_percentage / 100
width = int(scene.render.resolution_x * render_scale)
height = int(scene.render.resolution_y * render_scale)
# ---------------------------------------
# Get output path
# ---------------------------------------
temp_path = path.realpath(bpy.app.tempdir)
if len(temp_path) > 0:
outpath = path.join(temp_path, "measureit_tmp_render.png")
else:
self.report({'ERROR'},
"MeasureIt: Unable to save temporary render image. Define a valid temp path")
settings.color_depth = depth
return False
# Get object list
scene = context.scene
objlist = context.scene.objects
# --------------------
# Get resolution
# --------------------
render_scale = scene.render.resolution_percentage / 100
width = int(scene.render.resolution_x * render_scale)
height = int(scene.render.resolution_y * render_scale)
# Get Render Image
img = get_render_image(outpath)
if img is None:
self.report({'ERROR'},
"MeasureIt: Unable to save temporary render image. Define a valid temp path")
settings.color_depth = depth
return False
# --------------------------------------
# Loop to draw all lines in Offsecreen
# --------------------------------------
offscreen = gpu.types.GPUOffScreen(width, height)
view_matrix = scene.camera.matrix_world.inverted()
projection_matrix = scene.camera.calc_matrix_camera(context.depsgraph, x=width, y=height)
with offscreen.bind():
bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)
gpu.matrix.reset()
gpu.matrix.load_matrix(view_matrix)
gpu.matrix.load_projection_matrix(projection_matrix)
# -----------------------------
# Calculate rows and columns
# Loop to draw all objects
# -----------------------------
tile_x = 240
tile_y = 216
row_num = ceil(height / tile_y)
col_num = ceil(width / tile_x)
print("MeasureIt: Image divided in " + str(row_num) + "x" + str(col_num) + " tiles")
for myobj in objlist:
if myobj.visible_get() is True:
if 'MeasureGenerator' in myobj:
op = myobj.MeasureGenerator[0]
draw_segments(context, myobj, op, None, None)
# -----------------------------
# Loop to draw all debug
# -----------------------------
if scene.measureit_debug is True:
selobj = bpy.context.selected_objects
for myobj in selobj:
if scene.measureit_debug_objects is True:
draw_object(context, myobj, None, None)
elif scene.measureit_debug_object_loc is True:
draw_object(context, myobj, None, None)
if scene.measureit_debug_vertices is True:
draw_vertices(context, myobj, None, None)
elif scene.measureit_debug_vert_loc is True:
draw_vertices(context, myobj, None, None)
if scene.measureit_debug_edges is True:
draw_edges(context, myobj, None, None)
if scene.measureit_debug_faces is True or scene.measureit_debug_normals is True:
draw_faces(context, myobj, None, None)
# -----------------------------
# Draw a rectangle frame
# -----------------------------
if scene.measureit_rf is True:
rfcolor = scene.measureit_rf_color
rfborder = scene.measureit_rf_border
rfline = scene.measureit_rf_line
# pixels out of visible area
cut4 = (col_num * tile_x * 4) - width * 4 # pixels aout of drawing area
totpixel4 = width * height * 4 # total pixels RGBA
viewport_info = bgl.Buffer(bgl.GL_INT, 4)
bgl.glGetIntegerv(bgl.GL_VIEWPORT, viewport_info)
bgl.glLineWidth(rfline)
x1 = rfborder
x2 = width - rfborder
y1 = int(ceil(rfborder / (width / height)))
y2 = height - y1
draw_rectangle((x1, y1), (x2, y2), rfcolor)
# Load image on memory
img.gl_load(frame=0, filter=bgl.GL_NEAREST, mag=bgl.GL_NEAREST)
tex = img.bindcode
buffer = bgl.Buffer(bgl.GL_BYTE, width * height * 4)
bgl.glReadBuffer(bgl.GL_BACK)
bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, buffer)
# --------------------------------------------
# Create output image (to apply texture)
# --------------------------------------------
if "measureit_output" in bpy.data.images:
out_img = bpy.data.images["measureit_output"]
if out_img is not None:
bpy.data.images.remove(out_img)
offscreen.free()
out = bpy.data.images.new("measureit_output", width, height)
tmp_pixels = [1] * totpixel4
# -----------------------------
# Create image
# -----------------------------
image_name = "measureit_output"
if not image_name in bpy.data.images:
bpy.data.images.new(image_name, width, height)
# --------------------------------
# Loop for all tiles
# --------------------------------
for row in range(row_num):
for col in range(col_num):
buffer = bgl.Buffer(bgl.GL_FLOAT, width * height * 4)
bgl.glDisable(bgl.GL_SCISSOR_TEST) # if remove this line, get blender screenshot not image
bgl.glViewport(0, 0, tile_x, tile_y)
image = bpy.data.images[image_name]
image.scale(width, height)
image.pixels = [v / 255 for v in buffer]
bgl.glMatrixMode(bgl.GL_PROJECTION)
gpu.matrix.load_identity()
# Saves image
if image is not None and (scene.measureit_render is True or animation is True):
ren_path = bpy.context.scene.render.filepath
filename = "mit_frame"
if len(ren_path) > 0:
if ren_path.endswith(path.sep):
initpath = path.realpath(ren_path) + path.sep
else:
(initpath, filename) = path.split(ren_path)
# defines ortographic view for single tile
x1 = tile_x * col
y1 = tile_y * row
bgl.gluOrtho2D(x1, x1 + tile_x, y1, y1 + tile_y)
ftxt = "%04d" % scene.frame_current
outpath = path.realpath(path.join(initpath, filename + ftxt + ".png"))
save_image(self, outpath, image)
# Clear
bgl.glClearColor(0.0, 0.0, 0.0, 0.0)
bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT)
bgl.glEnable(bgl.GL_TEXTURE_2D)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, tex)
# defines drawing area
bgl.glBegin(bgl.GL_QUADS)
bgl.glColor3f(1.0, 1.0, 1.0)
bgl.glTexCoord2f(0.0, 0.0)
bgl.glVertex2f(0.0, 0.0)
bgl.glTexCoord2f(1.0, 0.0)
bgl.glVertex2f(width, 0.0)
bgl.glTexCoord2f(1.0, 1.0)
bgl.glVertex2f(width, height)
bgl.glTexCoord2f(0.0, 1.0)
bgl.glVertex2f(0.0, height)
bgl.glEnd()
# -----------------------------
# Loop to draw all lines
# -----------------------------
for myobj in objlist:
if myobj.visible_get() is True:
if 'MeasureGenerator' in myobj:
op = myobj.MeasureGenerator[0]
draw_segments(context, myobj, op, None, None)
# -----------------------------
# Loop to draw all debug
# -----------------------------
if scene.measureit_debug is True:
selobj = bpy.context.selected_objects
for myobj in selobj:
if scene.measureit_debug_objects is True:
draw_object(context, myobj, None, None)
elif scene.measureit_debug_object_loc is True:
draw_object(context, myobj, None, None)
if scene.measureit_debug_vertices is True:
draw_vertices(context, myobj, None, None)
elif scene.measureit_debug_vert_loc is True:
draw_vertices(context, myobj, None, None)
if scene.measureit_debug_edges is True:
draw_edges(context, myobj, None, None)
if scene.measureit_debug_faces is True or scene.measureit_debug_normals is True:
draw_faces(context, myobj, None, None)
if scene.measureit_rf is True:
rfcolor = scene.measureit_rf_color
rfborder = scene.measureit_rf_border
rfline = scene.measureit_rf_line
bgl.glLineWidth(rfline)
x1 = rfborder
x2 = width - rfborder
y1 = int(ceil(rfborder / (width / height)))
y2 = height - y1
draw_rectangle((x1, y1), (x2, y2), rfcolor)
# --------------------------------
# copy pixels to temporary area
# --------------------------------
bgl.glFinish()
bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA, bgl.GL_FLOAT, buffer) # read image data
for y in range(tile_y):
# final image pixels position
p1 = (y * width * 4) + (row * tile_y * width * 4) + (col * tile_x * 4)
p2 = p1 + (tile_x * 4)
# buffer pixels position
b1 = y * width * 4
b2 = b1 + (tile_x * 4)
if p1 < totpixel4: # avoid pixel row out of area
if col == col_num - 1: # avoid pixel columns out of area
p2 -= cut4
b2 -= cut4
tmp_pixels[p1:p2] = buffer[b1:b2]
# -----------------------
# Copy temporary to final
# -----------------------
out.pixels = tmp_pixels[:] # Assign image data
img.gl_free() # free opengl image memory
# delete image
bpy.data.images.remove(img)
# remove temp file
remove(outpath)
# reset
bgl.glEnable(bgl.GL_SCISSOR_TEST)
# -----------------------
# restore opengl defaults
# -----------------------
bgl.glLineWidth(1)
bgl.glDisable(bgl.GL_BLEND)
# Saves image
if out is not None and (scene.measureit_render is True or animation is True):
ren_path = bpy.context.scene.render.filepath
filename = "mit_frame"
if len(ren_path) > 0:
if ren_path.endswith(path.sep):
initpath = path.realpath(ren_path) + path.sep
else:
(initpath, filename) = path.split(ren_path)
ftxt = "%04d" % scene.frame_current
outpath = path.realpath(path.join(initpath, filename + ftxt + ".png"))
save_image(self, outpath, out)
settings.color_depth = depth
return True
except:
settings.color_depth = depth
print("Unexpected error:" + str(exc_info()))
self.report({'ERROR'}, "MeasureIt: Unable to create render image. Be sure the output render path is correct")
return False
# restore default value
settings.color_depth = depth
# --------------------------------------------------------------------