From 11ef1af240943e4a93368eb090245f5745163c96 Mon Sep 17 00:00:00 2001 From: huiyao8761380 Date: Fri, 30 Aug 2019 18:59:00 +0800 Subject: [PATCH 01/27] 1.align_pick_points.py MyFirstStep --- align_pick_points.py | 367 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 367 insertions(+) create mode 100644 align_pick_points.py diff --git a/align_pick_points.py b/align_pick_points.py new file mode 100644 index 0000000..3463d98 --- /dev/null +++ b/align_pick_points.py @@ -0,0 +1,367 @@ +# Copyright (C) 2019 Christopher Gearhart +# chris@bblanimation.com +# http://bblanimation.com/ +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# System imports +import time +import numpy as np + +# Blender imports +import bpy +import blf +from bpy.types import Operator +from mathutils import Matrix +from bpy_extras import view3d_utils + +# Addon imports +from ..functions import * + + +def draw_callback_px(self, context): + + font_id = 0 # XXX, need to find out how best to get this. + + # draw some text + y = context.region.height + dims = blf.dimensions(0, 'A') + + blf.position(font_id, 10, y - 20 - dims[1], 0) + blf.size(font_id, 20, 72) + + if context.area.x == self.area_align.x: + blf.draw(font_id, "Align: "+ self.align_msg) + points = [self.obj_align.matrix_world * p for p in self.align_points] + color = (1,0,0,1) + else: + blf.draw(font_id, "Base: " + self.base_msg) + points = [self.obj_align.matrix_world * p for p in self.base_points] + color = (0,1,0,1) + + draw_3d_points_revised(context, points, color, 4) + + for i, vec in enumerate(points): + ind = str(i) + draw_3d_text(context, font_id, ind, vec) + +class OBJECT_OT_align_pick_points(Operator): + """Align two objects with 3 or more pair of picked points""" + bl_idname = "object.align_picked_points" + bl_label = "Align: Picked Points" + # bl_options = {"REGISTER", "UNDO"} + + ################################################ + # Blender Operator methods + + @classmethod + def poll(cls, context): + condition_1 = len(context.selected_objects) == 2 + condition_2 = context.object.type == 'MESH' + return condition_1 and condition_2 + + def modal(self, context, event): + + tag_redraw_areas("VIEW_3D") + + if len(self.align_points) < 3: + self.align_msg = "Pick at least %s more pts" % str(3 - len(self.align_points)) + else: + self.align_msg = "More points optional" + + if len(self.base_points) < 3: + self.base_msg = "Pick at last %s more pts" % str(3 - len(self.base_points)) + else: + self.base_msg = "More points optional" + + + if len(self.base_points) > 3 and len(self.align_points) > 3 and len(self.base_points) != len(self.align_points): + + if len(self.align_points) < len(self.base_points): + self.align_msg = "Pick %s more pts to match" % str(len(self.base_points) - len(self.align_points)) + else: + self.base_msg = "Pick %s more pts to match" % str(len(self.align_points) - len(self.base_points)) + + if len(self.base_points) == len(self.align_points) and len(self.base_points) >= 3: + self.base_msg = "Hit Enter to Align" + self.align_msg = "Hit Enter to Align" + + + if event.type == 'LEFTMOUSE' and event.value == 'PRESS': + + ray_max = 10000 + + if event.mouse_x > self.area_align.x and event.mouse_x < self.area_align.x + self.area_align.width: + + for reg in self.area_align.regions: + if reg.type == 'WINDOW': + region = reg + for spc in self.area_align.spaces: + if spc.type == 'VIEW_3D': + rv3d = spc.region_3d + + #just transform the mouse window coords into the region coords + coord = (event.mouse_x - region.x, event.mouse_y - region.y) + + #are the cords the problem + print('align cords: ' + str(coord)) + print(str((event.mouse_region_x, event.mouse_region_y))) + + view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord) + ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord) + ray_target = ray_origin + (view_vector * ray_max) + + print('in the align object window') + (d, (ok,hit, normal, face_index)) = ray_cast_region2d(region, rv3d, coord, self.obj_align) + if hit: + print('hit! align_obj %s' % self.obj_align.name) + #local space of align object + self.align_points.append(hit) + + else: + + for reg in self.area_base.regions: + if reg.type == 'WINDOW': + region = reg + for spc in self.area_base.spaces: + if spc.type == 'VIEW_3D': + rv3d = spc.region_3d + + coord = (event.mouse_x - region.x, event.mouse_y - region.y) + view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord) + ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord) + ray_target = ray_origin + (view_vector * ray_max) + + print('in the base object window') + (d, (ok,hit, normal, face_index)) = ray_cast_region2d(region, rv3d, coord, self.obj_base) + if ok: + print('hit! base_obj %s' % self.obj_base.name) + #points in local space of align object + self.base_points.append(self.obj_align.matrix_world.inverted() * self.obj_base.matrix_world * hit) + + + return {'RUNNING_MODAL'} + + elif event.type == 'RIGHTMOUSE' and event.value == 'PRESS': + + if event.mouse_x > self.area_align.x and event.mouse_x < self.area_align.x + self.area_align.width: + self.align_points.pop() + else: + self.base_points.pop() + + return {'RUNNING_MODAL'} + + + if event.type in {'WHEELUPMOUSE', 'WHEELDOWNMOUSE'}: + + return {'PASS_THROUGH'} + + if self.modal_state == 'NAVIGATING': + + if (event.type in {'MOUSEMOVE', + 'MIDDLEMOUSE', + 'NUMPAD_2', + 'NUMPAD_4', + 'NUMPAD_6', + 'NUMPAD_8', + 'NUMPAD_1', + 'NUMPAD_3', + 'NUMPAD_5', + 'NUMPAD_7', + 'NUMPAD_9'} and event.value == 'RELEASE'): + + self.modal_state = 'WAITING' + return {'PASS_THROUGH'} + + + if (event.type in {'MIDDLEMOUSE', + 'NUMPAD_2', + 'NUMPAD_4', + 'NUMPAD_6', + 'NUMPAD_8', + 'NUMPAD_1', + 'NUMPAD_3', + 'NUMPAD_5', + 'NUMPAD_7', + 'NUMPAD_9'} and event.value == 'PRESS'): + + self.modal_state = 'NAVIGATING' + + return {'PASS_THROUGH'} + + elif event.type in {'ESC'}: + bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') + return {'CANCELLED'} + + elif event.type == 'RET': + + if len(self.align_points) >= 3 and len(self.base_points) >= 3 and len(self.align_points) == len(self.base_points): + bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') + self.de_localize(context) + self.align_obj(context) + + context.scene.objects.active = self.obj_align + self.obj_align.select = True + self.obj_base = True + + return {'FINISHED'} + + return {'RUNNING_MODAL'} + + def invoke(self, context, event): + self.modal_state = 'WAITING' + + self.start_time = time.time() + #capture some mouse info to pass to the draw handler + self.winx = event.mouse_x + self.winy = event.mouse_y + + self.regx = event.mouse_region_x + self.regy = event.mouse_region_y + + self.base_msg = 'Select 3 or more points' + self.align_msg = 'Select 3 or more points' + + + obj1_name = context.object.name + obj2_name = [obj for obj in context.selected_objects if obj != context.object][0].name + + for ob in context.scene.objects: + ob.select_set(False) + + bpy.context.view_layer.objects.active= None#context.scene.objects.active = None + + #I did this stupid method becuase I was unsure + #if some things were being "sticky" and not + #remembering where they were + obj1 = bpy.data.objects[obj1_name] + obj2 = bpy.data.objects[obj2_name] + + for ob in bpy.data.objects: + if ob.select_set(True): + print(ob.name) + + screen = context.window.screen + areas = [area.as_pointer() for area in screen.areas] + for area in screen.areas: + if area.type == 'VIEW_3D': + break + + #bpy.ops.view3d.toolshelf() #close the first toolshelf + override = context.copy() + override['area'] = area + + self.area_align = area + + bpy.ops.screen.area_split(direction='VERTICAL', factor=0.5, cursor=(100,-100))#bpy.ops.screen.area_split(override, direction='VERTICAL', factor=0.5, mouse_x=-100, mouse_y=-100) + #bpy.ops.view3d.toolshelf() #close the 2nd toolshelf + + bpy.context.view_layer.objects.active = obj1 + obj1.select_set(True) + obj2.select_set(False) + + bpy.ops.view3d.localview(override) + + obj1.select_set(False) + bpy.context.view_layer.objects.active = None + override = context.copy() + for area in screen.areas: + if area.as_pointer() not in areas: + override['area'] = area + self.area_base = area + bpy.ops.object.select_all(action = 'DESELECT') + bpy.context.view_layer.objects.active = obj2 + obj2.select_set(True) + override['selected_objects'] = [obj2] + override['selected_editable_objects'] = [obj2] + override['object'] = obj2 + override['active_object'] = obj2 + bpy.ops.view3d.localview(override) + break + + + self.obj_align = obj1 + self.obj_base = obj2 + + #hooray, we will raycast in local view! + self.align_points = [] + self.base_points = [] + + context.window_manager.modal_handler_add(self) + self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, (self, context), 'WINDOW', 'POST_PIXEL') + return {'RUNNING_MODAL'} + + ############################################# + # class methods + + def de_localize(self,context): + + override = context.copy() + override['area'] = self.area_align + bpy.ops.view3d.localview(override) + bpy.ops.view3d.view_selected(override) + + override['area'] = self.area_base + bpy.ops.view3d.localview(override) + bpy.ops.view3d.view_selected(override) + + #Crash Blender? + bpy.ops.screen.area_join(min_x=self.area_align.x,min_y=self.area_align.y, max_x=self.area_base.x, max_y=self.area_base.y) + bpy.ops.view3d.toolshelf() + + #ret = bpy.ops.screen.area_join(min_x=area_base.x,min_y=area_base.y, max_x=area_align.x, max_y=area_align.y) + + def align_obj(self,context): + + if len(self.align_points) != len(self.base_points): + if len(self.align_points) < len(self.base_points): + + self.base_points = self.base_points[0:len(self.align_points)] + else: + self.align_points = self.align_points[0:len(self.base_points)] + + A = np.zeros(shape = [3,len(self.base_points)]) + B = np.zeros(shape = [3,len(self.base_points)]) + + for i in range(0,len(self.base_points)): + V1 = self.align_points[i] + V2 = self.base_points[i] + + A[0][i], A[1][i], A[2][i] = V1[0], V1[1], V1[2] + B[0][i], B[1][i], B[2][i] = V2[0], V2[1], V2[2] + + + #test new method + settings = get_addon_preferences() + align_meth = settings.align_meth + + if align_meth == '0': #rigid transform + M = affine_matrix_from_points(A, B, shear=False, scale=False, usesvd=True) + elif align_meth == '1': # rot, loc, scale + M = affine_matrix_from_points(A, B, shear=False, scale=True, usesvd=True) + #else: #affine + #M = affine_matrix_from_points(A, B, shear=True, scale=True, usesvd=True) + + + new_mat = Matrix.Identity(4) + for n in range(0,4): + for m in range(0,4): + new_mat[n][m] = M[n][m] + + #because we calced transform in local space + #it's this easy to update the obj... + self.obj_align.matrix_world = self.obj_align.matrix_world * new_mat + + self.obj_align.update_tag() + context.scene.update() From 0455e661e281d27e84f4b4411a0180ff44423ad5 Mon Sep 17 00:00:00 2001 From: "0YSQD05YY1BMCM6\\Administrator" Date: Fri, 30 Aug 2019 19:08:35 +0800 Subject: [PATCH 02/27] 1align_pick_points.py for blender 2.8 api My first step --- operators/align_pick_points.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/operators/align_pick_points.py b/operators/align_pick_points.py index ad9dc34..3463d98 100644 --- a/operators/align_pick_points.py +++ b/operators/align_pick_points.py @@ -238,9 +238,9 @@ def invoke(self, context, event): obj2_name = [obj for obj in context.selected_objects if obj != context.object][0].name for ob in context.scene.objects: - ob.select = False + ob.select_set(False) - context.scene.objects.active = None + bpy.context.view_layer.objects.active= None#context.scene.objects.active = None #I did this stupid method becuase I was unsure #if some things were being "sticky" and not @@ -249,7 +249,7 @@ def invoke(self, context, event): obj2 = bpy.data.objects[obj2_name] for ob in bpy.data.objects: - if ob.select: + if ob.select_set(True): print(ob.name) screen = context.window.screen @@ -258,31 +258,31 @@ def invoke(self, context, event): if area.type == 'VIEW_3D': break - bpy.ops.view3d.toolshelf() #close the first toolshelf + #bpy.ops.view3d.toolshelf() #close the first toolshelf override = context.copy() override['area'] = area self.area_align = area - bpy.ops.screen.area_split(override, direction='VERTICAL', factor=0.5, mouse_x=-100, mouse_y=-100) + bpy.ops.screen.area_split(direction='VERTICAL', factor=0.5, cursor=(100,-100))#bpy.ops.screen.area_split(override, direction='VERTICAL', factor=0.5, mouse_x=-100, mouse_y=-100) #bpy.ops.view3d.toolshelf() #close the 2nd toolshelf - context.scene.objects.active = obj1 - obj1.select = True - obj2.select = False + bpy.context.view_layer.objects.active = obj1 + obj1.select_set(True) + obj2.select_set(False) bpy.ops.view3d.localview(override) - obj1.select = False - context.scene.objects.active = None + obj1.select_set(False) + bpy.context.view_layer.objects.active = None override = context.copy() for area in screen.areas: if area.as_pointer() not in areas: override['area'] = area self.area_base = area bpy.ops.object.select_all(action = 'DESELECT') - context.scene.objects.active = obj2 - obj2.select = True + bpy.context.view_layer.objects.active = obj2 + obj2.select_set(True) override['selected_objects'] = [obj2] override['selected_editable_objects'] = [obj2] override['object'] = obj2 From 6bbd12d90fcf51c69da62e166c7f9584fa5561c1 Mon Sep 17 00:00:00 2001 From: huiyao8761380 Date: Fri, 30 Aug 2019 19:26:09 +0800 Subject: [PATCH 03/27] Delete align_pick_points.py --- align_pick_points.py | 367 ------------------------------------------- 1 file changed, 367 deletions(-) delete mode 100644 align_pick_points.py diff --git a/align_pick_points.py b/align_pick_points.py deleted file mode 100644 index 3463d98..0000000 --- a/align_pick_points.py +++ /dev/null @@ -1,367 +0,0 @@ -# Copyright (C) 2019 Christopher Gearhart -# chris@bblanimation.com -# http://bblanimation.com/ -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# System imports -import time -import numpy as np - -# Blender imports -import bpy -import blf -from bpy.types import Operator -from mathutils import Matrix -from bpy_extras import view3d_utils - -# Addon imports -from ..functions import * - - -def draw_callback_px(self, context): - - font_id = 0 # XXX, need to find out how best to get this. - - # draw some text - y = context.region.height - dims = blf.dimensions(0, 'A') - - blf.position(font_id, 10, y - 20 - dims[1], 0) - blf.size(font_id, 20, 72) - - if context.area.x == self.area_align.x: - blf.draw(font_id, "Align: "+ self.align_msg) - points = [self.obj_align.matrix_world * p for p in self.align_points] - color = (1,0,0,1) - else: - blf.draw(font_id, "Base: " + self.base_msg) - points = [self.obj_align.matrix_world * p for p in self.base_points] - color = (0,1,0,1) - - draw_3d_points_revised(context, points, color, 4) - - for i, vec in enumerate(points): - ind = str(i) - draw_3d_text(context, font_id, ind, vec) - -class OBJECT_OT_align_pick_points(Operator): - """Align two objects with 3 or more pair of picked points""" - bl_idname = "object.align_picked_points" - bl_label = "Align: Picked Points" - # bl_options = {"REGISTER", "UNDO"} - - ################################################ - # Blender Operator methods - - @classmethod - def poll(cls, context): - condition_1 = len(context.selected_objects) == 2 - condition_2 = context.object.type == 'MESH' - return condition_1 and condition_2 - - def modal(self, context, event): - - tag_redraw_areas("VIEW_3D") - - if len(self.align_points) < 3: - self.align_msg = "Pick at least %s more pts" % str(3 - len(self.align_points)) - else: - self.align_msg = "More points optional" - - if len(self.base_points) < 3: - self.base_msg = "Pick at last %s more pts" % str(3 - len(self.base_points)) - else: - self.base_msg = "More points optional" - - - if len(self.base_points) > 3 and len(self.align_points) > 3 and len(self.base_points) != len(self.align_points): - - if len(self.align_points) < len(self.base_points): - self.align_msg = "Pick %s more pts to match" % str(len(self.base_points) - len(self.align_points)) - else: - self.base_msg = "Pick %s more pts to match" % str(len(self.align_points) - len(self.base_points)) - - if len(self.base_points) == len(self.align_points) and len(self.base_points) >= 3: - self.base_msg = "Hit Enter to Align" - self.align_msg = "Hit Enter to Align" - - - if event.type == 'LEFTMOUSE' and event.value == 'PRESS': - - ray_max = 10000 - - if event.mouse_x > self.area_align.x and event.mouse_x < self.area_align.x + self.area_align.width: - - for reg in self.area_align.regions: - if reg.type == 'WINDOW': - region = reg - for spc in self.area_align.spaces: - if spc.type == 'VIEW_3D': - rv3d = spc.region_3d - - #just transform the mouse window coords into the region coords - coord = (event.mouse_x - region.x, event.mouse_y - region.y) - - #are the cords the problem - print('align cords: ' + str(coord)) - print(str((event.mouse_region_x, event.mouse_region_y))) - - view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord) - ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord) - ray_target = ray_origin + (view_vector * ray_max) - - print('in the align object window') - (d, (ok,hit, normal, face_index)) = ray_cast_region2d(region, rv3d, coord, self.obj_align) - if hit: - print('hit! align_obj %s' % self.obj_align.name) - #local space of align object - self.align_points.append(hit) - - else: - - for reg in self.area_base.regions: - if reg.type == 'WINDOW': - region = reg - for spc in self.area_base.spaces: - if spc.type == 'VIEW_3D': - rv3d = spc.region_3d - - coord = (event.mouse_x - region.x, event.mouse_y - region.y) - view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord) - ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord) - ray_target = ray_origin + (view_vector * ray_max) - - print('in the base object window') - (d, (ok,hit, normal, face_index)) = ray_cast_region2d(region, rv3d, coord, self.obj_base) - if ok: - print('hit! base_obj %s' % self.obj_base.name) - #points in local space of align object - self.base_points.append(self.obj_align.matrix_world.inverted() * self.obj_base.matrix_world * hit) - - - return {'RUNNING_MODAL'} - - elif event.type == 'RIGHTMOUSE' and event.value == 'PRESS': - - if event.mouse_x > self.area_align.x and event.mouse_x < self.area_align.x + self.area_align.width: - self.align_points.pop() - else: - self.base_points.pop() - - return {'RUNNING_MODAL'} - - - if event.type in {'WHEELUPMOUSE', 'WHEELDOWNMOUSE'}: - - return {'PASS_THROUGH'} - - if self.modal_state == 'NAVIGATING': - - if (event.type in {'MOUSEMOVE', - 'MIDDLEMOUSE', - 'NUMPAD_2', - 'NUMPAD_4', - 'NUMPAD_6', - 'NUMPAD_8', - 'NUMPAD_1', - 'NUMPAD_3', - 'NUMPAD_5', - 'NUMPAD_7', - 'NUMPAD_9'} and event.value == 'RELEASE'): - - self.modal_state = 'WAITING' - return {'PASS_THROUGH'} - - - if (event.type in {'MIDDLEMOUSE', - 'NUMPAD_2', - 'NUMPAD_4', - 'NUMPAD_6', - 'NUMPAD_8', - 'NUMPAD_1', - 'NUMPAD_3', - 'NUMPAD_5', - 'NUMPAD_7', - 'NUMPAD_9'} and event.value == 'PRESS'): - - self.modal_state = 'NAVIGATING' - - return {'PASS_THROUGH'} - - elif event.type in {'ESC'}: - bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') - return {'CANCELLED'} - - elif event.type == 'RET': - - if len(self.align_points) >= 3 and len(self.base_points) >= 3 and len(self.align_points) == len(self.base_points): - bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') - self.de_localize(context) - self.align_obj(context) - - context.scene.objects.active = self.obj_align - self.obj_align.select = True - self.obj_base = True - - return {'FINISHED'} - - return {'RUNNING_MODAL'} - - def invoke(self, context, event): - self.modal_state = 'WAITING' - - self.start_time = time.time() - #capture some mouse info to pass to the draw handler - self.winx = event.mouse_x - self.winy = event.mouse_y - - self.regx = event.mouse_region_x - self.regy = event.mouse_region_y - - self.base_msg = 'Select 3 or more points' - self.align_msg = 'Select 3 or more points' - - - obj1_name = context.object.name - obj2_name = [obj for obj in context.selected_objects if obj != context.object][0].name - - for ob in context.scene.objects: - ob.select_set(False) - - bpy.context.view_layer.objects.active= None#context.scene.objects.active = None - - #I did this stupid method becuase I was unsure - #if some things were being "sticky" and not - #remembering where they were - obj1 = bpy.data.objects[obj1_name] - obj2 = bpy.data.objects[obj2_name] - - for ob in bpy.data.objects: - if ob.select_set(True): - print(ob.name) - - screen = context.window.screen - areas = [area.as_pointer() for area in screen.areas] - for area in screen.areas: - if area.type == 'VIEW_3D': - break - - #bpy.ops.view3d.toolshelf() #close the first toolshelf - override = context.copy() - override['area'] = area - - self.area_align = area - - bpy.ops.screen.area_split(direction='VERTICAL', factor=0.5, cursor=(100,-100))#bpy.ops.screen.area_split(override, direction='VERTICAL', factor=0.5, mouse_x=-100, mouse_y=-100) - #bpy.ops.view3d.toolshelf() #close the 2nd toolshelf - - bpy.context.view_layer.objects.active = obj1 - obj1.select_set(True) - obj2.select_set(False) - - bpy.ops.view3d.localview(override) - - obj1.select_set(False) - bpy.context.view_layer.objects.active = None - override = context.copy() - for area in screen.areas: - if area.as_pointer() not in areas: - override['area'] = area - self.area_base = area - bpy.ops.object.select_all(action = 'DESELECT') - bpy.context.view_layer.objects.active = obj2 - obj2.select_set(True) - override['selected_objects'] = [obj2] - override['selected_editable_objects'] = [obj2] - override['object'] = obj2 - override['active_object'] = obj2 - bpy.ops.view3d.localview(override) - break - - - self.obj_align = obj1 - self.obj_base = obj2 - - #hooray, we will raycast in local view! - self.align_points = [] - self.base_points = [] - - context.window_manager.modal_handler_add(self) - self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, (self, context), 'WINDOW', 'POST_PIXEL') - return {'RUNNING_MODAL'} - - ############################################# - # class methods - - def de_localize(self,context): - - override = context.copy() - override['area'] = self.area_align - bpy.ops.view3d.localview(override) - bpy.ops.view3d.view_selected(override) - - override['area'] = self.area_base - bpy.ops.view3d.localview(override) - bpy.ops.view3d.view_selected(override) - - #Crash Blender? - bpy.ops.screen.area_join(min_x=self.area_align.x,min_y=self.area_align.y, max_x=self.area_base.x, max_y=self.area_base.y) - bpy.ops.view3d.toolshelf() - - #ret = bpy.ops.screen.area_join(min_x=area_base.x,min_y=area_base.y, max_x=area_align.x, max_y=area_align.y) - - def align_obj(self,context): - - if len(self.align_points) != len(self.base_points): - if len(self.align_points) < len(self.base_points): - - self.base_points = self.base_points[0:len(self.align_points)] - else: - self.align_points = self.align_points[0:len(self.base_points)] - - A = np.zeros(shape = [3,len(self.base_points)]) - B = np.zeros(shape = [3,len(self.base_points)]) - - for i in range(0,len(self.base_points)): - V1 = self.align_points[i] - V2 = self.base_points[i] - - A[0][i], A[1][i], A[2][i] = V1[0], V1[1], V1[2] - B[0][i], B[1][i], B[2][i] = V2[0], V2[1], V2[2] - - - #test new method - settings = get_addon_preferences() - align_meth = settings.align_meth - - if align_meth == '0': #rigid transform - M = affine_matrix_from_points(A, B, shear=False, scale=False, usesvd=True) - elif align_meth == '1': # rot, loc, scale - M = affine_matrix_from_points(A, B, shear=False, scale=True, usesvd=True) - #else: #affine - #M = affine_matrix_from_points(A, B, shear=True, scale=True, usesvd=True) - - - new_mat = Matrix.Identity(4) - for n in range(0,4): - for m in range(0,4): - new_mat[n][m] = M[n][m] - - #because we calced transform in local space - #it's this easy to update the obj... - self.obj_align.matrix_world = self.obj_align.matrix_world * new_mat - - self.obj_align.update_tag() - context.scene.update() From f6aa117e69833c71f524718d93840552dc6d90e9 Mon Sep 17 00:00:00 2001 From: huiyao8761380 Date: Sat, 31 Aug 2019 19:32:24 +0800 Subject: [PATCH 04/27] 2.79 blender2.8 change too much ,so I can't fix it.But I can make it run in 2.79. From f3b78ddc2f8e2f4f76c4396ee00e52cbeffe1388 Mon Sep 17 00:00:00 2001 From: patmo141 Date: Sat, 31 Aug 2019 10:43:47 -0400 Subject: [PATCH 05/27] citation.text started --- citation.txt | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 citation.txt diff --git a/citation.txt b/citation.txt new file mode 100644 index 0000000..a1d821a --- /dev/null +++ b/citation.txt @@ -0,0 +1,31 @@ +Original Papers First introduced by Chen and Medioni (1991) and Besl and McKay (1992). + + +1. Chen, Yang; Gerard Medioni (1991). + "Object modelling by registration of multiple range images". + Image Vision Comput. + 10 (3): 145–155. doi:10.1016/0262-8856(92)90066-C. + +2. Besl, Paul J.; N.D. McKay (1992). + "A Method for Registration of 3-D Shapes". + IEEE Transactions on Pattern Analysis and Machine Intelligence. + 14 (2): 239–256. doi:10.1109/34.121791. + +3.Transformations Python Library +Author: Christoph Gohlke `_ +Organization: Laboratory for Fluorescence Dynamics. University of California, Irvine +https://www.lfd.uci.edu/~gohlke/code/transformations.py.html + +4. FINDING OPTIMAL ROTATION AND TRANSLATION BETWEEN CORRESPONDING 3D POINTS +Author: Nghia Ho, nghiaho12@yahoo.com +Organization: +https://nghiaho.com/?page_id=671 +http://nghiaho.com/uploads/code/rigid_transform_3D.py + +5. Blender Implementation, Filtering Code, UI, BVH Acceleration +Modal Operator +Patrick Moore: patrick.moore.bu@gmail.com +working as a hobby and later update for D3tool.com + + +### Add Additional Citation Below ### \ No newline at end of file From 7df7b85f34056403295f6d1573cbd273ccf494d3 Mon Sep 17 00:00:00 2001 From: patmo141 Date: Sat, 31 Aug 2019 12:16:43 -0400 Subject: [PATCH 06/27] try some things --- operators/align_pick_points.py | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/operators/align_pick_points.py b/operators/align_pick_points.py index ad9dc34..01ffd7f 100644 --- a/operators/align_pick_points.py +++ b/operators/align_pick_points.py @@ -38,23 +38,32 @@ def draw_callback_px(self, context): y = context.region.height dims = blf.dimensions(0, 'A') - blf.position(font_id, 10, y - 20 - dims[1], 0) + #blf.position(font_id, 10, y - 20 - dims[1], 0) + blf.position(font_id, 10, 20 + dims[1], 0) + blf.size(font_id, 20, 72) if context.area.x == self.area_align.x: blf.draw(font_id, "Align: "+ self.align_msg) - points = [self.obj_align.matrix_world * p for p in self.align_points] + points = [self.obj_align.matrix_world @ p for p in self.align_points] color = (1,0,0,1) else: blf.draw(font_id, "Base: " + self.base_msg) - points = [self.obj_align.matrix_world * p for p in self.base_points] + points = [self.obj_align.matrix_world @ p for p in self.base_points] color = (0,1,0,1) - draw_3d_points_revised(context, points, color, 4) + #draw_3d_points_revised(context, points, color, 4) - for i, vec in enumerate(points): - ind = str(i) - draw_3d_text(context, font_id, ind, vec) + #for i, vec in enumerate(points): + # ind = str(i) + # draw_3d_text(context, font_id, ind, vec) + + +def draw_callback_view(self, context): + + pass + + class OBJECT_OT_align_pick_points(Operator): """Align two objects with 3 or more pair of picked points""" @@ -201,13 +210,15 @@ def modal(self, context, event): return {'PASS_THROUGH'} elif event.type in {'ESC'}: - bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') + bpy.types.SpaceView3D.draw_handler_remove(self._2Dhandle, 'WINDOW') + bpy.types.SpaceView3D.draw_handler_remove(self._3Dhandle, 'WINDOW') return {'CANCELLED'} elif event.type == 'RET': if len(self.align_points) >= 3 and len(self.base_points) >= 3 and len(self.align_points) == len(self.base_points): - bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') + bpy.types.SpaceView3D.draw_handler_remove(self._2Dhandle, 'WINDOW') + bpy.types.SpaceView3D.draw_handler_remove(self._3Dhandle, 'WINDOW') self.de_localize(context) self.align_obj(context) @@ -299,7 +310,10 @@ def invoke(self, context, event): self.base_points = [] context.window_manager.modal_handler_add(self) - self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, (self, context), 'WINDOW', 'POST_PIXEL') + self._2Dhandle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, (self, context), 'WINDOW', 'POST_PIXEL') + self._3Dhandle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_view, (self, context), 'WINDOW', 'POST_VIEW') + + return {'RUNNING_MODAL'} ############################################# From f606a29ca1e62fbea885730a111b20e8f4895052 Mon Sep 17 00:00:00 2001 From: patmo141 Date: Sat, 31 Aug 2019 12:21:53 -0400 Subject: [PATCH 07/27] matrix multiplication --- functions/utilities.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/functions/utilities.py b/functions/utilities.py index 26df1e1..49342f1 100644 --- a/functions/utilities.py +++ b/functions/utilities.py @@ -71,7 +71,7 @@ def draw_3d_points_revised(context, points, color, size): for vec in points: - vec_4d = perspective_matrix * vec.to_4d() + vec_4d = perspective_matrix @ vec.to_4d() if vec_4d.w > 0.0: x = region_mid_width + region_mid_width * (vec_4d.x / vec_4d.w) y = region_mid_height + region_mid_height * (vec_4d.y / vec_4d.w) @@ -87,7 +87,7 @@ def draw_3d_text(context, font_id, text, vec): region_mid_height = region.height / 2.0 perspective_matrix = region3d.perspective_matrix.copy() - vec_4d = perspective_matrix * vec.to_4d() + vec_4d = perspective_matrix @ vec.to_4d() if vec_4d.w > 0.0: x = region_mid_width + region_mid_width * (vec_4d.x / vec_4d.w) y = region_mid_height + region_mid_height * (vec_4d.y / vec_4d.w) @@ -117,8 +117,8 @@ def get_ray_origin(ray_origin, ray_direction, ob): if abs(ray_direction.x)>0.0001: planes += [(bm,x), (bM,-x)] if abs(ray_direction.y)>0.0001: planes += [(bm,y), (bM,-y)] if abs(ray_direction.z)>0.0001: planes += [(bm,z), (bM,-z)] - dists = [get_ray_plane_intersection(ray_origin,ray_direction,mx*p0,q*no) for p0,no in planes] - return ray_origin + ray_direction * min(dists) + dists = [get_ray_plane_intersection(ray_origin,ray_direction,mx@p0,q@no) for p0,no in planes] + return ray_origin + ray_direction @ min(dists) # Jon Denning for Retopoflow def ray_cast_region2d(region, rv3d, screen_coord, obj): @@ -139,7 +139,7 @@ def ray_cast_region2d(region, rv3d, screen_coord, obj): bver = '%03d.%03d.%03d' % (bpy.app.version[0],bpy.app.version[1],bpy.app.version[2]) if (bver < '002.072.000') and not rv3d.is_perspective: mult *= -1 - st, en = imx*(o-mult*back*d), imx*(o+mult*d) + st, en = imx@(o-mult*back*d), imx@(o+mult*d) if bversion() < '002.077.000': hit = obj.ray_cast(st,en) From 10c0cb8011bedcc2214f2eda51259faaac1fb002 Mon Sep 17 00:00:00 2001 From: patmo141 Date: Sat, 31 Aug 2019 12:27:12 -0400 Subject: [PATCH 08/27] matrix multiplication --- operators/align_pick_points.py | 8 ++++---- operators/icp_align.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/operators/align_pick_points.py b/operators/align_pick_points.py index f139e3b..dcc1238 100644 --- a/operators/align_pick_points.py +++ b/operators/align_pick_points.py @@ -129,7 +129,7 @@ def modal(self, context, event): view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord) ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord) - ray_target = ray_origin + (view_vector * ray_max) + ray_target = ray_origin + (ray_max * view_vector) print('in the align object window') (d, (ok,hit, normal, face_index)) = ray_cast_region2d(region, rv3d, coord, self.obj_align) @@ -150,14 +150,14 @@ def modal(self, context, event): coord = (event.mouse_x - region.x, event.mouse_y - region.y) view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord) ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord) - ray_target = ray_origin + (view_vector * ray_max) + ray_target = ray_origin + (ray_max * view_vector) print('in the base object window') (d, (ok,hit, normal, face_index)) = ray_cast_region2d(region, rv3d, coord, self.obj_base) if ok: print('hit! base_obj %s' % self.obj_base.name) #points in local space of align object - self.base_points.append(self.obj_align.matrix_world.inverted() * self.obj_base.matrix_world * hit) + self.base_points.append(self.obj_align.matrix_world.inverted() @ self.obj_base.matrix_world @ hit) return {'RUNNING_MODAL'} @@ -375,7 +375,7 @@ def align_obj(self,context): #because we calced transform in local space #it's this easy to update the obj... - self.obj_align.matrix_world = self.obj_align.matrix_world * new_mat + self.obj_align.matrix_world = self.obj_align.matrix_world @ new_mat self.obj_align.update_tag() context.scene.update() diff --git a/operators/icp_align.py b/operators/icp_align.py index 723ab4d..8f7d16e 100644 --- a/operators/icp_align.py +++ b/operators/icp_align.py @@ -108,7 +108,7 @@ def execute(self, context): for z in range(0,4): new_mat[y][z] = M[y][z] - align_obj.matrix_world = align_obj.matrix_world * new_mat + align_obj.matrix_world = align_obj.matrix_world @ new_mat trans = new_mat.to_translation() quat = new_mat.to_quaternion() From d0d74cb135641fef89e76187d03b024bdaee8b40 Mon Sep 17 00:00:00 2001 From: patmo141 Date: Sat, 31 Aug 2019 12:33:01 -0400 Subject: [PATCH 09/27] comment out until future api knowledge replaces --- operators/align_pick_points.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operators/align_pick_points.py b/operators/align_pick_points.py index dcc1238..207471e 100644 --- a/operators/align_pick_points.py +++ b/operators/align_pick_points.py @@ -332,7 +332,7 @@ def de_localize(self,context): #Crash Blender? bpy.ops.screen.area_join(min_x=self.area_align.x,min_y=self.area_align.y, max_x=self.area_base.x, max_y=self.area_base.y) - bpy.ops.view3d.toolshelf() + #bpy.ops.view3d.toolshelf() #ret = bpy.ops.screen.area_join(min_x=area_base.x,min_y=area_base.y, max_x=area_align.x, max_y=area_align.y) From c483f7480a2f930f2b9e506b92a3385a0d6ff468 Mon Sep 17 00:00:00 2001 From: patmo141 Date: Sat, 31 Aug 2019 12:37:42 -0400 Subject: [PATCH 10/27] scene update changes --- operators/align_pick_points.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operators/align_pick_points.py b/operators/align_pick_points.py index 207471e..7aae43f 100644 --- a/operators/align_pick_points.py +++ b/operators/align_pick_points.py @@ -378,4 +378,4 @@ def align_obj(self,context): self.obj_align.matrix_world = self.obj_align.matrix_world @ new_mat self.obj_align.update_tag() - context.scene.update() + context.view_layer.update() From 61fbe04fa711618f67d0648275009c17d9e67cf0 Mon Sep 17 00:00:00 2001 From: patmo141 Date: Sat, 31 Aug 2019 12:42:48 -0400 Subject: [PATCH 11/27] active object --- operators/align_pick_points.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/operators/align_pick_points.py b/operators/align_pick_points.py index 7aae43f..916a78d 100644 --- a/operators/align_pick_points.py +++ b/operators/align_pick_points.py @@ -222,8 +222,8 @@ def modal(self, context, event): self.de_localize(context) self.align_obj(context) - context.scene.objects.active = self.obj_align - self.obj_align.select = True + context.view_layer.objects.active = self.obj_align + self.obj_align.select_set(True) self.obj_base = True return {'FINISHED'} From b3828436cf93ce94b874a723cae6f1c71c69ed37 Mon Sep 17 00:00:00 2001 From: patmo141 Date: Sat, 31 Aug 2019 12:51:07 -0400 Subject: [PATCH 12/27] depsgraph update --- operators/icp_align.py | 5 +++-- operators/icp_align_feedback.py | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/operators/icp_align.py b/operators/icp_align.py index 8f7d16e..3b74d49 100644 --- a/operators/icp_align.py +++ b/operators/icp_align.py @@ -50,7 +50,7 @@ def execute(self, context): start = time.time() align_obj = context.object base_obj = [obj for obj in context.selected_objects if obj != align_obj][0] - base_bvh = BVHTree.FromObject(base_obj, context.scene) + base_bvh = BVHTree.FromObject(base_obj, context.depsgraph) align_obj.rotation_mode = 'QUATERNION' vlist = [] @@ -113,7 +113,8 @@ def execute(self, context): quat = new_mat.to_quaternion() align_obj.update_tag() - context.scene.update() + context.view_layer.update() + #context.scene.update() if d_stats: i = int(fmod(n,5)) diff --git a/operators/icp_align_feedback.py b/operators/icp_align_feedback.py index 5145c8f..137fa58 100644 --- a/operators/icp_align_feedback.py +++ b/operators/icp_align_feedback.py @@ -195,7 +195,8 @@ def execute(self, context): quat = new_mat.to_quaternion() align_obj.update_tag() - context.scene.update() + #context.scene.update() + context.view_layer.update() if d_stats: i = int(fmod(n,5)) From fe1332cdd1cd8d7afb6f3cd317a529209d021391 Mon Sep 17 00:00:00 2001 From: patmo141 Date: Sat, 31 Aug 2019 12:56:25 -0400 Subject: [PATCH 13/27] eval depsgraph --- operators/icp_align.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operators/icp_align.py b/operators/icp_align.py index 3b74d49..dd2952c 100644 --- a/operators/icp_align.py +++ b/operators/icp_align.py @@ -50,7 +50,7 @@ def execute(self, context): start = time.time() align_obj = context.object base_obj = [obj for obj in context.selected_objects if obj != align_obj][0] - base_bvh = BVHTree.FromObject(base_obj, context.depsgraph) + base_bvh = BVHTree.FromObject(base_obj, context.evaluated_depsgraph_get()) align_obj.rotation_mode = 'QUATERNION' vlist = [] From 4d8a5227ce4d6fb4d5c58e5a3824676d282b1743 Mon Sep 17 00:00:00 2001 From: patmo141 Date: Sat, 31 Aug 2019 13:56:08 -0400 Subject: [PATCH 14/27] matrix multiplication --- functions/general.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/functions/general.py b/functions/general.py index f0eb385..e9266af 100644 --- a/functions/general.py +++ b/functions/general.py @@ -273,7 +273,7 @@ def make_pairs(align_obj, base_obj, base_bvh, vlist, thresh, sample = 0, calc_st vert = align_obj.data.vertices[vert_ind] #closest point for point clouds. Local space of base obj - co_find = imx2 * (mx1 * vert.co) + co_find = imx2 @ (mx1 @ vert.co) #closest surface point for triangle mesh #this is set up for a well modeled aligning object with @@ -285,12 +285,12 @@ def make_pairs(align_obj, base_obj, base_bvh, vlist, thresh, sample = 0, calc_st #res, co1, normal, face_index = base_obj.closest_point_on_mesh(co_find) co1, n, face_index, d = base_bvh.find_nearest(co_find) - dist = (mx2 * co_find - mx2 * co1).length + dist = (mx2 @ co_find - mx2 @ co1).length #d is now returned by bvh.find #dist = mx2.to_scale() * d if face_index != -1 and dist < thresh: verts1.append(vert.co) - verts2.append(imx1 * (mx2 * co1)) + verts2.append(imx1 @ (mx2 @ co1)) if calc_stats: dists.append(dist) From 3b4aded6037eb4737e9551cb4f8c21a9efedc52c Mon Sep 17 00:00:00 2001 From: patmo141 Date: Sat, 31 Aug 2019 14:00:53 -0400 Subject: [PATCH 15/27] 280 api --- operators/icp_align_feedback.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/operators/icp_align_feedback.py b/operators/icp_align_feedback.py index 137fa58..5591ceb 100644 --- a/operators/icp_align_feedback.py +++ b/operators/icp_align_feedback.py @@ -46,7 +46,7 @@ def poll(cls, context): def invoke(self,context, event): wm = context.window_manager - self._timer = wm.event_timer_add(0.01, context.window) + self._timer = wm.event_timer_add(time_step = 0.01, window = context.window) wm.modal_handler_add(self) settings = get_addon_preferences() @@ -190,7 +190,7 @@ def execute(self, context): for z in range(0,4): new_mat[y][z] = M[y][z] - align_obj.matrix_world = align_obj.matrix_world * new_mat + align_obj.matrix_world = align_obj.matrix_world @ new_mat trans = new_mat.to_translation() quat = new_mat.to_quaternion() @@ -253,7 +253,7 @@ def iterate(self,context): for z in range(0,4): new_mat[y][z] = M[y][z] - self.align_obj.matrix_world = self.align_obj.matrix_world * new_mat + self.align_obj.matrix_world = self.align_obj.matrix_world @ new_mat trans = new_mat.to_translation() quat = new_mat.to_quaternion() From e085372c7a121f22cc2f25e39262a3a1efa4cb8e Mon Sep 17 00:00:00 2001 From: patmo141 Date: Sat, 31 Aug 2019 14:05:46 -0400 Subject: [PATCH 16/27] 2.80 api changes --- operators/icp_align_feedback.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/operators/icp_align_feedback.py b/operators/icp_align_feedback.py index 5591ceb..8615c3c 100644 --- a/operators/icp_align_feedback.py +++ b/operators/icp_align_feedback.py @@ -54,7 +54,7 @@ def invoke(self,context, event): self.start = time.time() self.align_obj = context.object self.base_obj = [obj for obj in context.selected_objects if obj != self.align_obj][0] - self.base_bvh = BVHTree.FromObject(self.base_obj, context.scene) + self.base_bvh = BVHTree.FromObject(self.base_obj, context.evaluated_depsgraph_get()) self.align_obj.rotation_mode = 'QUATERNION' self.vlist = [] @@ -132,7 +132,7 @@ def execute(self, context): start = time.time() align_obj = context.object base_obj = [obj for obj in context.selected_objects if obj != align_obj][0] - base_bvh = BVHTree.FromObject(base_obj, context.scene) + base_bvh = BVHTree.FromObject(base_obj, context.evaluated_depsgraph_get()) align_obj.rotation_mode = 'QUATERNION' vlist = [] From 7415a86780242fb5d8868492ab31a07f692a7245 Mon Sep 17 00:00:00 2001 From: patmo141 Date: Sat, 31 Aug 2019 14:54:06 -0400 Subject: [PATCH 17/27] get point labels back --- operators/align_pick_points.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/operators/align_pick_points.py b/operators/align_pick_points.py index 916a78d..52b8467 100644 --- a/operators/align_pick_points.py +++ b/operators/align_pick_points.py @@ -54,9 +54,9 @@ def draw_callback_px(self, context): #draw_3d_points_revised(context, points, color, 4) - #for i, vec in enumerate(points): - # ind = str(i) - # draw_3d_text(context, font_id, ind, vec) + for i, vec in enumerate(points): + ind = str(i) + draw_3d_text(context, font_id, ind, vec) def draw_callback_view(self, context): @@ -331,7 +331,7 @@ def de_localize(self,context): bpy.ops.view3d.view_selected(override) #Crash Blender? - bpy.ops.screen.area_join(min_x=self.area_align.x,min_y=self.area_align.y, max_x=self.area_base.x, max_y=self.area_base.y) + bpy.ops.screen.area_join(min_x=self.area_align.x,min_y=self.area_align.y, max_x=self.area_base.x+1, max_y=self.area_base.y+1) #bpy.ops.view3d.toolshelf() #ret = bpy.ops.screen.area_join(min_x=area_base.x,min_y=area_base.y, max_x=area_align.x, max_y=area_align.y) From 1d56ee17e7b8d1ba1976c0a898a961ab9c4b6eba Mon Sep 17 00:00:00 2001 From: patmo141 Date: Sat, 31 Aug 2019 15:08:16 -0400 Subject: [PATCH 18/27] hack to collapse the dead screen? may cause crashes --- operators/align_pick_points.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/operators/align_pick_points.py b/operators/align_pick_points.py index 52b8467..5f793f9 100644 --- a/operators/align_pick_points.py +++ b/operators/align_pick_points.py @@ -334,6 +334,8 @@ def de_localize(self,context): bpy.ops.screen.area_join(min_x=self.area_align.x,min_y=self.area_align.y, max_x=self.area_base.x+1, max_y=self.area_base.y+1) #bpy.ops.view3d.toolshelf() + bpy.ops.screen.screen_full_area() + bpy.ops.screen.screen_full_area() #ret = bpy.ops.screen.area_join(min_x=area_base.x,min_y=area_base.y, max_x=area_align.x, max_y=area_align.y) def align_obj(self,context): From 755ff89f987f3090e1e239d0444225696d5a8cba Mon Sep 17 00:00:00 2001 From: patmo141 Date: Sat, 31 Aug 2019 15:39:40 -0400 Subject: [PATCH 19/27] attempt 3d drawing with crude shader --- operators/align_pick_points.py | 38 +++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/operators/align_pick_points.py b/operators/align_pick_points.py index 5f793f9..6172e0c 100644 --- a/operators/align_pick_points.py +++ b/operators/align_pick_points.py @@ -22,6 +22,12 @@ # Blender imports import bpy import blf +import bgl +import gpu + +from gpu_extras.batch import batch_for_shader + + from bpy.types import Operator from mathutils import Matrix from bpy_extras import view3d_utils @@ -60,7 +66,19 @@ def draw_callback_px(self, context): def draw_callback_view(self, context): - + bgl.glPointSize(8) + if context.area.x == self.area_align.x: + if not self.align_shader: + self. + self.align_shader.bind() + self.align_shader.uniform_float("color", (1,0,1,1)) + self.align_batch.draw(self.align_shader) + else: + self.base_shader.bind() + self.base_shader.uniform_float("color", (1,1,0,1)) + self.base_batch.draw(self.base_shader) + + bgl.glPointSize(1) pass @@ -166,8 +184,10 @@ def modal(self, context, event): if event.mouse_x > self.area_align.x and event.mouse_x < self.area_align.x + self.area_align.width: self.align_points.pop() + self.create_batch_align() else: self.base_points.pop() + self.create_batch_base() return {'RUNNING_MODAL'} @@ -309,6 +329,10 @@ def invoke(self, context, event): self.align_points = [] self.base_points = [] + self.base_batch = None + self.base_shader = None + self.align_batch = None + self.align_shader = None context.window_manager.modal_handler_add(self) self._2Dhandle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, (self, context), 'WINDOW', 'POST_PIXEL') self._3Dhandle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_view, (self, context), 'WINDOW', 'POST_VIEW') @@ -319,6 +343,18 @@ def invoke(self, context, event): ############################################# # class methods + + def create_batch_base(self): + vertices = [(v.x, v.y, v.z) for v in self.base_points] + self.base_shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') + self.base_batch = batch_for_shader(self.base_shader, 'POINTS', {"poS":vertices}) + + + def create_batch_align(self): + vertices = [(v.x, v.y, v.z) for v in self.align_points] + self.align_shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') + self.align_batch = batch_for_shader(self.base_shader, 'POINTS', {"poS":vertices}) + def de_localize(self,context): override = context.copy() From 3262b804a360a13079007e90d53e432f74ac303e Mon Sep 17 00:00:00 2001 From: patmo141 Date: Sat, 31 Aug 2019 15:41:46 -0400 Subject: [PATCH 20/27] dont draw before shaders are iniitialized --- operators/align_pick_points.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/operators/align_pick_points.py b/operators/align_pick_points.py index 6172e0c..7670803 100644 --- a/operators/align_pick_points.py +++ b/operators/align_pick_points.py @@ -69,11 +69,14 @@ def draw_callback_view(self, context): bgl.glPointSize(8) if context.area.x == self.area_align.x: if not self.align_shader: - self. + return + self.align_shader.bind() self.align_shader.uniform_float("color", (1,0,1,1)) self.align_batch.draw(self.align_shader) else: + if not self.base_shader: + return self.base_shader.bind() self.base_shader.uniform_float("color", (1,1,0,1)) self.base_batch.draw(self.base_shader) From 2907eb1ddc130186a340db98ecf49efefb7a07ff Mon Sep 17 00:00:00 2001 From: patmo141 Date: Sat, 31 Aug 2019 15:48:10 -0400 Subject: [PATCH 21/27] actually create the batches once points are clicked --- operators/align_pick_points.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/operators/align_pick_points.py b/operators/align_pick_points.py index 7670803..83acb6b 100644 --- a/operators/align_pick_points.py +++ b/operators/align_pick_points.py @@ -67,6 +67,7 @@ def draw_callback_px(self, context): def draw_callback_view(self, context): bgl.glPointSize(8) + print('draw view!') if context.area.x == self.area_align.x: if not self.align_shader: return @@ -158,6 +159,7 @@ def modal(self, context, event): print('hit! align_obj %s' % self.obj_align.name) #local space of align object self.align_points.append(hit) + self.create_batch_align() else: @@ -179,7 +181,7 @@ def modal(self, context, event): print('hit! base_obj %s' % self.obj_base.name) #points in local space of align object self.base_points.append(self.obj_align.matrix_world.inverted() @ self.obj_base.matrix_world @ hit) - + self.create_batch_base() return {'RUNNING_MODAL'} @@ -348,13 +350,15 @@ def invoke(self, context, event): def create_batch_base(self): - vertices = [(v.x, v.y, v.z) for v in self.base_points] + verts = [self.obj_align.matrix_world @ p for p in self.base_points] + vertices = [(v.x, v.y, v.z) for v in verts] self.base_shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') self.base_batch = batch_for_shader(self.base_shader, 'POINTS', {"poS":vertices}) def create_batch_align(self): - vertices = [(v.x, v.y, v.z) for v in self.align_points] + verts = [self.obj_align.matrix_world @ p for p in self.align_points] + vertices = [(v.x, v.y, v.z) for v in verts] self.align_shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') self.align_batch = batch_for_shader(self.base_shader, 'POINTS', {"poS":vertices}) From 0e66240981b2176db9146340445fbdab994b5d91 Mon Sep 17 00:00:00 2001 From: patmo141 Date: Sat, 31 Aug 2019 17:56:27 -0400 Subject: [PATCH 22/27] typo --- operators/align_pick_points.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/operators/align_pick_points.py b/operators/align_pick_points.py index 83acb6b..2b64341 100644 --- a/operators/align_pick_points.py +++ b/operators/align_pick_points.py @@ -353,14 +353,14 @@ def create_batch_base(self): verts = [self.obj_align.matrix_world @ p for p in self.base_points] vertices = [(v.x, v.y, v.z) for v in verts] self.base_shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') - self.base_batch = batch_for_shader(self.base_shader, 'POINTS', {"poS":vertices}) + self.base_batch = batch_for_shader(self.base_shader, 'POINTS', {"pos":vertices}) def create_batch_align(self): verts = [self.obj_align.matrix_world @ p for p in self.align_points] vertices = [(v.x, v.y, v.z) for v in verts] self.align_shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') - self.align_batch = batch_for_shader(self.base_shader, 'POINTS', {"poS":vertices}) + self.align_batch = batch_for_shader(self.base_shader, 'POINTS', {"pos":vertices}) def de_localize(self,context): From 6c969ed18373eed96edef77bfd8b5dad02c93fee Mon Sep 17 00:00:00 2001 From: patmo141 Date: Sat, 31 Aug 2019 17:56:49 -0400 Subject: [PATCH 23/27] typo --- operators/align_pick_points.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/operators/align_pick_points.py b/operators/align_pick_points.py index 83acb6b..2b64341 100644 --- a/operators/align_pick_points.py +++ b/operators/align_pick_points.py @@ -353,14 +353,14 @@ def create_batch_base(self): verts = [self.obj_align.matrix_world @ p for p in self.base_points] vertices = [(v.x, v.y, v.z) for v in verts] self.base_shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') - self.base_batch = batch_for_shader(self.base_shader, 'POINTS', {"poS":vertices}) + self.base_batch = batch_for_shader(self.base_shader, 'POINTS', {"pos":vertices}) def create_batch_align(self): verts = [self.obj_align.matrix_world @ p for p in self.align_points] vertices = [(v.x, v.y, v.z) for v in verts] self.align_shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') - self.align_batch = batch_for_shader(self.base_shader, 'POINTS', {"poS":vertices}) + self.align_batch = batch_for_shader(self.base_shader, 'POINTS', {"pos":vertices}) def de_localize(self,context): From aa987e539c03716afc0db2fd1a75ef2cde94fae8 Mon Sep 17 00:00:00 2001 From: patmo141 Date: Mon, 2 Sep 2019 06:19:08 -0400 Subject: [PATCH 24/27] code examples for later --- operators/align_pick_points.py | 1 + 1 file changed, 1 insertion(+) diff --git a/operators/align_pick_points.py b/operators/align_pick_points.py index 2b64341..e56cb71 100644 --- a/operators/align_pick_points.py +++ b/operators/align_pick_points.py @@ -14,6 +14,7 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . +#https://cognitivewaves.wordpress.com/opengl-vbo-shader-vao/#shader-with-vertex-buffer-object # System imports import time From 7b2da1f47857d8a816d0a7c0d73b51fd8cfe4af5 Mon Sep 17 00:00:00 2001 From: patmo141 Date: Sun, 15 Mar 2020 14:54:41 -0400 Subject: [PATCH 25/27] test updates to area split and merge code --- operators/align_pick_points.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/operators/align_pick_points.py b/operators/align_pick_points.py index 2b64341..9e7383d 100644 --- a/operators/align_pick_points.py +++ b/operators/align_pick_points.py @@ -302,6 +302,14 @@ def invoke(self, context, event): bpy.ops.screen.area_split(direction='VERTICAL', factor=0.5, cursor=(100,-100))#bpy.ops.screen.area_split(override, direction='VERTICAL', factor=0.5, mouse_x=-100, mouse_y=-100) #bpy.ops.view3d.toolshelf() #close the 2nd toolshelf + +#..........Hide sidebar after area split........................... + for A in bpy.context.screen.areas: + if A.type == 'VIEW_3D' : + ctx = bpy.context.copy() + ctx['area'] = A + bpy.ops.screen.region_toggle(ctx, region_type='UI') +#................................................................... bpy.context.view_layer.objects.active = obj1 obj1.select_set(True) @@ -373,8 +381,11 @@ def de_localize(self,context): bpy.ops.view3d.localview(override) bpy.ops.view3d.view_selected(override) - #Crash Blender? - bpy.ops.screen.area_join(min_x=self.area_align.x,min_y=self.area_align.y, max_x=self.area_base.x+1, max_y=self.area_base.y+1) +#............Crash Blender? Resolve................................ + xj = int(self.area_align.width + 1) + yj = int(self.area_align.y + self.area_align.height / 2) + bpy.ops.screen.area_join(cursor=(xj,yj)) +#.................................................................. #bpy.ops.view3d.toolshelf() bpy.ops.screen.screen_full_area() From ee5785a985cf4e333a7cc754f91db75b35dba1e4 Mon Sep 17 00:00:00 2001 From: patmo141 Date: Sun, 15 Mar 2020 15:24:12 -0400 Subject: [PATCH 26/27] need to do context override after taking objects to local view --- operators/align_pick_points.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/operators/align_pick_points.py b/operators/align_pick_points.py index 0bccc2d..8f52e07 100644 --- a/operators/align_pick_points.py +++ b/operators/align_pick_points.py @@ -68,7 +68,7 @@ def draw_callback_px(self, context): def draw_callback_view(self, context): bgl.glPointSize(8) - print('draw view!') + #print('draw view!') if context.area.x == self.area_align.x: if not self.align_shader: return @@ -304,19 +304,23 @@ def invoke(self, context, event): bpy.ops.screen.area_split(direction='VERTICAL', factor=0.5, cursor=(100,-100))#bpy.ops.screen.area_split(override, direction='VERTICAL', factor=0.5, mouse_x=-100, mouse_y=-100) #bpy.ops.view3d.toolshelf() #close the 2nd toolshelf -#..........Hide sidebar after area split........................... + + bpy.context.view_layer.objects.active = obj1 + obj1.select_set(True) + obj2.select_set(False) + + bpy.ops.view3d.localview(override) + + + #..........Hide sidebar after area split........................... for A in bpy.context.screen.areas: if A.type == 'VIEW_3D' : ctx = bpy.context.copy() ctx['area'] = A bpy.ops.screen.region_toggle(ctx, region_type='UI') -#................................................................... +#................................................................... - bpy.context.view_layer.objects.active = obj1 - obj1.select_set(True) - obj2.select_set(False) - bpy.ops.view3d.localview(override) obj1.select_set(False) bpy.context.view_layer.objects.active = None From fd3b4febd690de7d90888a08b4f8510e57584eef Mon Sep 17 00:00:00 2001 From: FredericNk Date: Fri, 3 Apr 2020 10:28:02 +0200 Subject: [PATCH 27/27] Fixed typo in icp_align polling function --- operators/icp_align.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/operators/icp_align.py b/operators/icp_align.py index dd2952c..39cc178 100644 --- a/operators/icp_align.py +++ b/operators/icp_align.py @@ -41,8 +41,8 @@ class OBJECT_OT_icp_align(Operator): @classmethod def poll(cls, context): condition_1 = len(context.selected_objects) == 2 - conidion_2 = context.object.type == 'MESH' - return condition_1 and condition_1 + condition_2 = context.object.type == 'MESH' + return condition_1 and condition_2 def execute(self, context): settings = get_addon_preferences()